aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--externals/grill/absattr/absattr.cpp541
1 files changed, 271 insertions, 270 deletions
diff --git a/externals/grill/absattr/absattr.cpp b/externals/grill/absattr/absattr.cpp
index 1ee0e895..8d5da671 100644
--- a/externals/grill/absattr/absattr.cpp
+++ b/externals/grill/absattr/absattr.cpp
@@ -1,270 +1,271 @@
-/*
-
-absattr - patcher attributes
-
-Copyright (c) 2002-2006 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.
-
-*/
-
-#define VERSION "0.2.0"
-
-#include <flext.h>
-
-#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 501)
-#error You need at least flext version 0.5.1
-#endif
-
-#include <map>
-#include <set>
-
-class absattr
- : public flext_base
-{
- FLEXT_HEADER_S(absattr,flext_base,Setup)
-
-public:
- absattr(int argc,const t_atom *argv)
- : parent(0),prior(0)
- , loadbang(true)
- {
- AddInAnything("bang/get/set");
- AddInAnything("external attribute messages");
- AddOutAnything("arguments");
- AddOutAnything("attributes");
- AddOutAnything("external attribute outlet");
-
- // process default values (only attributes can have default values)
- Process(argc,argv,false);
-
- // process canvas arguments
- AtomListStatic<20> args;
- GetCanvasArgs(args);
- Process(args.Count(),args.Atoms(),true);
-
- // add to loadbang registry
- Objects &o = loadbangs[parent].obj;
- o.insert(this);
- }
-
- ~absattr()
- {
- // remove from loadbang registry
- Loadbangs::iterator it = loadbangs.find(parent);
- if(it != loadbangs.end()) {
- Objects &o = it->second.obj;
- for(Objects::iterator oit = o.begin(); oit != o.end(); ++oit) {
- if(*oit == this) {
- // found
- o.erase(oit);
- break;
- }
- }
- FLEXT_ASSERT(oit != o.end());
- if(o.empty()) loadbangs.erase(it);
- }
- else
- error("%s - not found in loadbang registry");
- }
-
- //! dump parameters
- void m_bang() { BangAttr(0); }
-
- void m_bangx() { BangAttr(1); }
-
- void m_dump() { DumpAttr(0); }
-
- void m_get(const t_symbol *s) { OutAttr(0,s); }
-
- void m_dumpx() { DumpAttr(1); }
-
- void m_getx(const t_symbol *s) { OutAttr(1,s); }
-
- void m_set(int argc,const t_atom *argv)
- {
- if(!argc && !IsSymbol(*argv))
- post("%s - attribute must be given as first argument",thisName());
- else {
- const t_symbol *attr = GetSymbol(*argv);
- --argc,++argv;
- SetAttr(attr,argc,argv);
- }
- }
-
-protected:
-
- typedef std::map<const t_symbol *,AtomList> AttrMap;
-
- int parent; // don't change after inserting into registry
- float prior; // don't change after inserting into registry
- bool loadbang;
-
- AtomList args;
- AttrMap attrs;
-
- class Compare
- {
- public:
- bool operator()(const absattr *a,const absattr *b) const { return a->prior == b->prior?a < b:a->prior < b->prior; }
- };
-
- typedef std::set<absattr *,Compare> Objects;
-
- struct Loadbang
- {
- double lasttime;
- Objects obj;
- };
-
- typedef std::map<int,Loadbang> Loadbangs;
-
- static Loadbangs loadbangs;
-
- virtual void CbLoadbang()
- {
- // all loadbangs have the same logical time
- double time = GetTime();
-
- Loadbangs::iterator it = loadbangs.find(parent);
- if(it != loadbangs.end()) {
- Loadbang &lb = it->second;
- // found
- if(lb.lasttime < time) {
- // bang all objects with the same parent in the prioritized order
- for(Objects::iterator oit = lb.obj.begin(); oit != lb.obj.end(); ++oit) {
- absattr *o = *oit;
- FLEXT_ASSERT(o);
- if(o->loadbang) o->m_bang();
- }
-
- // set timestamp
- lb.lasttime = time;
- }
- }
- else
- error("%s - not found in database");
- }
-
- void BangAttr(int ix)
- {
- if(ix == 0)
- ToOutList(ix,args);
-
- for(AttrMap::const_iterator it = attrs.begin(); it != attrs.end(); ++it) {
- const AtomList &lst = it->second;
- ToOutAnything(1+ix,it->first,lst.Count(),lst.Atoms());
- }
- }
-
- void DumpAttr(int ix)
- {
- int cnt = attrs.size();
- AtomListStatic<20> lst(cnt);
-
- AttrMap::const_iterator it = attrs.begin();
- for(int i = 0; it != attrs.end(); ++it,++i)
- SetSymbol(lst[i],it->first);
-
- ToOutAnything(1+ix,sym_attributes,lst.Count(),lst.Atoms());
- }
-
- void OutAttr(int ix,const t_symbol *s)
- {
- AttrMap::const_iterator it = attrs.find(s);
- if(it != attrs.end()) {
- const AtomList &lst = it->second;
- ToOutAnything(1+ix,s,lst.Count(),lst.Atoms());
- }
- else
- post("%s - attribute %s not found",thisName(),GetString(s));
- }
-
- void SetAttr(const t_symbol *attr,int argc,const t_atom *argv)
- {
- if(argc) {
- AtomList &lst = attrs[attr];
- lst.Set(argc,argv,0,true);
- }
- else
- attrs.erase(attr);
- }
-
- static bool IsAttr(const t_atom &at) { return IsSymbol(at) && *GetString(at) == '@'; }
-
- void Process(int argc,const t_atom *argv,bool ext)
- {
- int cnt = CheckAttrib(argc,argv);
-
- args.Set(cnt,argv,0,true);
- argc -= cnt,argv += cnt;
-
- while(argc) {
- FLEXT_ASSERT(IsAttr(*argv));
- const t_symbol *attr = MakeSymbol(GetString(*argv)+1);
- --argc,++argv;
-
- cnt = CheckAttrib(argc,argv);
- if(cnt) {
- if(attr == sym_loadbang) {
- if(ext) {
- if(cnt == 2 && CanbeInt(argv[0]) && CanbeFloat(argv[1])) {
- parent = GetAInt(argv[0]);
- prior = GetAFloat(argv[1]);
- }
- else
- post("%s - expected: @loadbang [parent-id ($0)] priority",thisName());
- }
- else {
- if(cnt == 1 && CanbeBool(*argv))
- loadbang = GetABool(*argv);
- else
- post("%s - expected: @loadbang 0/1",thisName());
- }
- }
- else {
- AtomList &lst = attrs[attr];
- lst.Set(cnt,argv,0,true);
- }
- argc -= cnt,argv += cnt;
- }
- else
- attrs.erase(attr);
- }
- }
-
-private:
-
- static const t_symbol *sym_attributes;
- static const t_symbol *sym_loadbang;
-
- FLEXT_CALLBACK(m_bang);
- FLEXT_CALLBACK_S(m_get);
- FLEXT_CALLBACK(m_dump);
- FLEXT_CALLBACK(m_bangx);
- FLEXT_CALLBACK_S(m_getx);
- FLEXT_CALLBACK(m_dumpx);
- FLEXT_CALLBACK_V(m_set);
-
- static void Setup(t_classid cl)
- {
- sym_attributes = MakeSymbol("attributes");
- sym_loadbang = MakeSymbol("loadbang");
-
- FLEXT_CADDBANG(cl,0,m_bang);
- FLEXT_CADDMETHOD_(cl,0,"get",m_get);
- FLEXT_CADDMETHOD_(cl,0,"getattributes",m_dump);
- FLEXT_CADDMETHOD_(cl,0,"set",m_set);
- FLEXT_CADDBANG(cl,1,m_bangx);
- FLEXT_CADDMETHOD_(cl,1,"get",m_getx);
- FLEXT_CADDMETHOD_(cl,1,"getattributes",m_dumpx);
- FLEXT_CADDMETHOD_(cl,1,"set",m_set);
- }
-};
-
-const t_symbol *absattr::sym_attributes;
-const t_symbol *absattr::sym_loadbang;
-
-absattr::Loadbangs absattr::loadbangs;
-
-FLEXT_NEW_V("absattr",absattr)
+/*
+
+absattr - patcher attributes
+
+Copyright (c) 2002-2006 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.
+
+*/
+
+#define VERSION "0.2.0"
+
+#include <flext.h>
+
+#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 501)
+#error You need at least flext version 0.5.1
+#endif
+
+#include <map>
+#include <set>
+
+class absattr
+ : public flext_base
+{
+ FLEXT_HEADER_S(absattr,flext_base,Setup)
+
+public:
+ absattr(int argc,const t_atom *argv)
+ : parent(0),prior(0)
+ , loadbang(true)
+ {
+ AddInAnything("bang/get/set");
+ AddInAnything("external attribute messages");
+ AddOutAnything("arguments");
+ AddOutAnything("attributes");
+ AddOutAnything("external attribute outlet");
+
+ // process default values (only attributes can have default values)
+ Process(argc,argv,false);
+
+ // process canvas arguments
+ AtomListStatic<20> args;
+ GetCanvasArgs(args);
+ Process(args.Count(),args.Atoms(),true);
+
+ // add to loadbang registry
+ Objects &o = loadbangs[parent].obj;
+ o.insert(this);
+ }
+
+ ~absattr()
+ {
+ // remove from loadbang registry
+ Loadbangs::iterator it = loadbangs.find(parent);
+ if(it != loadbangs.end()) {
+ Objects &o = it->second.obj;
+ Objects::iterator oit;
+ for(oit = o.begin(); oit != o.end(); ++oit) {
+ if(*oit == this) {
+ // found
+ o.erase(oit);
+ break;
+ }
+ }
+ FLEXT_ASSERT(oit != o.end());
+ if(o.empty()) loadbangs.erase(it);
+ }
+ else
+ error("%s - not found in loadbang registry");
+ }
+
+ //! dump parameters
+ void m_bang() { BangAttr(0); }
+
+ void m_bangx() { BangAttr(1); }
+
+ void m_dump() { DumpAttr(0); }
+
+ void m_get(const t_symbol *s) { OutAttr(0,s); }
+
+ void m_dumpx() { DumpAttr(1); }
+
+ void m_getx(const t_symbol *s) { OutAttr(1,s); }
+
+ void m_set(int argc,const t_atom *argv)
+ {
+ if(!argc && !IsSymbol(*argv))
+ post("%s - attribute must be given as first argument",thisName());
+ else {
+ const t_symbol *attr = GetSymbol(*argv);
+ --argc,++argv;
+ SetAttr(attr,argc,argv);
+ }
+ }
+
+protected:
+
+ typedef std::map<const t_symbol *,AtomList> AttrMap;
+
+ int parent; // don't change after inserting into registry
+ float prior; // don't change after inserting into registry
+ bool loadbang;
+
+ AtomList args;
+ AttrMap attrs;
+
+ class Compare
+ {
+ public:
+ bool operator()(const absattr *a,const absattr *b) const { return a->prior == b->prior?a < b:a->prior < b->prior; }
+ };
+
+ typedef std::set<absattr *,Compare> Objects;
+
+ struct Loadbang
+ {
+ double lasttime;
+ Objects obj;
+ };
+
+ typedef std::map<int,Loadbang> Loadbangs;
+
+ static Loadbangs loadbangs;
+
+ virtual void CbLoadbang()
+ {
+ // all loadbangs have the same logical time
+ double time = GetTime();
+
+ Loadbangs::iterator it = loadbangs.find(parent);
+ if(it != loadbangs.end()) {
+ Loadbang &lb = it->second;
+ // found
+ if(lb.lasttime < time) {
+ // bang all objects with the same parent in the prioritized order
+ for(Objects::iterator oit = lb.obj.begin(); oit != lb.obj.end(); ++oit) {
+ absattr *o = *oit;
+ FLEXT_ASSERT(o);
+ if(o->loadbang) o->m_bang();
+ }
+
+ // set timestamp
+ lb.lasttime = time;
+ }
+ }
+ else
+ error("%s - not found in database");
+ }
+
+ void BangAttr(int ix)
+ {
+ if(ix == 0)
+ ToSysList(ix,args);
+
+ for(AttrMap::const_iterator it = attrs.begin(); it != attrs.end(); ++it) {
+ const AtomList &lst = it->second;
+ ToSysAnything(1+ix,it->first,lst.Count(),lst.Atoms());
+ }
+ }
+
+ void DumpAttr(int ix)
+ {
+ int cnt = attrs.size();
+ AtomListStatic<20> lst(cnt);
+
+ AttrMap::const_iterator it = attrs.begin();
+ for(int i = 0; it != attrs.end(); ++it,++i)
+ SetSymbol(lst[i],it->first);
+
+ ToSysAnything(1+ix,sym_attributes,lst.Count(),lst.Atoms());
+ }
+
+ void OutAttr(int ix,const t_symbol *s)
+ {
+ AttrMap::const_iterator it = attrs.find(s);
+ if(it != attrs.end()) {
+ const AtomList &lst = it->second;
+ ToSysAnything(1+ix,s,lst.Count(),lst.Atoms());
+ }
+ else
+ post("%s - attribute %s not found",thisName(),GetString(s));
+ }
+
+ void SetAttr(const t_symbol *attr,int argc,const t_atom *argv)
+ {
+ if(argc) {
+ AtomList &lst = attrs[attr];
+ lst.Set(argc,argv,0,true);
+ }
+ else
+ attrs.erase(attr);
+ }
+
+ static bool IsAttr(const t_atom &at) { return IsSymbol(at) && *GetString(at) == '@'; }
+
+ void Process(int argc,const t_atom *argv,bool ext)
+ {
+ int cnt = CheckAttrib(argc,argv);
+
+ args.Set(cnt,argv,0,true);
+ argc -= cnt,argv += cnt;
+
+ while(argc) {
+ FLEXT_ASSERT(IsAttr(*argv));
+ const t_symbol *attr = MakeSymbol(GetString(*argv)+1);
+ --argc,++argv;
+
+ cnt = CheckAttrib(argc,argv);
+ if(cnt) {
+ if(attr == sym_loadbang) {
+ if(ext) {
+ if(cnt == 2 && CanbeInt(argv[0]) && CanbeFloat(argv[1])) {
+ parent = GetAInt(argv[0]);
+ prior = GetAFloat(argv[1]);
+ }
+ else
+ post("%s - expected: @loadbang [parent-id ($0)] priority",thisName());
+ }
+ else {
+ if(cnt == 1 && CanbeBool(*argv))
+ loadbang = GetABool(*argv);
+ else
+ post("%s - expected: @loadbang 0/1",thisName());
+ }
+ }
+ else {
+ AtomList &lst = attrs[attr];
+ lst.Set(cnt,argv,0,true);
+ }
+ argc -= cnt,argv += cnt;
+ }
+ else
+ attrs.erase(attr);
+ }
+ }
+
+private:
+
+ static const t_symbol *sym_attributes;
+ static const t_symbol *sym_loadbang;
+
+ FLEXT_CALLBACK(m_bang);
+ FLEXT_CALLBACK_S(m_get);
+ FLEXT_CALLBACK(m_dump);
+ FLEXT_CALLBACK(m_bangx);
+ FLEXT_CALLBACK_S(m_getx);
+ FLEXT_CALLBACK(m_dumpx);
+ FLEXT_CALLBACK_V(m_set);
+
+ static void Setup(t_classid cl)
+ {
+ sym_attributes = MakeSymbol("attributes");
+ sym_loadbang = MakeSymbol("loadbang");
+
+ FLEXT_CADDMETHOD(cl,0,m_bang);
+ FLEXT_CADDMETHOD_(cl,0,"get",m_get);
+ FLEXT_CADDMETHOD_(cl,0,"getattributes",m_dump);
+ FLEXT_CADDMETHOD_(cl,0,"set",m_set);
+ FLEXT_CADDMETHOD(cl,1,m_bangx);
+ FLEXT_CADDMETHOD_(cl,1,"get",m_getx);
+ FLEXT_CADDMETHOD_(cl,1,"getattributes",m_dumpx);
+ FLEXT_CADDMETHOD_(cl,1,"set",m_set);
+ }
+};
+
+const t_symbol *absattr::sym_attributes;
+const t_symbol *absattr::sym_loadbang;
+
+absattr::Loadbangs absattr::loadbangs;
+
+FLEXT_NEW_V("absattr",absattr)