From 9f059a801dd8b840ee6a636b99ce4c8abf05b9e6 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Thu, 2 Nov 2006 19:03:52 +0000 Subject: use new ToSys* methods added loadbang prioritization svn path=/trunk/; revision=6215 --- externals/grill/absattr/absattr.cpp | 541 ++++++++++++++++++------------------ 1 file 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 - -#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 501) -#error You need at least flext version 0.5.1 -#endif - -#include -#include - -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 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 Objects; - - struct Loadbang - { - double lasttime; - Objects obj; - }; - - typedef std::map 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 + +#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 501) +#error You need at least flext version 0.5.1 +#endif + +#include +#include + +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 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 Objects; + + struct Loadbang + { + double lasttime; + Objects obj; + }; + + typedef std::map 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) -- cgit v1.2.1