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@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@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)