diff options
Diffstat (limited to 'externals/grill/dyn/src')
-rw-r--r-- | externals/grill/dyn/src/main.cpp | 380 |
1 files changed, 247 insertions, 133 deletions
diff --git a/externals/grill/dyn/src/main.cpp b/externals/grill/dyn/src/main.cpp index 79af2089..cdf37504 100644 --- a/externals/grill/dyn/src/main.cpp +++ b/externals/grill/dyn/src/main.cpp @@ -45,35 +45,45 @@ public: void m_reset(); void m_reload(); // refresh objects/abstractions void m_newobj(int argc,const t_atom *argv); + void m_newmsg(int argc,const t_atom *argv); + void m_newtext(int argc,const t_atom *argv); void m_del(const t_symbol *n); - void m_connect(int argc,const t_atom *argv) { conndis(true,argc,argv); } - void m_disconnect(int argc,const t_atom *argv) { conndis(false,argc,argv); } + void m_connect(int argc,const t_atom *argv) { ConnDis(true,argc,argv); } + void m_disconnect(int argc,const t_atom *argv) { ConnDis(false,argc,argv); } void m_send(int argc,const t_atom *argv); void m_vis(bool vis); protected: + static const t_symbol *k_obj,*k_msg,*k_text; + class obj { public: - obj(const t_symbol *n,t_object *o): name(n),object(o),nxt(NULL) {} + obj(unsigned long i,t_gobj *o): id(i),object(o),nxt(NULL) {} void Add(obj *o); - const t_symbol *name; - t_object *object; + unsigned long id; + t_gobj *object; obj *nxt; } *root; + obj *Find(const t_symbol *n); - void Add(const t_symbol *n,t_object *o); + t_glist *FindCanvas(const t_symbol *n); + void Add(const t_symbol *n,t_gobj *o); + + t_gobj *New(const t_symbol *kind,int _argc_,const t_atom *_argv_,bool add = true); + void Delete(t_gobj *o); - void ToCanvas(t_object *o,t_binbuf *b,int x,int y); - void FromCanvas(t_object *o); + void ConnDis(bool conn,int argc,const t_atom *argv); - virtual bool m_method_(int n,const t_symbol *s,int argc,const t_atom *argv); + + virtual bool m_method_(int n,const t_symbol *s,int argc,const t_atom *argv); virtual void m_dsp(int n,t_signalvec const *insigs,t_signalvec const *outsigs); virtual void m_signal(int n,t_sample *const *insigs,t_sample *const *outsigs); + // proxy object class proxy { @@ -85,7 +95,8 @@ protected: t_sample defsig; void init(dyn *t); - void exit(); + + static void px_exit(proxy *px) { if(px->buf) delete[] px->buf; } }; // proxy for inbound messages @@ -133,10 +144,14 @@ protected: proxyin **pxin; proxyout **pxout; - int m_inlets,s_inlets,m_outlets,s_outlets; - t_canvas *canvas; - void conndis(bool conn,int argc,const t_atom *argv); + static t_object *pxin_new() { return (t_object *)pd_new(pxin_class); } + static t_object *pxins_new() { return (t_object *)pd_new(pxins_class); } + static t_object *pxout_new() { return (t_object *)pd_new(pxout_class); } + static t_object *pxouts_new() { return (t_object *)pd_new(pxouts_class); } + + int m_inlets,s_inlets,m_outlets,s_outlets; + t_canvas *canvas; private: static void setup(t_classid c); @@ -144,6 +159,8 @@ private: FLEXT_CALLBACK(m_reset) FLEXT_CALLBACK(m_reload) FLEXT_CALLBACK_V(m_newobj) + FLEXT_CALLBACK_V(m_newmsg) + FLEXT_CALLBACK_V(m_newtext) FLEXT_CALLBACK_S(m_del) FLEXT_CALLBACK_V(m_connect) FLEXT_CALLBACK_V(m_disconnect) @@ -157,6 +174,11 @@ FLEXT_NEW_DSP_V("dyn~",dyn) t_class *dyn::pxin_class = NULL,*dyn::pxout_class = NULL; t_class *dyn::pxins_class = NULL,*dyn::pxouts_class = NULL; +const t_symbol *dyn::k_obj = NULL; +const t_symbol *dyn::k_msg = NULL; +const t_symbol *dyn::k_text = NULL; + + void dyn::setup(t_classid c) { post(""); @@ -164,32 +186,39 @@ void dyn::setup(t_classid c) post(""); // set up proxy class for inbound messages - pxin_class = class_new(gensym("dyn proxy in"),NULL,NULL,sizeof(proxyin),0, A_NULL); + pxin_class = class_new(gensym("dyn_in"),(t_newmethod)pxin_new,(t_method)proxy::px_exit,sizeof(proxyin),0, A_NULL); add_anything(pxin_class,proxyin::px_method); // set up proxy class for inbound signals - pxins_class = class_new(gensym("dyn proxy in~"),NULL,NULL,sizeof(proxyin),0, A_NULL); + pxins_class = class_new(gensym("dyn_in~"),(t_newmethod)pxins_new,(t_method)proxy::px_exit,sizeof(proxyin),0, A_NULL); add_dsp(pxins_class,proxyin::dsp); CLASS_MAINSIGNALIN(pxins_class, proxyin, defsig); // set up proxy class for outbound messages - pxout_class = class_new(gensym("dyn proxy out"),NULL,NULL,sizeof(proxyout),0, A_NULL); + pxout_class = class_new(gensym("dyn_out"),(t_newmethod)pxout_new,(t_method)proxy::px_exit,sizeof(proxyout),0, A_NULL); add_anything(pxout_class,proxyout::px_method); // set up proxy class for outbound signals - pxouts_class = class_new(gensym("dyn proxy out~"),NULL,NULL,sizeof(proxyout),0, A_NULL); + pxouts_class = class_new(gensym("dyn_out~"),(t_newmethod)pxouts_new,(t_method)proxy::px_exit,sizeof(proxyout),0, A_NULL); add_dsp(pxouts_class,proxyout::dsp); CLASS_MAINSIGNALIN(pxouts_class, proxyout, defsig); // set up dyn~ FLEXT_CADDMETHOD_(c,0,"reset",m_reset); FLEXT_CADDMETHOD_(c,0,"reload",m_reload); - FLEXT_CADDMETHOD_(c,0,"new",m_newobj); + FLEXT_CADDMETHOD_(c,0,"newobj",m_newobj); + FLEXT_CADDMETHOD_(c,0,"newmsg",m_newmsg); + FLEXT_CADDMETHOD_(c,0,"newtext",m_newtext); FLEXT_CADDMETHOD_(c,0,"del",m_del); FLEXT_CADDMETHOD_(c,0,"conn",m_connect); FLEXT_CADDMETHOD_(c,0,"dis",m_disconnect); FLEXT_CADDMETHOD_(c,0,"send",m_send); FLEXT_CADDMETHOD_(c,0,"vis",m_vis); + + // set up symbols + k_obj = MakeSymbol("obj"); + k_msg = MakeSymbol("msg"); + k_text = MakeSymbol("text"); } @@ -243,7 +272,8 @@ dyn::dyn(int argc,const t_atom *argv): int i; - // make a sub-canvas for dyn~ + // --- make a sub-canvas for dyn~ ------ + t_atom arg[6]; SetInt(arg[0],0); // xpos SetInt(arg[1],0); // ypos @@ -256,27 +286,51 @@ dyn::dyn(int argc,const t_atom *argv): // must do that.... canvas_unsetcurrent(canvas); + // --- create inlet proxies ------ + pxin = new proxyin *[s_inlets+m_inlets]; for(i = 0; i < s_inlets+m_inlets; ++i) { bool sig = i < s_inlets; - pxin[i] = (proxyin *)object_new(sig?pxins_class:pxin_class); - pxin[i]->init(this,sig); - t_binbuf *b = binbuf_new(); - binbuf_text(b,(char *)(sig?"dyn-in~":"dyn-in"),7); - ToCanvas(&pxin[i]->obj,b,i*100,10); // place them left-to-right - } + + t_atom lst[5]; + SetInt(lst[0],i*100); + SetInt(lst[1],10); + SetString(lst[2],"."); + SetString(lst[3],""); + SetString(lst[4],sig?"dyn_in~":"dyn_in"); + + try { + pxin[i] = (proxyin *)New(k_obj,5,lst,false); + if(pxin[i]) pxin[i]->init(this,sig); + } + catch(...) { + error("%s - Error creating inlet proxy",thisName()); + } + } + + // --- create outlet proxies ------ pxout = new proxyout *[s_outlets+m_outlets]; for(i = 0; i < s_outlets+m_outlets; ++i) { bool sig = i < s_outlets; - pxout[i] = (proxyout *)object_new(sig?pxouts_class:pxout_class); - pxout[i]->init(this,i,sig); - t_binbuf *b = binbuf_new(); - binbuf_text(b,(char *)(sig?"dyn-out~":"dyn-out"),8); - ToCanvas(&pxout[i]->obj,b,i*100,500); // place them left-to-right - } - AddInSignal("Messages (new,del,conn,dis)"); + t_atom lst[5]; + SetInt(lst[0],i*100); + SetInt(lst[1],500); + SetString(lst[2],"."); + SetString(lst[3],""); + SetString(lst[4],sig?"dyn_out~":"dyn_out"); + + try { + pxout[i] = (proxyout *)New(k_obj,5,lst,false); + if(pxout[i]) pxout[i]->init(this,i,sig); + } + catch(...) { + error("%s - Error creating outlet proxy",thisName()); + } + } + + AddInSignal("Messages (newobj,newmsg,newtext,del,conn,dis)"); AddInSignal(s_inlets); AddInAnything(m_inlets); AddOutSignal(s_outlets); @@ -287,20 +341,10 @@ dyn::~dyn() { m_reset(); - if(pxin) { - for(int i = 0; i < s_inlets+m_inlets; ++i) - if(pxin[i]) { pxin[i]->exit(); FromCanvas(&pxin[i]->obj); } - delete[] pxin; - } - if(pxout) { - for(int i = 0; i < s_outlets+m_outlets; ++i) - if(pxout[i]) { pxout[i]->exit(); FromCanvas(&pxout[i]->obj); } - delete[] pxout; - } + if(canvas) pd_free((t_pd *)canvas); - if(canvas) { - pd_free((t_pd *)canvas); - } + if(pxin) delete[] pxin; + if(pxout) delete[] pxout; } @@ -308,139 +352,211 @@ void dyn::obj::Add(obj *o) { if(nxt) nxt->Add(o); else nxt = o; } dyn::obj *dyn::Find(const t_symbol *n) { + unsigned long id = *(unsigned long *)n; obj *o; - for(o = root; o && o->name != n; o = o->nxt) {} + for(o = root; o && o->id != id; o = o->nxt) {} return o; } -void dyn::Add(const t_symbol *n,t_object *ob) +t_glist *dyn::FindCanvas(const t_symbol *n) { - obj *o = new obj(n,ob); - if(root) root->Add(o); else root = o; -} - -void dyn::ToCanvas(t_object *o,t_binbuf *b,int x,int y) -{ - // add object to the glist.... this is needed for graphical representation - // which is needed to have all connections be properly deleted - - o->te_binbuf = b; - o->te_xpix = x,o->te_ypix = y; - o->te_width = 0; - o->te_type = T_OBJECT; - - glist_add(canvas, &o->te_g); + if(n == MakeSymbol(".")) + return canvas; + else { + obj *o = Find(n); + if(o && pd_class(&o->object->g_pd) == canvas_class) + return (t_glist *)o->object; + else + return NULL; + } } -void dyn::FromCanvas(t_object *o) +void dyn::Add(const t_symbol *n,t_gobj *ob) { - glist_delete(canvas,&o->te_g); -} - -void dyn::m_reset() -{ - obj *o = root; - while(o) { - FromCanvas(o->object); - obj *n = o->nxt; - delete o; - o = n; - } - root = NULL; + unsigned long id = *(unsigned long *)n; + obj *o = new obj(id,ob); + if(root) root->Add(o); else root = o; } -void dyn::m_vis(bool vis) +void dyn::Delete(t_gobj *o) { - canvas_vis(canvas,vis?1:0); + glist_delete(canvas,o); } -void dyn::m_reload() +static t_gobj *GetLast(t_glist *gl) { - post("%s - reload: not implemented yet",thisName()); + t_gobj *go; + for (go = gl->gl_list; go->g_next; go = go->g_next); + return go; } - -void dyn::m_newobj(int _argc_,const t_atom *_argv_) +t_gobj *dyn::New(const t_symbol *kind,int _argc_,const t_atom *_argv_,bool add) { + t_gobj *newest = NULL; + const char *err = NULL; int argc = 0; - const t_atom *argv = NULL; - int posx,posy; + t_atom *argv = NULL; + const t_symbol *name = NULL,*canv = NULL; + t_glist *glist = NULL; if(_argc_ >= 4 && CanbeInt(_argv_[0]) && CanbeInt(_argv_[1]) && IsSymbol(_argv_[2]) && IsSymbol(_argv_[3])) { - posx = GetAInt(_argv_[0]); - posy = GetAInt(_argv_[1]); - argc = _argc_-2; - argv = _argv_+2; + canv = GetSymbol(_argv_[2]); + name = GetSymbol(_argv_[3]); + + argc = _argc_-2; + argv = new t_atom[argc]; + SetInt(argv[0],GetAInt(_argv_[0])); + SetInt(argv[1],GetAInt(_argv_[1])); + for(int i = 0; i < argc-2; ++i) SetAtom(argv[i+2],_argv_[i+4]); } - else if(_argc_ >= 2 && IsSymbol(_argv_[0]) && IsSymbol(_argv_[1])) { + else if(_argc_ >= 3 && IsSymbol(_argv_[0]) && IsSymbol(_argv_[1])) { + canv = GetSymbol(_argv_[0]); + name = GetSymbol(_argv_[1]); + + argc = _argc_; + argv = new t_atom[argc]; // random position if not given - posx = rand()%600; - posy = 50+rand()%400; - argc = _argc_; - argv = _argv_; + SetInt(argv[0],rand()%600); + SetInt(argv[1],50+rand()%400); + for(int i = 0; i < argc-2; ++i) SetAtom(argv[i+2],_argv_[i+2]); } if(argv) { - const t_symbol *name = GetSymbol(argv[0]); + if(add && (!name || name == MakeSymbol(".") || Find(name))) + err = "Object name is already present"; + else if(!canv || !(glist = FindCanvas(canv))) + err = "Canvas could not be found"; + else { + // set selected canvas as current + canvas_setcurrent(glist); + + pd_typedmess((t_pd *)glist,(t_symbol *)kind,argc,(t_atom *)argv); - if(Find(name)) - post("%s - new: object \"%s\" is already present",thisName(),GetString(name)); - else { - // now set canvas - canvas_setcurrent(canvas); + if(kind == k_obj) { + t_object *o = (t_object *)pd_newest(); + newest = o?&o->te_g:NULL; - t_binbuf *b = binbuf_new(); - // make arg list - binbuf_add(b,argc-1,(t_atom *)argv+1); - // send message to object maker - binbuf_eval(b,&pd_objectmaker,0,NULL); + if(!newest) { + // PD creates a text object when the intended object could not be created + t_gobj *trash = GetLast(glist); + + // TODO: Test for it.... + + // Delete it! + Delete(trash); + } + } + else + newest = GetLast(glist); // look for latest created object - t_object *x = (t_object *)pd_newest(); - if(x) { - // place it - ToCanvas(x,b,posx,posy); + if(newest) { // add to database - Add(name,x); + if(add) Add(name,newest); // send loadbang (if it is an abstraction) - if(pd_class(&x->te_g.g_pd) == canvas_class) { + if(pd_class(&newest->g_pd) == canvas_class) { // loadbang the abstraction - pd_vmess((t_pd *)x,gensym("loadbang"),""); - } + pd_vmess((t_pd *)newest,gensym("loadbang"),""); + + // hide the sub-canvas + pd_vmess((t_pd *)newest,gensym("vis"),"i",0); + } // restart dsp - that's necessary because ToCanvas is called manually canvas_update_dsp(); } - else { - post("%s - new: Could not create object",thisName()); - binbuf_free(b); - } + else + if(!err) err = "Could not create object"; - // pop the dyn~ canvas - canvas_unsetcurrent(canvas); + // pop the current canvas + canvas_unsetcurrent(glist); } + + delete[] argv; } - else - post("%s - new name object [args]",thisName()); + else + if(!err) err = "new name object [args]"; + + if(err) throw err; + + return newest; +} + + +void dyn::m_reset() +{ + obj *o = root; + while(o) { + Delete(o->object); + obj *n = o->nxt; + delete o; + o = n; + } + root = NULL; +} + +void dyn::m_vis(bool vis) +{ + canvas_vis(canvas,vis?1:0); +} + +void dyn::m_reload() +{ + post("%s - reload: not implemented yet",thisName()); +} + +void dyn::m_newobj(int argc,const t_atom *argv) +{ + try { New(k_obj,argc,argv); } + catch(const char *err) { + post("%s - %s",thisName(),err); + } + catch(...) { + post("%s - unknown error",thisName()); + } +} + +void dyn::m_newmsg(int argc,const t_atom *argv) +{ + try { New(k_msg,argc,argv); } + catch(const char *err) { + post("%s - %s",thisName(),err); + } + catch(...) { + post("%s - unknown error",thisName()); + } +} + +void dyn::m_newtext(int argc,const t_atom *argv) +{ + try { New(k_text,argc,argv); } + catch(const char *err) { + post("%s - %s",thisName(),err); + } + catch(...) { + post("%s - unknown error",thisName()); + } } void dyn::m_del(const t_symbol *n) { - obj *p = NULL,*o = root; - for(; o && o->name != n; p = o,o = o->nxt) {} + unsigned long id = *(unsigned long *)n; + + obj *p = NULL,*o = root; + for(; o && o->id != id; p = o,o = o->nxt) {} if(o) { if(p) p->nxt = o->nxt; else root = o->nxt; - FromCanvas(o->object); + Delete(o->object); delete o; } else post("%s - del: object not found",thisName()); } -void dyn::conndis(bool conn,int argc,const t_atom *argv) +void dyn::ConnDis(bool conn,int argc,const t_atom *argv) { const t_symbol *s_n = NULL,*d_n = NULL; int s_x,d_x; @@ -475,14 +591,14 @@ void dyn::conndis(bool conn,int argc,const t_atom *argv) return; } - t_object *s_obj,*d_obj; + t_text *s_obj,*d_obj; if(s_n) { obj *s_o = Find(s_n); if(!s_o) { post("%s - connect: source \"%s\" not found",thisName(),GetString(s_n)); return; } - s_obj = s_o->object; + s_obj = (t_text *)s_o->object; } else if(s_x < 0 && s_x >= s_inlets+m_inlets) { post("%s - connect: inlet %i out of range (0..%i)",thisName(),s_x,s_inlets+m_inlets-1); @@ -499,7 +615,7 @@ void dyn::conndis(bool conn,int argc,const t_atom *argv) post("%s - connect: destination \"%s\" not found",thisName(),GetString(d_n)); return; } - d_obj = d_o->object; + d_obj = (t_text *)d_o->object; } else if(d_x < 0 && d_x >= s_outlets+m_outlets) { post("%s - connect: outlet %i out of range (0..%i)",thisName(),d_x,s_outlets+m_outlets-1); @@ -511,12 +627,12 @@ void dyn::conndis(bool conn,int argc,const t_atom *argv) } #ifndef NO_VIS - int s_oix = canvas_getindex(canvas,&s_obj->ob_g); - int d_oix = canvas_getindex(canvas,&d_obj->ob_g); + int s_oix = canvas_getindex(canvas,&s_obj->te_g); + int d_oix = canvas_getindex(canvas,&d_obj->te_g); #endif if(conn) { - if(!canvas_isconnected(canvas,s_obj,s_x,d_obj,d_x)) { + if(!canvas_isconnected(canvas,(t_text *)s_obj,s_x,(t_text *)d_obj,d_x)) { #ifdef NO_VIS if(!obj_connect(s_obj, s_x, d_obj, d_x)) post("%s - connect: connection could not be made",thisName()); @@ -569,8 +685,6 @@ void dyn::proxy::init(dyn *t) defsig = 0; } -void dyn::proxy::exit() { if(buf) delete[] buf; } - void dyn::proxyin::dsp(proxyin *x,t_signal **sp) { @@ -614,7 +728,7 @@ void dyn::proxyout::init(dyn *t,int o,bool s) void dyn::m_dsp(int n,t_signalvec const *insigs,t_signalvec const *outsigs) { // add sub canvas to dsp list (no signal vector to borrow from .. set it to NULL) -// mess1((t_pd *)canvas, gensym("dsp"),NULL); + mess1((t_pd *)canvas, gensym("dsp"),NULL); flext_dsp::m_dsp(n,insigs,outsigs); } |