aboutsummaryrefslogtreecommitdiff
path: root/tcl_class.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'tcl_class.cxx')
-rw-r--r--tcl_class.cxx446
1 files changed, 0 insertions, 446 deletions
diff --git a/tcl_class.cxx b/tcl_class.cxx
deleted file mode 100644
index 25af02d..0000000
--- a/tcl_class.cxx
+++ /dev/null
@@ -1,446 +0,0 @@
-#include "tcl_extras.h"
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#define CLASS_TABLE_SIZE (1 << 7)
-#define OBJECT_TABLE_SIZE (1 << 8)
-
-static inline uint32_t hash_str(const char *s)
-{
- const unsigned char *p = (const unsigned char *)s;
- uint32_t h = 5381;
-
- while (*p) {
- h *= 33;
- h ^= *p++;
- }
-
- return h ^ (h >> 16);
-}
-
-typedef struct list_node
-{
- const char* k;
- void* v;
- struct list_node* next;
-} list_node_t;
-
-static inline list_node_t* list_add(list_node_t* head, const char* k, void* v)
-{
- list_node_t* n = (list_node_t*)malloc(sizeof(list_node_t));
- n->next = head;
- n->k = k;
- n->v = v;
- return n;
-}
-
-static inline list_node_t* list_remove(list_node_t* head, const char* k)
-{
- list_node_t* tmp;
-
- // head remove
- while(head && strcmp(head->k, k) == 0)
- {
- tmp = head;
- head = head->next;
- free(tmp);
- }
-
- list_node_t* p = head;
-
- // normal (non-head) remove
- while(p->next)
- {
- if(strcmp(p->next->k, k) == 0)
- {
- tmp = p->next;
- p->next = p->next->next;
- free(tmp);
- continue;
- }
- p = p->next;
- }
-
- return head;
-}
-
-static inline void* list_get(list_node_t* head, const char* k)
-{
- while(head)
- {
- if(strcmp(head->k, k) == 0)
- return head->v;
- head = head->next;
- }
- return (void*)0;
-}
-
-static inline void list_print(list_node_t* head)
-{
- if(!head)
- {
- printf("NULL\n");
- return;
- }
- while(head)
- {
- printf("%s=x%8.8X", head->k, head->v);
- if(head->next) printf(", ");
- head = head->next;
- }
- printf("\n");
-}
-
-
-static list_node_t* class_tbl[CLASS_TABLE_SIZE];
-static list_node_t* object_tbl[OBJECT_TABLE_SIZE];
-
-static inline void class_table_add(const char* name, t_class* c)
-{
- uint32_t h = hash_str(name) % CLASS_TABLE_SIZE;
- class_tbl[h] = list_add(class_tbl[h], name, (void*)c);
-}
-
-static inline void class_table_remove(const char* name)
-{
- uint32_t h = hash_str(name) % CLASS_TABLE_SIZE;
- class_tbl[h] = list_remove(class_tbl[h], name);
-}
-
-static inline t_class* class_table_get(const char* name)
-{
- uint32_t h = hash_str(name) % CLASS_TABLE_SIZE;
- return (t_class*)list_get(class_tbl[h], name);
-}
-
-static inline void object_table_add(const char* name, t_pd* o)
-{
- uint32_t h = hash_str(name) % OBJECT_TABLE_SIZE;
- object_tbl[h] = list_add(object_tbl[h], name, (void*)o);
-}
-
-static inline void object_table_remove(const char* name)
-{
- uint32_t h = hash_str(name) % OBJECT_TABLE_SIZE;
- object_tbl[h] = list_remove(object_tbl[h], name);
-}
-
-static inline t_pd* object_table_get(const char* name)
-{
- uint32_t h = hash_str(name) % OBJECT_TABLE_SIZE;
- return (t_pd*)list_get(object_tbl[h], name);
-}
-
-static unsigned long objectSequentialId = 0;
-
-static list_node_t* class_tbl[CLASS_TABLE_SIZE];
-static list_node_t* object_tbl[OBJECT_TABLE_SIZE];
-
-/* set up the class that handles loading of tcl classes */
-t_class* tclpd_class_new(const 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);
-
- if(!class_table_get(name))
- class_table_add(name, c);
-
- class_addanything(c, tclpd_anything);
- class_addmethod(c, (t_method)tclpd_loadbang, gensym("loadbang"), A_NULL);
-
- // always set save function. it will call the default if
- // none exists in tcl space.
- class_setsavefn(c, tclpd_save);
-
- // check if properties function exists in tcl space.
- char buf[80];
- int res_i;
- snprintf(buf, 80, "llength [info procs ::%s_object_properties]", name);
- if(Tcl_Eval(tcl_for_pd, buf) == TCL_OK) {
- Tcl_Obj* res = Tcl_GetObjResult(tcl_for_pd);
- if(Tcl_GetIntFromObj(tcl_for_pd, res, &res_i) == TCL_OK) {
- if(res_i) {
- class_setpropertiesfn(c, tclpd_properties);
- }
-#ifdef DEBUG
- else {
- post("tclpd_class_new: propertiesfn does not exist", buf);
- }
-#endif
- }
-#ifdef DEBUG
- else {
- post("tclpd_class_new: Tcl_GetIntFromObj returned an error");
- }
-#endif
- }
-#ifdef DEBUG
- else {
- post("tclpd_class_new: [info procs] returned an error");
- }
-#endif
- return c;
-}
-
-t_class* tclpd_guiclass_new(const char* name, int flags) {
- t_class* c = tclpd_class_new(name, flags);
- t_widgetbehavior* wb = (t_widgetbehavior*)getbytes(sizeof(t_widgetbehavior));
- wb->w_getrectfn = tclpd_guiclass_getrect;
- wb->w_displacefn = tclpd_guiclass_displace;
- wb->w_selectfn = tclpd_guiclass_select;
- wb->w_activatefn = NULL;
- wb->w_deletefn = tclpd_guiclass_delete;
- wb->w_visfn = tclpd_guiclass_vis;
- wb->w_clickfn = tclpd_guiclass_click;
- class_setwidget(c, wb);
- return c;
-}
-
-t_tcl* tclpd_new(t_symbol* classsym, int ac, t_atom* at) {
- // lookup in class table
- const char* name = classsym->s_name;
- t_class* qlass = class_table_get(name);
-
- t_tcl* x = (t_tcl*)pd_new(qlass);
- x->ninlets = 1 /* qlass->c_firstin ??? */;
-
- x->classname = Tcl_NewStringObj(name, -1);
- Tcl_IncrRefCount(x->classname);
-
- char s[64];
- snprintf(s, 64, "tclpd:%s:x%lx", name, objectSequentialId++);
- x->self = Tcl_NewStringObj(s, -1);
- Tcl_IncrRefCount(x->self);
-
- x->x_glist = (t_glist*)canvas_getcurrent();
-
- // store in object table (for later lookup)
- if(!object_table_get(s))
- object_table_add(s, x);
-
- // build constructor command
- Tcl_Obj *av[ac+2]; InitArray(av, ac+2, NULL);
- av[0] = x->classname;
- Tcl_IncrRefCount(av[0]);
- av[1] = x->self;
- Tcl_IncrRefCount(av[1]);
- for(int i=0; i<ac; i++) {
- if(pd_to_tcl(&at[i], &av[2+i]) == TCL_ERROR) {
-#ifdef DEBUG
- post("pd_to_tcl: tclpd_new: failed during conversion. check memory leaks!");
-#endif
- goto error;
- }
- }
- // call constructor
- if(Tcl_EvalObjv(tcl_for_pd, ac+2, av, 0) != TCL_OK) {
- goto error;
- }
-
- for(int i = 0; i < (ac+2); i++)
- Tcl_DecrRefCount(av[i]);
-
- return x;
-
-error:
- tclpd_interp_error(TCL_ERROR);
- for(int i = 0; i < (ac+2); i++) {
- if(!av[i]) break;
- Tcl_DecrRefCount(av[i]);
- }
- pd_free((t_pd*)x);
- return 0;
-}
-
-void tclpd_free(t_tcl* x) {
- // build destructor command
- Tcl_Obj *sym = Tcl_NewStringObj(Tcl_GetStringFromObj(x->classname, NULL), -1);
- Tcl_AppendToObj(sym, "_destructor", -1);
- Tcl_Obj *av[2]; InitArray(av, 2, NULL);
- av[0] = sym;
- Tcl_IncrRefCount(av[0]);
- av[1] = x->self;
- Tcl_IncrRefCount(av[1]);
- // call destructor
- if(Tcl_EvalObjv(tcl_for_pd, 2, av, 0) != TCL_OK) {
-#ifdef DEBUG
- post("tclpd_free: failed");
-#endif
- }
- Tcl_DecrRefCount(av[0]);
- Tcl_DecrRefCount(av[1]);
-
- Tcl_DecrRefCount(x->self);
- Tcl_DecrRefCount(x->classname);
-#ifdef DEBUG
- post("tclpd_free called");
-#endif
-}
-
-void tclpd_anything(t_tcl* x, t_symbol* s, int ac, t_atom* at) {
- tclpd_inlet_anything(x, 0, s, ac, at);
-}
-
-void tclpd_inlet_anything(t_tcl* x, int inlet, t_symbol* s, int ac, t_atom* at) {
- // proxy method - format: <self> <inlet#> <selector> ...
- Tcl_Obj* av[ac+3]; InitArray(av, ac+3, NULL);
- int result;
-
- av[0] = x->self;
- Tcl_IncrRefCount(av[0]);
- av[1] = Tcl_NewIntObj(inlet);
- Tcl_IncrRefCount(av[1]);
- av[2] = Tcl_NewStringObj(s->s_name, -1);
- Tcl_IncrRefCount(av[2]);
- for(int i=0; i<ac; i++) {
- if(pd_to_tcl(&at[i], &av[3+i]) == TCL_ERROR) {
-#ifdef DEBUG
- post("pd_to_tcl: tclpd_inlet_anything: failed during conversion. check memory leaks!");
-#endif
- goto error;
- }
- }
- result = Tcl_EvalObjv(tcl_for_pd, ac+3, av, 0);
- if(result != TCL_OK) {
- goto error;
- }
-
- for(int i=0; i < (ac+3); i++)
- Tcl_DecrRefCount(av[i]);
-
- // OK
- return;
-
-error:
- tclpd_interp_error(TCL_ERROR);
- for(int i=0; i < (ac+3); i++) {
- if(!av[i]) break;
- Tcl_DecrRefCount(av[i]);
- }
- return;
-}
-
-void tclpd_loadbang(t_tcl* x) {
- tclpd_inlet_anything(x, 0, gensym("loadbang"), 0, NULL);
-}
-
-/* Tcl glue: */
-
-t_proxyinlet* tclpd_add_proxyinlet(t_tcl* x) {
- t_proxyinlet* proxy = (t_proxyinlet*)pd_new(proxyinlet_class);
- proxyinlet_init(proxy);
- proxy->target = x;
- proxy->ninlet = x->ninlets++;
- inlet_new(&x->o, &proxy->obj.ob_pd, 0, 0);
- return proxy;
-}
-
-t_tcl* tclpd_get_instance(const char* objectSequentialId) {
- return (t_tcl*)object_table_get(objectSequentialId);
-}
-
-t_pd* tclpd_get_instance_pd(const char* objectSequentialId) {
- return (t_pd*)object_table_get(objectSequentialId);
-}
-
-t_object* tclpd_get_object(const char* objectSequentialId) {
- t_tcl* x = 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;
-}
-
-t_glist* tclpd_get_glist(const char* objectSequentialId) {
- t_tcl* x = tclpd_get_instance(objectSequentialId);
- return x->x_glist;
-}
-
-t_symbol* null_symbol() {
- return (t_symbol*)0;
-}
-
-void poststring2 (const char *s) {
- post("%s", s);
-}
-
-void tclpd_save(t_gobj* z, t_binbuf* b) {
- Tcl_Obj* av[3]; InitArray(av, 3, NULL);
- Tcl_Obj* res;
-
- t_tcl* x = (t_tcl*)z;
-
- av[0] = x->self;
- Tcl_IncrRefCount(av[0]);
- av[1] = Tcl_NewStringObj("object", -1);
- Tcl_IncrRefCount(av[1]);
- av[2] = Tcl_NewStringObj("save", -1);
- Tcl_IncrRefCount(av[2]);
- int result = Tcl_EvalObjv(tcl_for_pd, 3, av, 0);
- if(result == TCL_OK) {
- res = Tcl_GetObjResult(tcl_for_pd);
- Tcl_IncrRefCount(res);
- int objc;
- Tcl_Obj** objv;
- result = Tcl_ListObjGetElements(tcl_for_pd, res, &objc, &objv);
- if(result == TCL_OK) {
- if(objc == 0 && objv == NULL) {
- // call default savefn
- text_save(z, b);
- } else {
- // do custom savefn
- int i;
- double tmp;
- for(i = 0; i < objc; i++) {
- result = Tcl_GetDoubleFromObj(tcl_for_pd, objv[i], &tmp);
- if(result == TCL_OK) {
- binbuf_addv(b, "f", (t_float)tmp);
- } else {
- char* tmps = Tcl_GetStringFromObj(objv[i], NULL);
- if(!strcmp(tmps, ";")) {
- binbuf_addv(b, ";");
- } else {
- binbuf_addv(b, "s", gensym(tmps));
- }
- }
- }
- }
- } else {
- pd_error(x, "Tcl: object save: failed");
- tclpd_interp_error(result);
- }
- Tcl_DecrRefCount(res);
- } else {
- pd_error(x, "Tcl: object save: failed");
- tclpd_interp_error(result);
- }
- Tcl_DecrRefCount(av[0]);
- Tcl_DecrRefCount(av[1]);
- Tcl_DecrRefCount(av[2]);
-}
-
-void tclpd_properties(t_gobj* z, t_glist* owner) {
- Tcl_Obj* av[3]; InitArray(av, 3, NULL);
- Tcl_Obj* res;
-
- t_tcl* x = (t_tcl*)z;
-
- av[0] = x->self;
- Tcl_IncrRefCount(av[0]);
- av[1] = Tcl_NewStringObj("object", -1);
- Tcl_IncrRefCount(av[1]);
- av[2] = Tcl_NewStringObj("properties", -1);
- Tcl_IncrRefCount(av[2]);
- int result = Tcl_EvalObjv(tcl_for_pd, 3, av, 0);
- if(result != TCL_OK) {
- //res = Tcl_GetObjResult(tcl_for_pd);
- pd_error(x, "Tcl: object properties: failed");
- tclpd_interp_error(result);
- }
- Tcl_DecrRefCount(av[0]);
- Tcl_DecrRefCount(av[1]);
- Tcl_DecrRefCount(av[2]);
-}