Update of /cvsroot/pure-data/externals/grill/absattr
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29491
Modified Files:
absattr.cpp
Log Message:
use new ToSys* methods
added loadbang prioritization
Index: absattr.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/absattr/absattr.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** absattr.cpp 24 May 2006 12:21:20 -0000 1.4
--- absattr.cpp 2 Nov 2006 19:03:52 -0000 1.5
***************
*** 1,270 ****
! /*
!
! absattr - patcher attributes
!
! Copyright (c) 2002-2006 Thomas Grill (gr(a)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)
--- 1,271 ----
! /*
!
! absattr - patcher attributes
!
! Copyright (c) 2002-2006 Thomas Grill (gr(a)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)