From 562dcc336797951b2a8707413aa44177484c9f2a Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Sat, 28 Dec 2002 04:37:42 +0000 Subject: "" svn path=/trunk/; revision=309 --- externals/grill/flext/source/flattr.cpp | 212 ++++++++++++++++++++++---------- 1 file changed, 144 insertions(+), 68 deletions(-) (limited to 'externals/grill/flext/source/flattr.cpp') diff --git a/externals/grill/flext/source/flattr.cpp b/externals/grill/flext/source/flattr.cpp index 44dc0d28..5612ab33 100644 --- a/externals/grill/flext/source/flattr.cpp +++ b/externals/grill/flext/source/flattr.cpp @@ -21,41 +21,80 @@ WARRANTIES, see the file, "license.txt," in this distribution. #define STD #endif -flext_base::attritem::attritem(const t_symbol *t,const t_symbol *gt,metharg tp,methfun gf,methfun sf): - tag(t),gtag(gt),argtp(tp),gfun(gf),sfun(sf),nxt(NULL) -{} +flext_base::attritem::attritem(const t_symbol *t,metharg tp,methfun f,bool g): + item(t,0,NULL),argtp(tp), + fun(f),isget(g) +{ +} flext_base::attritem::~attritem() { - if(nxt) delete nxt; +// if(nxt) delete nxt; } +/* void flext_base::AddAttrItem(attritem *m) { - if(attrhead) { + int ix = m->Hash(); + post("attr index %x",ix); + attritem *&aix = attrhead[ix]; + + if(aix) { attritem *mi; - for(mi = attrhead; mi->nxt; mi = mi->nxt) {} + for(mi = aix; mi->nxt; mi = mi->nxt) {} mi->nxt = m; } else - attrhead = m; - attrcnt++; + aix = m; +// m->th->attrcnt++; } +*/ -void flext_base::AddAttrib(const char *attr,metharg tp,methfun gfun,methfun sfun) +//! Add get and set attributes +void flext_base::AddAttrib(itemarr *aa,itemarr *ma,const char *attr,metharg tp,methfun gfun,methfun sfun) { - if(procattr) { - char tmp[256] = "get"; + const t_symbol *asym = MakeSymbol(attr); + +// if(sfun) // if commented out, there will be a warning at run-time (more user-friendly) + { + attritem *a = new attritem(asym,tp,sfun,false); + aa->Add(a); + + // bind attribute to a method + methitem *mi = new methitem(0,asym,a); + mi->SetArgs(sfun,1,&tp); + ma->Add(mi); + } + +// if(gfun) // if commented out, there will be a warning at run-time (more user-friendly) + { + attritem *a = new attritem(asym,tp,gfun,true); + aa->Add(a); + + static char tmp[256] = "get"; strcpy(tmp+3,attr); - AddAttrItem(new attritem(MakeSymbol(attr),MakeSymbol(tmp),tp,gfun,sfun)); - AddMethod(0,attr,(methfun)cb_SetAttrib,a_any,a_null); - AddMethod(0,tmp,(methfun)cb_GetAttrib,a_any,a_null); + // bind attribute to a method + methitem *mi = new methitem(0,MakeSymbol(tmp),a); + mi->SetArgs(gfun,0,NULL); + ma->Add(mi); } +} + +void flext_base::AddAttrib(const char *attr,metharg tp,methfun gfun,methfun sfun) +{ + if(procattr) + AddAttrib(ThAttrs(),ThMeths(),attr,tp,gfun,sfun); else error("%s - attribute procession is not enabled!",thisName()); } +void flext_base::AddAttrib(t_class *c,const char *attr,metharg tp,methfun gfun,methfun sfun) +{ + AddAttrib(ClAttrs(c),ClMeths(c),attr,tp,gfun,sfun); +} + + int flext_base::CheckAttrib(int argc,const t_atom *argv) { int offs = 0; @@ -81,9 +120,19 @@ bool flext_base::InitAttrib(int argc,const t_atom *argv) bool flext_base::ListAttrib() { if(outattr) { - AtomList la(attrcnt); - attritem *a = attrhead; - for(int i = 0; i < attrcnt; ++i,a = a->nxt) SetSymbol(la[i],a->tag); + int cnt = attrhead?attrhead->Count():0; + int ccnt = clattrhead?clattrhead->Count():0; + AtomList la(ccnt+cnt); + + for(int i = 0,ix = 0; i <= 1; ++i) { + itemarr *a = i?attrhead:clattrhead; + if(a) { + for(int ai = 0; ai < a->Size(); ++ai) { + for(item *l = a->Item(ai); l; l = l->nxt) + SetSymbol(la[ix++],l->tag); + } + } + } ToOutAnything(outattr,MakeSymbol("attributes"),la.Count(),la.Atoms()); return true; @@ -94,90 +143,117 @@ bool flext_base::ListAttrib() bool flext_base::SetAttrib(const t_symbol *tag,int argc,const t_atom *argv) { - attritem *a = attrhead; - for(; a && a->tag != tag; a = a->nxt) {} + // search for matching attribute + attritem *a = (attritem *)attrhead->Find(tag); + while(a && (a->tag != tag || a->inlet != 0 || a->isget)) a = (attritem *)a->nxt; + if(!a) { + a = (attritem *)clattrhead->Find(tag); + while(a && (a->tag != tag || a->inlet != 0 || a->isget)) a = (attritem *)a->nxt; + } - if(a) { - if(a->sfun) { - bool ok = true; + if(a) + return SetAttrib(a,argc,argv); + else { + error("%s - %s: attribute not found",thisName(),GetString(tag)); + return true; + } +} - AtomList la; - t_any any; - switch(a->argtp) { - case a_float: - if(argc == 1 && CanbeFloat(argv[0])) { - any.ft = GetAFloat(argv[0]); - ((methfun_1)a->sfun)(this,any); - } - else ok = false; - break; - case a_int: - if(argc == 1 && CanbeInt(argv[0])) { - any.it = GetAInt(argv[0]); - ((methfun_1)a->sfun)(this,any); - } - else ok = false; - break; - case a_symbol: - if(argc == 1 && IsSymbol(argv[0])) { - any.st = GetSymbol(argv[0]); - ((methfun_1)a->sfun)(this,any); - } - else ok = false; - break; - case a_LIST: - any.vt = &(la(argc,argv)); - ((methfun_1)a->sfun)(this,any); - break; - default: - ERRINTERNAL(); - } +bool flext_base::SetAttrib(attritem *a,int argc,const t_atom *argv) +{ + if(a->fun) { + bool ok = true; - if(!ok) - post("%s - wrong arguments for attribute %s",thisName(),GetString(tag)); + AtomList la; + t_any any; + switch(a->argtp) { + case a_float: + if(argc == 1 && CanbeFloat(argv[0])) { + any.ft = GetAFloat(argv[0]); + ((methfun_1)a->fun)(this,any); + } + else ok = false; + break; + case a_int: + if(argc == 1 && CanbeInt(argv[0])) { + any.it = GetAInt(argv[0]); + ((methfun_1)a->fun)(this,any); + } + else ok = false; + break; + case a_symbol: + if(argc == 1 && IsSymbol(argv[0])) { + any.st = GetSymbol(argv[0]); + ((methfun_1)a->fun)(this,any); + } + else ok = false; + break; + case a_LIST: + any.vt = &(la(argc,argv)); + ((methfun_1)a->fun)(this,any); + break; + default: + ERRINTERNAL(); } - else - post("%s - attribute %s has no get method",thisName(),GetString(tag)); + + if(!ok) + post("%s - wrong arguments for attribute %s",thisName(),GetString(a->tag)); } else - error("%s - %s: attribute not found",thisName(),GetString(tag)); + post("%s - attribute %s has no get method",thisName(),GetString(a->tag)); return true; } -bool flext_base::GetAttrib(const t_symbol *tag,int argc,const t_atom *argv) +/* +bool flext_base::GetAttrib(const t_symbol *tag) { if(argc) post("%s - %s: arguments ignored",thisName(),GetString(tag)); - attritem *a = attrhead; - for(; a && a->gtag != tag; a = a->nxt) {} +#ifdef FLEXT_DEBUG + if(strncmp(GetString(tag),"get",3)) { + post("%s - %s: tag has no 'get' prefix",thisName(),GetString(tag)); + return false; + } +#endif + + const t_symbol *mtag = MakeSymbol(GetString(a->tag)+3); + // search for attribute + attritem *a = (attritem *)attrhead->Find(mtag); + if(!a) a = (attritem *)clattrhead->Find(mtag); +} +*/ + +bool flext_base::GetAttrib(attritem *a) +{ + // main attribute tag if(a) { - if(a->gfun) { + if(a->fun) { AtomList la; t_any any; switch(a->argtp) { case a_float: { - ((methfun_1)a->gfun)(this,any); + ((methfun_1)a->fun)(this,any); la(1); SetFloat(la[0],any.ft); break; } case a_int: { - ((methfun_1)a->gfun)(this,any); + ((methfun_1)a->fun)(this,any); la(1); SetInt(la[0],any.it); break; } case a_symbol: { - ((methfun_1)a->gfun)(this,any); + ((methfun_1)a->fun)(this,any); la(1); SetSymbol(la[0],any.st); break; } case a_LIST: { any.vt = &la; - ((methfun_1)a->gfun)(this,any); + ((methfun_1)a->fun)(this,any); break; } default: @@ -186,10 +262,10 @@ bool flext_base::GetAttrib(const t_symbol *tag,int argc,const t_atom *argv) ToOutAnything(outattr,a->tag,la.Count(),la.Atoms()); } else - post("%s - attribute %s has no set method",thisName(),GetString(tag)); + post("%s - attribute %s has no set method",thisName(),GetString(a->tag)); } else - error("%s - %s: attribute not found",thisName(),GetString(tag)); + error("%s - %s: attribute not found",thisName(),GetString(a->tag)); return true; } -- cgit v1.2.1