diff options
Diffstat (limited to 'externals/grill/dyn/dyn_data.h')
-rw-r--r-- | externals/grill/dyn/dyn_data.h | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/externals/grill/dyn/dyn_data.h b/externals/grill/dyn/dyn_data.h new file mode 100644 index 00000000..e3cc7486 --- /dev/null +++ b/externals/grill/dyn/dyn_data.h @@ -0,0 +1,192 @@ +/* +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 <map> +#include <set> + + +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<dyn_base *> Objects; +typedef std::set<dyn_conn *> Connections; +typedef std::map<int,proxy *> 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<dyn_patcher *>(data); } + dyn_object *Object() { return dynamic_cast<dyn_object *>(data); } + dyn_message *Message() { return dynamic_cast<dyn_message *>(data); } + dyn_text *Text() { return dynamic_cast<dyn_text *>(data); } + dyn_conn *Conn() { return dynamic_cast<dyn_conn *>(data); } + dyn_patchable *Patchable() { return dynamic_cast<dyn_patchable *>(data); } + dyn_listen *Listen() { return dynamic_cast<dyn_listen *>(data); } + + int type; + dyn_base *data; + + dyn_callback *callback; + void *userdata; +}; + +inline void Destroy(dyn_base *b) +{ + b->ident->data = NULL; + delete b; +} + +#endif |