/* dyn - dynamical object management Copyright (c)2003-2004 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ #ifndef __DYN_DATA_H #define __DYN_DATA_H #include "dyn_proxy.h" #include #include class dyn_patcher; class dyn_conn; class dyn_base { public: dyn_base(dyn_id id); dyn_id ident; friend void Destroy(dyn_base *b); protected: virtual ~dyn_base(); }; typedef std::set Objects; typedef std::set Connections; typedef std::map Proxies; class dyn_patchable: public dyn_base { public: dyn_patchable(dyn_id id,dyn_patcher *o,t_gobj *obj); void AddProxyIn(int inlet,proxyin *o) { pxin[inlet] = o; } void RmvProxyIn(int inlet) { pxin.erase(inlet); } proxyin *GetProxyIn(int inlet) { Proxies::iterator it = pxin.find(inlet); return it != pxin.end()?(proxyin *)it->second:NULL; } void AddProxyOut(int outlet,proxyout *o) { pxout[outlet] = o; } void RmvProxyOut(int outlet) { pxout.erase(outlet); } proxyout *GetProxyOut(int outlet) { Proxies::iterator it = pxout.find(outlet); return it != pxout.end()?(proxyout *)it->second:NULL; } int GetInletCount() const { return obj_ninlets((t_object *)pdobj); } int GetOutletCount() const { return obj_noutlets((t_object *)pdobj); } int GetInletType(int ix) const { return obj_issignalinlet((t_object *)pdobj,ix)?DYN_INOUT_SIGNAL:DYN_INOUT_MESSAGE; } int GetOutletType(int ix) const { return obj_issignaloutlet((t_object *)pdobj,ix)?DYN_INOUT_SIGNAL:DYN_INOUT_MESSAGE; } void AddInlet(dyn_conn *o); void RmvInlet(dyn_conn *o); void AddOutlet(dyn_conn *o); void RmvOutlet(dyn_conn *o); void EnumInlet(int ix,dyn_enumfun fun,void *data); void EnumOutlet(int ix,dyn_enumfun fun,void *data); t_gobj *pdobj; // PD object dyn_patcher *owner; // patcher protected: virtual ~dyn_patchable(); Proxies pxin,pxout; Connections inconns,outconns; }; class dyn_patcher: public dyn_patchable { public: dyn_patcher(dyn_id id,dyn_patcher *o,t_glist *obj): dyn_patchable(id,o,(t_gobj *)obj) {} virtual ~dyn_patcher(); t_glist *glist() { return (t_glist *)pdobj; } void Add(dyn_base *o) { objs.insert(o); } void Remove(dyn_base *o) { objs.erase(o); } void Enumerate(dyn_enumfun fun,void *data); protected: Objects objs; }; class dyn_object: public dyn_patchable { public: dyn_object(dyn_id id,dyn_patcher *o,t_gobj *obj): dyn_patchable(id,o,obj) {} }; class dyn_message: public dyn_patchable { public: dyn_message(dyn_id id,dyn_patcher *o,t_gobj *obj): dyn_patchable(id,o,obj) {} }; class dyn_text: public dyn_patchable { public: dyn_text(dyn_id id,dyn_patcher *o,t_gobj *obj): dyn_patchable(id,o,obj) {} }; class dyn_conn: public dyn_base { public: dyn_conn(dyn_id id,dyn_id s,int six,dyn_id d,int dix) : dyn_base(id) , src(s),slet(six),dst(d),dlet(dix) {} dyn_id src,dst; // connected objects int slet,dlet; protected: virtual ~dyn_conn(); }; class dyn_listen: public dyn_base { public: dyn_listen(dyn_id id,proxyout *p,dyn_listener cb,void *dt) : dyn_base(id),px(p) , callback(cb),userdata(dt) {} void Callback(int outlet,const t_symbol *sym,int argc,const t_atom *argv) { if(callback) callback(ident,px->object->ident,outlet,sym,argc,argv,userdata); } proxyout *px; dyn_listener *callback; void *userdata; protected: virtual ~dyn_listen(); }; struct dyn_ident { dyn_ident(int tp,dyn_callback cb,void *dt = NULL): type(tp),data(NULL), callback(cb),userdata(dt) {} ~dyn_ident() { // data should already have been cleared by the objects ASSERT(!data); } void Set(dyn_base *obj) { data = obj; } void Callback(int signal) { if(callback) callback(this,signal,userdata); } dyn_patcher *Patcher() { return dynamic_cast(data); } dyn_object *Object() { return dynamic_cast(data); } dyn_message *Message() { return dynamic_cast(data); } dyn_text *Text() { return dynamic_cast(data); } dyn_conn *Conn() { return dynamic_cast(data); } dyn_patchable *Patchable() { return dynamic_cast(data); } dyn_listen *Listen() { return dynamic_cast(data); } int type; dyn_base *data; dyn_callback *callback; void *userdata; }; inline void Destroy(dyn_base *b) { b->ident->data = NULL; delete b; } #endif