aboutsummaryrefslogtreecommitdiff
path: root/tcl_class.cxx
diff options
context:
space:
mode:
authormescalinum <mescalinum@users.sourceforge.net>2009-08-29 17:07:13 +0000
committermescalinum <mescalinum@users.sourceforge.net>2009-08-29 17:07:13 +0000
commit8b65741620bae448b96eb8ce59b85a7b1bb36c44 (patch)
tree6b22e262f1152965a656855478c4ad1a9c58aef0 /tcl_class.cxx
parent066a639c0bb28d759c017ab2e00624dfb0a64b3f (diff)
tidy up!
svn path=/trunk/externals/tclpd/; revision=12133
Diffstat (limited to 'tcl_class.cxx')
-rw-r--r--tcl_class.cxx93
1 files changed, 93 insertions, 0 deletions
diff --git a/tcl_class.cxx b/tcl_class.cxx
new file mode 100644
index 0000000..a95bf5c
--- /dev/null
+++ b/tcl_class.cxx
@@ -0,0 +1,93 @@
+#include "tcl_extras.h"
+#include <map>
+#include <string>
+#include <string.h>
+
+using namespace std;
+
+static long objectSequentialId = 0;
+map<string,t_class*> class_table;
+map<string,t_pd*> object_table;
+
+/* set up the class that handles loading of tcl classes */
+t_class* tclpd_class_new(char *name, int flags) {
+ t_class *c = class_new(gensym(name), (t_newmethod)tclpd_new,
+ (t_method)tclpd_free, sizeof(t_tcl), flags, A_GIMME, A_NULL);
+ class_table[string(name)] = c;
+ class_addanything(c, tclpd_anything);
+ return c;
+}
+
+t_tcl* tclpd_new(t_symbol *classsym, int ac, t_atom *at) {
+ const char* name = classsym->s_name;
+ t_class* qlass = class_table[string(name)];
+ t_tcl* self = (t_tcl*)pd_new(qlass);
+ char s[32];
+ sprintf(s, "pd%06lx", objectSequentialId++);
+ self->self = Tcl_NewStringObj(s, -1);
+ Tcl_IncrRefCount(self->self);
+ object_table[string(s)] = (t_pd*)self;
+ Tcl_Obj *av[ac+2];
+ av[0] = Tcl_NewStringObj(name, -1);
+ Tcl_IncrRefCount(av[0]);
+ av[1] = self->self;
+ for(int i=0; i<ac; i++) {
+ if(pd_to_tcl(&at[i], &av[2+i]) == TCL_ERROR) {
+ post("tcl error: %s\n", Tcl_GetStringResult(tcl_for_pd));
+ pd_free((t_pd *)self);
+ return 0;
+ }
+ }
+ if (Tcl_EvalObjv(tcl_for_pd,ac+2,av,0) != TCL_OK) {
+ post("tcl error: %s\n", Tcl_GetStringResult(tcl_for_pd));
+ pd_free((t_pd *)self);
+ return 0;
+ }
+ return self;
+}
+
+void tclpd_free (t_tcl *self) {
+#ifdef DEBUG
+ post("tclpd_free called");
+#endif
+}
+
+void tclpd_anything(t_tcl *self, t_symbol *s, int ac, t_atom *at) {
+/* proxy method */
+ Tcl_Obj *av[ac+2];
+ av[0] = self->self;
+ av[1] = Tcl_NewIntObj(0); // TODO: 0 -> outlet_number
+ Tcl_AppendToObj(av[1],"_",1);
+ Tcl_AppendToObj(av[1],s->s_name,strlen(s->s_name)); // selector
+ Tcl_IncrRefCount(av[1]);
+ for(int i=0; i<ac; i++) {
+ if(pd_to_tcl(&at[i], &av[2+i]) == TCL_ERROR) {
+ post("Tcl error: %s\n", Tcl_GetStringResult(tcl_for_pd));
+ return;
+ }
+ }
+ int result = Tcl_EvalObjv(tcl_for_pd,ac+2,av,0);
+ Tcl_DecrRefCount(av[1]);
+ if (result != TCL_OK)
+ post("Tcl error: %s\n", Tcl_GetStringResult(tcl_for_pd));
+}
+
+/* Tcl glue: */
+
+t_pd* tclpd_get_instance(const char* objectSequentialId) {
+ return object_table[objectSequentialId];
+}
+
+t_object* tclpd_get_object(const char* objectSequentialId) {
+ t_tcl* x = (t_tcl*)tclpd_get_instance(objectSequentialId);
+ return &x->o;
+}
+
+t_pd* tclpd_get_object_pd(const char* objectSequentialId) {
+ t_object* o = tclpd_get_object(objectSequentialId);
+ return &o->ob_pd;
+}
+
+void poststring2 (const char *s) {
+ post("%s", s);
+}