From 74e28b058aaf629d94ad7d44a9add3062e89441d Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Sun, 22 Feb 2004 03:34:00 +0000 Subject: "" svn path=/trunk/; revision=1326 --- externals/grill/flext/source/flitem.cpp | 266 ++++++-------------------------- 1 file changed, 43 insertions(+), 223 deletions(-) (limited to 'externals/grill/flext/source/flitem.cpp') diff --git a/externals/grill/flext/source/flitem.cpp b/externals/grill/flext/source/flitem.cpp index ffd7f3f1..3dec5965 100755 --- a/externals/grill/flext/source/flitem.cpp +++ b/externals/grill/flext/source/flitem.cpp @@ -2,7 +2,7 @@ flext - C++ layer for Max/MSP and pd (pure data) externals -Copyright (c) 2001-2003 Thomas Grill (xovo@gmx.net) +Copyright (c) 2001-2004 Thomas Grill (xovo@gmx.net) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. @@ -15,243 +15,63 @@ WARRANTIES, see the file, "license.txt," in this distribution. #include "flext.h" #include - -flext_base::Item::Item(const t_symbol *t,int inl,AttrItem *a): - tag(t),inlet(inl),attr(a),nxt(NULL) -{} - -flext_base::Item::~Item() -{ - if(nxt) delete nxt; -} - - -flext_base::ItemCont::ItemCont(): - arr(new Item *[2]),cnt(0),bits(-1) -{ - arr[0] = arr[1] = NULL; -} - -flext_base::ItemCont::~ItemCont() -{ - if(Ready()) { - // if finalized, the array has several slots - int c = Size(); - for(int i = 0; i < c; ++i) - if(arr[i]) delete arr[i]; - } - else - // the array only has a head (arr[0]) and a tail (arr[1]) pointer - delete arr[0]; - - delete[] arr; -} - -void flext_base::ItemCont::Add(Item *it) +void flext_base::ItemCont::Add(Item *item,const t_symbol *tag,int inlet) { - if(Ready()) { - // retrieve array index - int ix = Hash(it->tag,it->inlet,bits); - - // add to array slot - if(arr[ix]) { - Item *a = arr[ix]; - while(a->nxt) a = a->nxt; - a->nxt = it; - } - else arr[ix] = it; - -// post("RDY inlet=%i,tag=%s,hash=%i",it->inlet,GetString(it->tag),ix); - } - else { -// post("ADD index=%i,inlet=%i,tag=%s",cnt,it->inlet,GetString(it->tag)); - - if(arr[0]) arr[1] = arr[1]->nxt = it; - else arr[0] = arr[1] = it; - ++cnt; - } + FLEXT_ASSERT(inlet >= -1); + if(!Contained(inlet)) resize(inlet+2); + ItemSet &set = GetInlet(inlet); + set[tag].push_back(item); + members++; } -bool flext_base::ItemCont::Remove(Item *it) +bool flext_base::ItemCont::Remove(Item *item,const t_symbol *tag,int inlet) { - if(Ready()) { - // retrieve array index - int ix = Hash(it->tag,it->inlet,bits); - - // remove from array slot - if(arr[ix]) { - Item *a1 = NULL,*a = arr[ix]; - while(a && a != it) a1 = a,a = a->nxt; - if(a) { // found (a == it) - if(a1) a1->nxt = it->nxt; - else arr[ix] = it->nxt; - it->nxt = NULL; - return true; - } - else - return false; - } - else - return false; - } - else { - // remove from list - if(!arr[0]) - return false; - else { - Item *a1 = NULL,*a = arr[0]; - while(a && a != it) a1 = a,a = a->nxt; - if(a) { // found (a == it) - if(a1) a1->nxt = it->nxt; - else arr[0] = it->nxt; - if(!it->nxt) arr[1] = a1; - it->nxt = NULL; - --cnt; - return true; + FLEXT_ASSERT(inlet >= -1); + if(Contained(inlet)) { + ItemSet &set = GetInlet(inlet); + ItemSet::iterator it = set.find(tag); + if(it != set.end()) { + ItemList &lst = it->second; + for(ItemList::iterator lit = lst.begin(); lit != lst.end(); ++lit) { + if(*lit == item) { + delete *lit; + lst.erase(lit); + return true; + } } - else - return false; } - } -} - -void flext_base::ItemCont::Finalize() -{ - if(!Ready()) { - bits = Int2Bits(cnt); // at least enough bits to hold all items - -// post("This=%p, Count %i, Bits %i",this,cnt,bits); - - int sz = Size(); - - // save stored item list - Item *lst = arr[0]; - - delete[] arr; - arr = new Item *[sz]; - memset(arr,0,sz*sizeof(*arr)); - - while(lst) { - Item *l = lst; - lst = lst->nxt; - l->nxt = NULL; - - Add(l); - } - -#if 0 - post("count=%i, bit=%i size=%i",Count(),bits,sz); - - if(Count()) { - static char usage[1024]; - int c = 0,i; - for(i = 0; i < sz; ++i) { - usage[i] = arr[i]?'x':'.'; - if(arr[i]) ++c; - } - usage[i] = 0; - post("USAGE %i/%i - sparse=%i%% %s",c,Count(),(int)((float)c/Count()*100.),usage); - } -#endif - } -} - -flext_base::Item *flext_base::ItemCont::Find(const t_symbol *tag,int inlet) const -{ - Item *a; - if(!Ready()) - a = arr[0]; - else if(Count()) { - int ix = Hash(tag,inlet,bits); - a = arr[ix]; -// post("FIND tag=%s inlet=%i hash=%i p=%p",GetString(tag),inlet,ix,a); - } - else - a = NULL; - - - // Search first matching entry - while(a && (a->tag != tag || a->inlet != inlet)) a = a->nxt; - return a; + } + return false; } -int flext_base::ItemCont::Hash(const t_symbol *tag,int inlet,int bits) +flext_base::ItemList *flext_base::ItemCont::FindList(const t_symbol *tag,int inlet) { - unsigned long h = ((reinterpret_cast(tag)&~7L)<<1)+inlet; - return FoldBits(h,bits); + FLEXT_ASSERT(inlet >= -1); + if(Contained(inlet)) { + ItemSet &ai = GetInlet(inlet); + ItemSet::iterator as = ai.find(tag); + if(as != ai.end()) return &as->second; + } + return NULL; } // --- class item lists (methods and attributes) ---------------- -class _itemarr -{ -public: - enum { HASHBITS=7, HASHSIZE=1< ClassMap; +typedef std::vector ClassArr; - static int Hash(flext_obj::t_classid c,int ix); - - int Hash() const { return Hash(clid,ix); } - void Add(_itemarr *a); - - flext_obj::t_classid clid; - int ix; - flext_base::ItemCont *arr; - - _itemarr *nxt; -}; - -_itemarr::_itemarr(flext_obj::t_classid c,int i): - clid(c),ix(i), - arr(new flext_base::ItemCont), - nxt(NULL) -{} - -_itemarr::~_itemarr() -{ - delete arr; - if(nxt) delete nxt; -} - -void _itemarr::Add(_itemarr *a) -{ - if(nxt) nxt->Add(a); - else nxt = a; -} - -int _itemarr::Hash(flext_obj::t_classid c,int ix) -{ - unsigned long h = (reinterpret_cast(c)&~3L)+ix; - return flext::FoldBits(h,HASHBITS); -} - -static _itemarr **_arrs = NULL; +static ClassArr classarr; flext_base::ItemCont *flext_base::GetClassArr(t_classid c,int ix) { - if(!_arrs) { - _arrs = new _itemarr *[_itemarr::HASHSIZE]; - memset(_arrs,0,_itemarr::HASHSIZE*sizeof(*_arrs)); - } - - int hash = _itemarr::Hash(c,ix); - _itemarr *a = _arrs[hash]; - _itemarr *pa = NULL; - while(a && (a->clid != c || a->ix != ix)) pa = a,a = a->nxt; - -// post("GETARR classid=%p ix=%i -> hash=%i,arr=%p",c,ix,hash,a?a->arr:NULL); - - if(!a) { - a = new _itemarr(c,ix); - if(pa) - // previous entry... extend - a->nxt = pa->nxt,pa->nxt = a; - else - // new singular entry - _arrs[hash] = a; - } - - return a->arr; + if(ix >= (int)classarr.size()) classarr.resize(ix+1); + ClassMap &map = classarr[ix]; + ClassMap::iterator it = map.find(c); + if(it == map.end()) { + ItemCont *cont = new ItemCont; + map[c] = cont; + return cont; + } + else + return it->second; } -- cgit v1.2.1