[PD-cvs] externals/grill/flext/source flattr.cpp,1.19,1.20 flattr_ed.cpp,1.18,1.19 flbind.cpp,1.11,1.12 flclass.h,1.40,1.41 flext.cpp,1.26,1.27 flitem.cpp,1.9,1.10 fllib.cpp,1.20,1.21 flmeth.cpp,1.7,1.8 flmsg.cpp,1.9,1.10 flprefix.h,1.24,1.25 flsupport.cpp,1.30,1.31 flsupport.h,1.63,1.64

xovo at users.sourceforge.net xovo at users.sourceforge.net
Sun Feb 22 04:34:05 CET 2004


Update of /cvsroot/pure-data/externals/grill/flext/source
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14647/source

Modified Files:
	flattr.cpp flattr_ed.cpp flbind.cpp flclass.h flext.cpp 
	flitem.cpp fllib.cpp flmeth.cpp flmsg.cpp flprefix.h 
	flsupport.cpp flsupport.h 
Log Message:
 ""

Index: flattr.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/flext/source/flattr.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -C2 -d -r1.19 -r1.20
*** flattr.cpp	3 Sep 2003 02:32:49 -0000	1.19
--- flattr.cpp	22 Feb 2004 03:33:59 -0000	1.20
***************
*** 26,31 ****
  #endif
  
! flext_base::AttrItem::AttrItem(const t_symbol *t,metharg tp,methfun f,int fl):
! 	Item(t,0,NULL),index(0),
  	flags(fl|afl_shown),
  	argtp(tp),fun(f),
--- 26,31 ----
  #endif
  
! flext_base::AttrItem::AttrItem(metharg tp,methfun f,int fl):
! 	Item(NULL),index(0),
  	flags(fl|afl_shown),
  	argtp(tp),fun(f),
***************
*** 47,62 ****
  	if(sfun) // if commented out, there will be a warning at run-time (more user-friendly)
  	{
! 		a = new AttrItem(asym,tp,sfun,AttrItem::afl_set);
! 
! 		// set index of item to the next higher value
! 		AttrItem *last = (AttrItem *)aa->Last();
! 		if(last) a->index = last->index+1;
! 
! 		aa->Add(a); 
  
  		// bind attribute to a method
! 		MethItem *mi = new MethItem(0,asym,a);
  		mi->SetArgs(sfun,1,new metharg(tp));
! 		ma->Add(mi);
  	}
  	else
--- 47,58 ----
  	if(sfun) // if commented out, there will be a warning at run-time (more user-friendly)
  	{
! 		a = new AttrItem(tp,sfun,AttrItem::afl_set);
!         a->index = aa->Members();
! 		aa->Add(a,asym); 
  
  		// bind attribute to a method
! 		MethItem *mi = new MethItem(a);
  		mi->SetArgs(sfun,1,new metharg(tp));
! 		ma->Add(mi,asym);
  	}
  	else
***************
*** 65,75 ****
  	if(gfun) // if commented out, there will be a warning at run-time (more user-friendly)
  	{
! 		b = new AttrItem(asym,tp,gfun,AttrItem::afl_get);
! 
! 		// set index of item to the next higher value
! 		AttrItem *last = (AttrItem *)aa->Last();
! 		if(last) b->index = last->index+1;
! 
! 		aa->Add(b); 
  
  		static char tmp[256] = "get";
--- 61,67 ----
  	if(gfun) // if commented out, there will be a warning at run-time (more user-friendly)
  	{
! 		b = new AttrItem(tp,gfun,AttrItem::afl_get);
!         b->index = aa->Members();
! 		aa->Add(b,asym); 
  
  		static char tmp[256] = "get";
***************
*** 77,83 ****
  
  		// bind attribute to a method
! 		MethItem *mi = new MethItem(0,MakeSymbol(tmp),b);
  		mi->SetArgs(gfun,0,NULL);
! 		ma->Add(mi);
  	}
  	else
--- 69,75 ----
  
  		// bind attribute to a method
! 		MethItem *mi = new MethItem(b);
  		mi->SetArgs(gfun,0,NULL);
! 		ma->Add(mi,MakeSymbol(tmp));
  	}
  	else
***************
*** 103,138 ****
  }
  
- /*
- //! Sorting function for pure symbol atom lists (used with qsort below)
- static int sortcmp(const void *a, const void *b) 
- { 
- 	return strcmp(flext::GetString(*(t_atom *)a),flext::GetString(*(t_atom *)b)); 
- }
- */
- 
- struct attrless : public std::binary_function<flext_base::AttrItem *,flext_base::AttrItem *, bool> 
- {
- 	bool operator()(const flext_base::AttrItem *l,const flext_base::AttrItem *r) const { 
- 		return l->index != r->index?l->index < r->index:strcmp(flext::GetString(l->tag),flext::GetString(r->tag)) < 0; 
- 	}
- };
- 
  void flext_base::ListAttrib(AtomList &la) const
  {
! 	typedef std::set<AttrItem *,attrless> AttrList;
  	AttrList list[2];
  
  	int i;
  	for(i = 0; i <= 1; ++i) {
! 		ItemCont *a = i?attrhead:clattrhead;
! 		if(a) {
! 			for(int ai = 0; ai < a->Size(); ++ai) {
! 				for(Item *l = a->GetItem(ai); l; l = l->nxt) {
! 					AttrItem *aa = (AttrItem *)l;
! 
! 					// only list once!
! 					if(!aa->BothExist() || aa->IsGet()) 
! 						list[i].insert(aa);
! 				}
  			}
  		}
--- 95,114 ----
  }
  
  void flext_base::ListAttrib(AtomList &la) const
  {
! 	typedef std::map<int,const t_symbol *> AttrList;
  	AttrList list[2];
  
  	int i;
  	for(i = 0; i <= 1; ++i) {
!         ItemCont *a = i?attrhead:clattrhead;
! 		if(a && a->Contained(0)) {
!             ItemSet &ai = a->GetInlet();
!             for(ItemSet::iterator as = ai.begin(); as != ai.end(); ++as) {
!                 for(ItemList::iterator al = as->second.begin(); al != as->second.end(); ++al) {
! 					AttrItem *aa = (AttrItem *)*al;
! 					list[i][aa->index] = as->first;
!                     break;
!                 }
  			}
  		}
***************
*** 144,148 ****
  	for(i = 0; i <= 1; ++i)
  		for(it = list[i].begin(); it != list[i].end(); ++it) 
! 			SetSymbol(la[ix++],(*it)->tag);
  }
  
--- 120,124 ----
  	for(i = 0; i <= 1; ++i)
  		for(it = list[i].begin(); it != list[i].end(); ++it) 
! 			SetSymbol(la[ix++],it->second);
  }
  
***************
*** 174,178 ****
  
  			// pass value to object
! 			SetAttrib(attr,a.GetInitValue());
  		}
  	}
--- 150,154 ----
  
  			// pass value to object
! 			SetAttrib(tag,attr,a.GetInitValue());
  		}
  	}
***************
*** 195,208 ****
  {
      // first search within object scope
! 	AttrItem *a = (AttrItem *)attrhead->Find(tag);
! 	while(a && (a->tag != tag || a->inlet != 0 || (get?a->IsSet():a->IsGet()))) a = (AttrItem *)a->nxt;
  
      // then (if nothing found) search within class scope
  	if(!a) {
! 		a = (AttrItem *)clattrhead->Find(tag);	
! 		while(a && (a->tag != tag || a->inlet != 0 || (get?a->IsSet():a->IsGet()))) a = (AttrItem *)a->nxt;
  	}
  
! 	if(!a && msg) {
  		// print a message
  		error("%s - %s: attribute not found",thisName(),GetString(tag));
--- 171,197 ----
  {
      // first search within object scope
! 	AttrItem *a = NULL;
!     {
!         ItemList *lst = attrhead->FindList(tag);
!         if(lst) {
!             for(ItemList::iterator it = lst->begin(); it != lst->end(); ++it) {
!                 AttrItem *b = (AttrItem *)*it;
!                 if(get?b->IsGet():b->IsSet()) { a = b; break; }
!             }
!         }
!     }
  
      // then (if nothing found) search within class scope
  	if(!a) {
!         ItemList *lst = clattrhead->FindList(tag);
!         if(lst) {
!             for(ItemList::iterator it = lst->begin(); it != lst->end(); ++it) {
!                 AttrItem *b = (AttrItem *)*it;
!                 if(get?b->IsGet():b->IsSet()) { a = b; break; }
!             }
!         }
  	}
  
!     if(!a && msg) {
  		// print a message
  		error("%s - %s: attribute not found",thisName(),GetString(tag));
***************
*** 216,225 ****
  	AttrItem *a = FindAttrib(tag,false,true);
  	if(a) 
! 		return SetAttrib(a,argc,argv);
  	else
  		return true;
  }
  
! bool flext_base::SetAttrib(AttrItem *a,int argc,const t_atom *argv)
  {
  	if(a->fun) {
--- 205,214 ----
  	AttrItem *a = FindAttrib(tag,false,true);
  	if(a) 
! 		return SetAttrib(tag,a,argc,argv);
  	else
  		return true;
  }
  
! bool flext_base::SetAttrib(const t_symbol *tag,AttrItem *a,int argc,const t_atom *argv)
  {
  	if(a->fun) {
***************
*** 273,285 ****
  
  		if(!ok)
! 			post("%s - wrong arguments for attribute %s",thisName(),GetString(a->tag));
  	}
  	else
! 		post("%s - attribute %s has no get method",thisName(),GetString(a->tag));
  	return true;
  }
  
  
! bool flext_base::GetAttrib(AttrItem *a,AtomList &la) const
  {
  	bool ok = true;
--- 262,274 ----
  
  		if(!ok)
! 			post("%s - wrong arguments for attribute %s",thisName(),GetString(tag));
  	}
  	else
! 		post("%s - attribute %s has no get method",thisName(),GetString(tag));
  	return true;
  }
  
  
! bool flext_base::GetAttrib(const t_symbol *tag,AttrItem *a,AtomList &la) const
  {
  	bool ok = true;
***************
*** 324,333 ****
  		}
  		else {
! 			post("%s - attribute %s has no get method",thisName(),GetString(a->tag));
  			ok = false;
  		}
  	}
  	else {
! 		error("%s - %s: attribute not found",thisName(),GetString(a->tag));
  		ok = false;
  	}
--- 313,322 ----
  		}
  		else {
! 			post("%s - attribute %s has no get method",thisName(),GetString(tag));
  			ok = false;
  		}
  	}
  	else {
! 		error("%s - %s: attribute not found",thisName(),GetString(tag));
  		ok = false;
  	}
***************
*** 338,349 ****
  {
  	AttrItem *attr = FindAttrib(s,true);
! 	return attr && GetAttrib(attr,a);
  }
  
! bool flext_base::DumpAttrib(AttrItem *a) const
  {
  	AtomList la;
! 	bool ret = GetAttrib(a,la);
! 	if(ret) ToOutAnything(GetOutAttr(),a->tag,la.Count(),la.Atoms());
  	return ret;
  }
--- 327,338 ----
  {
  	AttrItem *attr = FindAttrib(s,true);
! 	return attr && GetAttrib(s,attr,a);
  }
  
! bool flext_base::DumpAttrib(const t_symbol *tag,AttrItem *a) const
  {
  	AtomList la;
! 	bool ret = GetAttrib(tag,a,la);
! 	if(ret) ToOutAnything(GetOutAttr(),tag,la.Count(),la.Atoms());
  	return ret;
  }
***************
*** 352,359 ****
  {
  	AttrItem *item = FindAttrib(attr,true);
! 	return item && DumpAttrib(item);
  }
  
! bool flext_base::BangAttrib(AttrItem *item)
  {
  	AtomList val;
--- 341,348 ----
  {
  	AttrItem *item = FindAttrib(attr,true);
! 	return item && DumpAttrib(attr,item);
  }
  
! bool flext_base::BangAttrib(const t_symbol *attr,AttrItem *item)
  {
  	AtomList val;
***************
*** 363,367 ****
  	if(item) {
  		item2 = item->Counterpart();
! 		return item2 && GetAttrib(item,val) && SetAttrib(item2,val);
  	}
  	else
--- 352,356 ----
  	if(item) {
  		item2 = item->Counterpart();
! 		return item2 && GetAttrib(attr,item,val) && SetAttrib(attr,item2,val);
  	}
  	else
***************
*** 372,395 ****
  {
  	AttrItem *item = FindAttrib(attr,true);
! 	return item && BangAttrib(item);
  }
  
  bool flext_base::BangAttribAll()
  {
! 	int i,cnt = clattrhead->Ready()?clattrhead->Size():2;
! 	for(i = 0; i < cnt; ++i) {
! 		AttrItem *a = (AttrItem *)clattrhead->GetItem(i);
! 		for(; a; a = (AttrItem *)a->nxt) {
! 			if(a->IsGet() && a->BothExist()) 
! 				BangAttrib(a);
! 		}
! 	}
! 
! 	cnt = attrhead->Ready()?attrhead->Size():2;
! 	for(i = 0; i < cnt; ++i) {
! 		AttrItem *a = (AttrItem *)attrhead->GetItem(i);
! 		for(; a; a = (AttrItem *)a->nxt) {
! 			if(a->IsGet() && a->BothExist()) 
! 				BangAttrib(a);
  		}
  	}
--- 361,379 ----
  {
  	AttrItem *item = FindAttrib(attr,true);
! 	return item && BangAttrib(attr,item);
  }
  
  bool flext_base::BangAttribAll()
  {
! 	for(int i = 0; i <= 1; ++i) {
!         ItemCont *a = i?attrhead:clattrhead;
! 		if(a) {
!             ItemSet &ai = a->GetInlet(); // \todo need to check for presence of inlet 0?
!             for(ItemSet::iterator as = ai.begin(); as != ai.end(); ++as) {
!                 for(ItemList::iterator al = as->second.begin(); al != as->second.end(); ++al) {
! 					AttrItem *a = (AttrItem *)*al;
! 	        		if(a->IsGet() && a->BothExist()) BangAttrib(as->first,a);
!                 }
! 			}
  		}
  	}

Index: flattr_ed.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/flext/source/flattr_ed.cpp,v
retrieving revision 1.18
retrieving revision 1.19
diff -C2 -d -r1.18 -r1.19
*** flattr_ed.cpp	8 Feb 2004 03:36:25 -0000	1.18
--- flattr_ed.cpp	22 Feb 2004 03:33:59 -0000	1.19
***************
*** 467,471 ****
  		if(gattr) { // gettable attribute is present
  			// Retrieve attribute value
! 			th->GetAttrib(gattr,lv);
  
  			PrintList(lv.Count(),lv.Atoms(),b,sizeof(buf)+buf-b); b += strlen(b);
--- 467,471 ----
  		if(gattr) { // gettable attribute is present
  			// Retrieve attribute value
! 			th->GetAttrib(sym,gattr,lv);
  
  			PrintList(lv.Count(),lv.Atoms(),b,sizeof(buf)+buf-b); b += strlen(b);
***************
*** 600,604 ****
  				// attribute must be gettable (so that the data can be retrieved) and puttable (so that the data can be inited)
  				if(attr && attr->BothExist()) {
! 					th->GetAttrib(attr,lv); 
  					lref = &lv;
  				}
--- 600,604 ----
  				// attribute must be gettable (so that the data can be retrieved) and puttable (so that the data can be inited)
  				if(attr && attr->BothExist()) {
! 					th->GetAttrib(sym,attr,lv); 
  					lref = &lv;
  				}
***************
*** 663,667 ****
  		AttrItem *attr = th->FindAttrib(aname,false);
  		if(attr) {
! 			bool ret = th->SetAttrib(attr,ccnt,argv+coffs);
  			FLEXT_ASSERT(ret);
  
--- 663,667 ----
  		AttrItem *attr = th->FindAttrib(aname,false);
  		if(attr) {
! 			bool ret = th->SetAttrib(aname,attr,ccnt,argv+coffs);
  			FLEXT_ASSERT(ret);
  

Index: flbind.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/flext/source/flbind.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** flbind.cpp	20 Oct 2003 02:32:51 -0000	1.11
--- flbind.cpp	22 Feb 2004 03:34:00 -0000	1.12
***************
*** 57,66 ****
  
  
! flext_base::BindItem::BindItem(int in,const t_symbol *sym,bool (*f)(flext_base *,t_symbol *s,int,t_atom *,void *data),pxbnd_object *p):
! 	Item(sym,0,NULL),fun(f),px(p)
  {}
  
  flext_base::BindItem::~BindItem()
  {
      if(px) {
  #if FLEXT_SYS == FLEXT_SYS_PD
--- 57,71 ----
  
  
! flext_base::BindItem::BindItem(bool (*f)(flext_base *,t_symbol *s,int,t_atom *,void *data),pxbnd_object *p):
! 	Item(NULL),fun(f),px(p)
  {}
  
  flext_base::BindItem::~BindItem()
  {
+     if(px) object_free(&px->obj);
+ }
+ 
+ void flext_base::BindItem::Unbind(const t_symbol *tag)
+ {
      if(px) {
  #if FLEXT_SYS == FLEXT_SYS_PD
***************
*** 74,78 ****
  #           pragma warning("Not implemented")
  #endif
-         object_free(&px->obj);
      }
  }
--- 79,82 ----
***************
*** 96,113 ****
      else {
          // Search for symbol
!         flext_base::BindItem *item = (flext_base::BindItem *)bindhead->Find(sym,0);
  
!         // go through all items with matching tag
!         for(; item && item->tag == sym; item = (flext_base::BindItem *)item->nxt) 
!             if(item->fun == fun) {
!                 // function already registered -> bail out!
!                 post("%s - Symbol already bound with this method",thisName());
!                 return false;
              }
-     
-     	if(bindhead->Count() > 20) {
-   			// Hash it!
-   			bindhead->Finalize();
-     	}
      }
  
--- 100,116 ----
      else {
          // Search for symbol
!         ItemList *lst = bindhead->FindList(sym);
  
!         if(lst)
!             for(ItemList::iterator it = lst->begin(); it != lst->end(); ++it) {
!                 BindItem *item = (BindItem *)*it;
! 
!                 // go through all items with matching tag
!                 if(item->fun == fun) {
!                     // function already registered -> bail out!
!                     post("%s - Symbol already bound with this method",thisName());
!                     return false;
!                 }
              }
      }
  
***************
*** 123,128 ****
  
      if(px) {
! 	    BindItem *mi = new BindItem(0,sym,fun,px);
! 	    bindhead->Add(mi);
  
          px->init(this,mi,data);
--- 126,131 ----
  
      if(px) {
! 	    BindItem *mi = new BindItem(fun,px);
! 	    bindhead->Add(mi,sym);
  
          px->init(this,mi,data);
***************
*** 150,178 ****
      bool ok = false;
      
!     if(bindhead) {
!         BindItem *it = NULL;
!         if(sym) {
!             it = (BindItem *)bindhead->Find(sym,0);
!             while(it) {
!                 if(it->tag == sym && (!fun || it->fun == fun)) break;
!             }
          }
!         else {
              // any tag
  
!             int sz = bindhead->Count();
!             if(!sz) sz = 1;
! 
!             for(int i = 0; i < sz; ++i) {
!                 for(it = (BindItem *)bindhead->GetItem(i); it; it = (BindItem *)it->nxt) {
!                     if(!fun || it->fun == fun) break;
!                 }
!                 if(it) break;
              }
          }
          if(it) {
              if(data) *data = it->px->data;
!             ok = bindhead->Remove(it);
!             if(ok) delete it;
          }
      }
--- 153,183 ----
      bool ok = false;
      
!     if(bindhead && bindhead->Contained(0)) {
!         ItemSet &set = bindhead->GetInlet();
!         ItemSet::iterator it1,it2;
!         if(sym) { 
!             // specific tag
!             it1 = it2 = set.find(sym); it2++; 
          }
!         else { 
              // any tag
+             it1 = set.begin(),it2 = set.end(); 
+         }
  
!         BindItem *it = NULL;
!         for(ItemSet::iterator si = it1; si != it2 && !it; ++si) {
!             for(ItemList::iterator i = si->second.begin(); i != si->second.end(); ++i) {
!                 BindItem *item = (BindItem *)*i;
!                 if(!fun || item->fun == fun) { it = item; break; }
              }
          }
+ 
          if(it) {
              if(data) *data = it->px->data;
!             ok = bindhead->Remove(it,sym);
!             if(ok) {
!                 it->Unbind(sym);
!                 delete it;
!             }
          }
      }
***************
*** 184,194 ****
      if(bindhead) {
          // Search for symbol
!         flext_base::BindItem *item = (flext_base::BindItem *)bindhead->Find(sym,0);
  
!         // go through all items with matching tag
!         for(; item && item->tag == sym; item = (flext_base::BindItem *)item->nxt) 
!             if(item->fun == fun) {
!                 data = item->px->data;
!                 return true;
              }
      }
--- 189,203 ----
      if(bindhead) {
          // Search for symbol
!         ItemList *lst = bindhead->FindList(sym);
  
!         if(lst)
!             for(ItemList::iterator it = lst->begin(); it != lst->end(); ++it) {
!                 BindItem *item = (BindItem *)*it;
! 
!                 // go through all items with matching tag
!                 if(item->fun == fun) {
!                     data = item->px->data;
!                     return true;
!                 }
              }
      }
***************
*** 198,216 ****
  bool flext_base::UnbindAll()
  {
! //	bool memleak = false;
! 
!     int sz = bindhead->Count();
!     if(!sz) sz = 1;
! 
!     for(int i = 0; i < sz; ++i) {
!         for(BindItem *it = (BindItem *)bindhead->GetItem(i); it; it = (BindItem *)it->nxt) {
! //			if(it->px->data) memleak = true;
!             if(bindhead->Remove(it)) delete it;
          }
      }
- /*
- 	if(memleak)
- 		post("%s - Memory was not deallocated while unbinding methods",thisName());
- */
  	return true;
  }
--- 207,224 ----
  bool flext_base::UnbindAll()
  {
!     if(bindhead && bindhead->Contained(0)) {
!         ItemSet &set = bindhead->GetInlet();
!         for(ItemSet::iterator si = set.begin(); si != set.end(); ++si) {
!             ItemList &lst = si->second;
!             while(!lst.empty()) {
!                 // eventual allocated data in item is not freed!
!                 BindItem *it = (BindItem *)lst.front();
!                 it->Unbind(si->first);
!                 delete it;
!                 lst.pop_front();
!             }
          }
+         set.clear();
      }
  	return true;
  }

Index: flclass.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/flext/source/flclass.h,v
retrieving revision 1.40
retrieving revision 1.41
diff -C2 -d -r1.40 -r1.41
*** flclass.h	10 Nov 2003 03:32:53 -0000	1.40
--- flclass.h	22 Feb 2004 03:34:00 -0000	1.41
***************
*** 3,7 ****
  flext - C++ layer for Max/MSP and pd (pure data) externals
  
! Copyright (c) 2001-2003 Thomas Grill (xovo at gmx.net)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
--- 3,7 ----
  flext - C++ layer for Max/MSP and pd (pure data) externals
  
! Copyright (c) 2001-2004 Thomas Grill (xovo at gmx.net)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
***************
*** 24,27 ****
--- 24,28 ----
  #include <set>
  #include <list>
+ #include <vector>
  
  #ifdef _MSC_VER
***************
*** 601,665 ****
  	class AttrItem;
  
!     class Item:
!         public flext_root
      {
  	public:
! 		Item(const t_symbol *t,int inl,AttrItem *a);
! 		virtual ~Item();
  		
  		bool IsAttr() const { return attr != NULL; }
  
- 		const t_symbol *tag;
- 		int inlet;
  		AttrItem *attr;
- 		Item *nxt;
  	};
  
      //! This class holds hashed item entries
      class ItemCont:
!         public flext_root
      {
  	public:
! 		ItemCont();
! 		~ItemCont();
  
          //! Add an entry
! 		void Add(Item *it);
          //! Remove an entry
! 		bool Remove(Item *it);
!         //! Find an entry in the Item array
! 		Item *Find(const t_symbol *tag,int inlet = 0) const;
! 
!         //! Create hash table out of the preliminary linked lists
! 		void Finalize();
  
! 		//! Get first element
! 		Item *First() { return !Ready()?arr[0]:NULL; }
! 		//! Get last element
! 		Item *Last() { return !Ready()?arr[1]:NULL; }
! 		
!         //! Query whether the array has been finalized
! 		bool Ready() const { return bits >= 0; }
!         //! Number of items in the array
! 		int Count() const { return cnt; }
!         //! Number of array slots (0 if not finalized)
! 		int Size() const { return bits?1<<bits:0; }
  
!         //! Get an array slot
! 		Item *GetItem(int ix) { return arr[ix]; }
! 	
! 	protected:		
!         //! Calculate a hash value
! 		static int Hash(const t_symbol *,int inlet,int bits);
! 	
! 		Item **arr;
! 		int cnt,bits;
  	};
  
! 	//! \brief This represents an item of the method list
  	class MethItem:
! 		public Item { 
  	public:
! 		MethItem(int inlet,const t_symbol *tg,AttrItem *conn = NULL);
  		virtual ~MethItem();
  		
--- 602,655 ----
  	class AttrItem;
  
!     class Item
      {
  	public:
!         Item(AttrItem *a): attr(a) {}
!         virtual ~Item() {}
  		
  		bool IsAttr() const { return attr != NULL; }
  
  		AttrItem *attr;
  	};
  
+     typedef std::list<Item *> ItemList;
+ 
+     typedef std::map<const t_symbol *,ItemList> ItemSet;
+     typedef std::vector<ItemSet> ItemVec;
+ 
      //! This class holds hashed item entries
      class ItemCont:
!         private ItemVec
      {
  	public:
!         typedef ItemVec::iterator iterator;
!         typedef ItemVec::const_iterator const_iterator;
! 
!         ItemCont(): members(0) {}
! 
!         bool Contained(int i) const { return i+1 < (int)size(); }
  
          //! Add an entry
! 		void Add(Item *it,const t_symbol *tag,int inlet = 0);
          //! Remove an entry
! 		bool Remove(Item *it,const t_symbol *tag,int inlet = 0);
!         //! Find an entry list in the Item array
! 		ItemList *FindList(const t_symbol *tag,int inlet = 0);
!         //! Get list for an inlet
!         ItemSet &GetInlet(int inlet = 0) { return (*this)[inlet+1]; }
  
!         //! Get counter for total members (for index of new item)
!         int Members() const { return members; }
  
!     protected:
!         int members;
  	};
  
!     //! \brief This represents an item of the method list
  	class MethItem:
! 		public Item 
!     { 
  	public:
! 		MethItem(AttrItem *conn = NULL);
  		virtual ~MethItem();
  		
***************
*** 674,680 ****
  	//! \brief This represents an item of the attribute list
  	class AttrItem:
! 		public Item { 
  	public:
! 		AttrItem(const t_symbol *tag,metharg tp,methfun fun,int flags);
  		virtual ~AttrItem();
  
--- 664,671 ----
  	//! \brief This represents an item of the attribute list
  	class AttrItem:
! 		public Item 
!     { 
  	public:
! 		AttrItem(metharg tp,methfun fun,int flags);
  		virtual ~AttrItem();
  
***************
*** 738,748 ****
  
  	//! \brief This represents an item of the symbol-bound method list
! 	class BindItem
! 		:public Item 
  	{ 
  	public:
! 		BindItem(int inlet,const t_symbol *sym,bool (*f)(flext_base *,t_symbol *s,int,t_atom *,void *),pxbnd_object *px);
  		virtual ~BindItem();
! 		
  		bool (*fun)(flext_base *,t_symbol *s,int,t_atom *,void *);
          pxbnd_object *px;
--- 729,740 ----
  
  	//! \brief This represents an item of the symbol-bound method list
!     class BindItem:
! 		public Item 
  	{ 
  	public:
! 		BindItem(bool (*f)(flext_base *,t_symbol *s,int,t_atom *,void *),pxbnd_object *px);
  		virtual ~BindItem();
! 		void Unbind(const t_symbol *s);
! 
  		bool (*fun)(flext_base *,t_symbol *s,int,t_atom *,void *);
          pxbnd_object *px;
***************
*** 805,811 ****
  	bool CallMeth(const MethItem &m,int argc,const t_atom *argv);
  	bool FindMeth(int inlet,const t_symbol *s,int argc,const t_atom *argv);
! 	bool TryMethTag(const MethItem *m,int inlet,const t_symbol *t,int argc,const t_atom *argv);
! 	bool TryMethSym(const MethItem *m,int inlet,const t_symbol *t,const t_symbol *s);
! 	bool TryMethAny(const MethItem *m,int inlet,const t_symbol *t,const t_symbol *s,int argc,const t_atom *argv);
  
  	mutable ItemCont *attrhead,*clattrhead;
--- 797,803 ----
  	bool CallMeth(const MethItem &m,int argc,const t_atom *argv);
  	bool FindMeth(int inlet,const t_symbol *s,int argc,const t_atom *argv);
! 	bool TryMethTag(ItemList &lst,const t_symbol *tag,int argc,const t_atom *argv);
! 	bool TryMethSym(ItemList &lst,const t_symbol *s);
! 	bool TryMethAny(ItemList &lst,const t_symbol *s,int argc,const t_atom *argv);
  
  	mutable ItemCont *attrhead,*clattrhead;
***************
*** 819,829 ****
  	bool ListMethods(int inlet = 0) const;
  	bool ListAttrib() const;
! 	bool DumpAttrib(AttrItem *a) const;
! 	bool GetAttrib(AttrItem *a,AtomList &l) const;
  	bool SetAttrib(const t_symbol *s,int argc,const t_atom *argv);
! 	bool SetAttrib(AttrItem *a,int argc,const t_atom *argv);
! 	bool SetAttrib(AttrItem *a,const AtomList &l) { return SetAttrib(a,l.Count(),l.Atoms()); }
  	// get and set the attribute
! 	bool BangAttrib(AttrItem *a);
  	// show/hide the attribute
  	bool ShowAttrib(AttrItem *a,bool show) const;
--- 811,821 ----
  	bool ListMethods(int inlet = 0) const;
  	bool ListAttrib() const;
! 	bool DumpAttrib(const t_symbol *tag,AttrItem *a) const;
! 	bool GetAttrib(const t_symbol *tag,AttrItem *a,AtomList &l) const;
  	bool SetAttrib(const t_symbol *s,int argc,const t_atom *argv);
! 	bool SetAttrib(const t_symbol *tag,AttrItem *a,int argc,const t_atom *argv);
! 	bool SetAttrib(const t_symbol *tag,AttrItem *a,const AtomList &l) { return SetAttrib(tag,a,l.Count(),l.Atoms()); }
  	// get and set the attribute
! 	bool BangAttrib(const t_symbol *tag,AttrItem *a);
  	// show/hide the attribute
  	bool ShowAttrib(AttrItem *a,bool show) const;

Index: flext.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/flext/source/flext.cpp,v
retrieving revision 1.26
retrieving revision 1.27
diff -C2 -d -r1.26 -r1.27
*** flext.cpp	25 Jul 2003 02:32:45 -0000	1.26
--- flext.cpp	22 Feb 2004 03:34:00 -0000	1.27
***************
*** 123,138 ****
  
  	if(ok) {
! 		// initialize method lists
! 		if(methhead) methhead->Finalize();
! 		if(clmethhead) clmethhead->Finalize();
! 		
! 		if(procattr) {
! 			// initialize attribute lists
! 			if(attrhead) attrhead->Finalize();
! 			if(clattrhead) clattrhead->Finalize();
! 
  			// initialize creation attributes
! 			if(m_holdaargc && m_holdaargv)
! 				ok = InitAttrib(m_holdaargc,m_holdaargv);
  		}
  	}
--- 123,129 ----
  
  	if(ok) {
! 		if(procattr && m_holdaargc && m_holdaargv) {
  			// initialize creation attributes
! 			ok = InitAttrib(m_holdaargc,m_holdaargv);
  		}
  	}

Index: flitem.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/flext/source/flitem.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -d -r1.9 -r1.10
*** flitem.cpp	29 Jul 2003 02:32:56 -0000	1.9
--- flitem.cpp	22 Feb 2004 03:34:00 -0000	1.10
***************
*** 3,7 ****
  flext - C++ layer for Max/MSP and pd (pure data) externals
  
! Copyright (c) 2001-2003 Thomas Grill (xovo at gmx.net)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
--- 3,7 ----
  flext - C++ layer for Max/MSP and pd (pure data) externals
  
! Copyright (c) 2001-2004 Thomas Grill (xovo at gmx.net)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
***************
*** 16,257 ****
  #include <string.h>
  
! 
! 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)
  {
! 	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;
! 	}
  }
  
! bool flext_base::ItemCont::Remove(Item *it)
  {
! 	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;
              }
-             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;
  }
  
! int flext_base::ItemCont::Hash(const t_symbol *tag,int inlet,int bits)
  {
! 	unsigned long h = ((reinterpret_cast<unsigned long>(tag)&~7L)<<1)+inlet;
! 	return FoldBits(h,bits);
  }
  
  // --- class item lists (methods and attributes) ----------------
  
! class _itemarr 
! {
! public:
! 	enum { HASHBITS=7, HASHSIZE=1<<HASHBITS };
! 
! 	_itemarr(flext_obj::t_classid c,int i);
! 	~_itemarr();
! 
! 	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<unsigned long>(c)&~3L)+ix;
! 	return flext::FoldBits(h,HASHBITS);
! }
  
! static _itemarr **_arrs = NULL;
  
  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;
  }
--- 16,77 ----
  #include <string.h>
  
! void flext_base::ItemCont::Add(Item *item,const t_symbol *tag,int inlet)
  {
!     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 *item,const t_symbol *tag,int inlet)
  {
!     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;
!                 }
              }
          }
!     }
!     return false;
  }
  
! flext_base::ItemList *flext_base::ItemCont::FindList(const t_symbol *tag,int inlet)
  {
!     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) ----------------
  
! typedef std::map<flext_base::t_classid,flext_base::ItemCont *> ClassMap;
! typedef std::vector<ClassMap> ClassArr;
  
! static ClassArr classarr;
  
  flext_base::ItemCont *flext_base::GetClassArr(t_classid c,int ix) 
  {
!     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;
  }

Index: fllib.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/flext/source/fllib.cpp,v
retrieving revision 1.20
retrieving revision 1.21
diff -C2 -d -r1.20 -r1.21
*** fllib.cpp	24 Sep 2003 02:34:55 -0000	1.20
--- fllib.cpp	22 Feb 2004 03:34:00 -0000	1.21
***************
*** 3,7 ****
  flext - C++ layer for Max/MSP and pd (pure data) externals
  
! Copyright (c) 2001-2003 Thomas Grill (xovo at gmx.net)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
--- 3,7 ----
  flext - C++ layer for Max/MSP and pd (pure data) externals
  
! Copyright (c) 2001-2004 Thomas Grill (xovo at gmx.net)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
***************
*** 126,191 ****
  {}
  	
! // this class stands for one registered object name
! // it holds a pointer to the respective object
! // it will never be destroyed
! class libname:
!     public flext_root
! {
! public:
! 	const t_symbol *name;
! 	libclass *obj;
! 
! 	static void add(libname *n);
! 	static libname *Find(const t_symbol *s,libclass *o = NULL);
! 	
! protected:
! 	libname(const t_symbol *n,libclass *o): name(n),obj(o),nxt(NULL) {}	
! 
! 	static int Hash(const t_symbol *s);
! 	int Hash() const { return Hash(name); }
! 
! 	enum { HASHBITS=7, HASHSIZE=1<<HASHBITS };
! 
! 	libname *nxt;
! 	void Add(libname *n);
! 
! 	static libname **root;
! };
! 
! void libname::Add(libname *n) { if(nxt) nxt->Add(n); else nxt = n; }
! 
! int libname::Hash(const t_symbol *s) 
! {
! 	return flext::FoldBits(reinterpret_cast<unsigned long>(s),HASHBITS);
! }
! 
! libname *libname::Find(const t_symbol *s,libclass *o) 
  {
! 	if(!root) {
! 		root = new libname *[HASHSIZE];
! 		memset(root,0,HASHSIZE*sizeof(*root));
! 	}
! 
! 	int hash = Hash(s);
! 	libname *a = root[hash];
! 	libname *pa = NULL;
! 	while(a && a->name != s) pa = a,a = a->nxt;
  
! 	if(!a && o) {
! 		a = new libname(s,o);
! 		if(pa) 
! 			// previous entry... extend
! 			a->nxt = pa->nxt,pa->nxt = a;
! 		else 
! 			// new singular entry
! 			root[hash] = a;
! 	}
  
! 	return a;
  }
  
- libname **libname::root = NULL;
- 
- 
  
  // for Max/MSP, the library is represented by a special object (class) registered at startup
--- 126,145 ----
  {}
  	
! //! Store or retrieve registered classes
! static libclass *FindName(const t_symbol *s,libclass *o = NULL) 
  {
!     typedef std::map<const t_symbol *,libclass *> LibMap;
  
!     static LibMap libnames;
  
!     LibMap::iterator it = libnames.find(s);
!     if(it == libnames.end()) {
!         if(o) libnames[s] = o;
!         return o;
!     }
!     else
!         return it->second;
  }
  
  
  // for Max/MSP, the library is represented by a special object (class) registered at startup
***************
*** 195,199 ****
  static const t_symbol *lib_name = NULL;
  
! flext_obj::t_classid flext_obj::thisClassId() const { return libname::Find(thisNameSym())->obj; }
  t_class *flext_obj::getClass(t_classid id) { return reinterpret_cast<libclass *>(id)->clss; }
  #endif
--- 149,157 ----
  static const t_symbol *lib_name = NULL;
  
! flext_obj::t_classid flext_obj::thisClassId() const 
! { 
!     return FindName(thisNameSym()); 
! }
! 
  t_class *flext_obj::getClass(t_classid id) { return reinterpret_cast<libclass *>(id)->clss; }
  #endif
***************
*** 309,318 ****
  
  		// add to name list
! 		libname *l = libname::Find(MakeSymbol(c),lo);
  	
  #if FLEXT_SYS == FLEXT_SYS_PD
  		if(ix > 0) 
  			// in PD the first name is already registered with class creation
! 			::class_addcreator((t_newmethod)obj_new,(t_symbol *)l->name,A_GIMME,A_NULL);
  #elif FLEXT_SYS == FLEXT_SYS_MAX
  		if(ix > 0 || lib) 
--- 267,277 ----
  
  		// add to name list
!         const t_symbol *lsym = MakeSymbol(c);
! 		libclass *lcl = FindName(lsym,lo);
  	
  #if FLEXT_SYS == FLEXT_SYS_PD
  		if(ix > 0) 
  			// in PD the first name is already registered with class creation
! 			::class_addcreator((t_newmethod)obj_new,(t_symbol *)lsym,A_GIMME,A_NULL);
  #elif FLEXT_SYS == FLEXT_SYS_MAX
  		if(ix > 0 || lib) 
***************
*** 321,325 ****
  			::alias(const_cast<char *>(c));  
  #elif FLEXT_SYS == FLEXT_SYS_JMAX
! 		if(ix > 0)  fts_class_alias(lo->clss,l->name);
  #else
  #error
--- 280,284 ----
  			::alias(const_cast<char *>(c));  
  #elif FLEXT_SYS == FLEXT_SYS_JMAX
! 		if(ix > 0)  fts_class_alias(lo->clss,lsym);
  #else
  #error
***************
*** 347,355 ****
  	flext_hdr *obj = NULL;
  #endif
! 	libname *l = libname::Find(s);
! 	if(l) {
  		bool ok = true;
  		t_atom args[FLEXT_MAXNEWARGS]; 
- 		libclass *lo = l->obj;
  
  		int argc = _argc_;
--- 306,313 ----
  	flext_hdr *obj = NULL;
  #endif
! 	libclass *lo = FindName(s);
! 	if(lo) {
  		bool ok = true;
  		t_atom args[FLEXT_MAXNEWARGS]; 
  
  		int argc = _argc_;
***************
*** 411,415 ****
  
  		    flext_obj::m_holder = obj;
! 			flext_obj::m_holdname = l->name;
  			flext_obj::m_holdattr = lo->attr;
  
--- 369,373 ----
  
  		    flext_obj::m_holder = obj;
! 			flext_obj::m_holdname = s;
  			flext_obj::m_holdattr = lo->attr;
  
***************
*** 482,493 ****
  	flext_hdr *hdr = (flext_hdr *)h;
  	const t_symbol *name = hdr->data->thisNameSym();
! 	libname *l = libname::Find(name);
  
! 	if(l) {
  		// call virtual exit function
  		hdr->data->Exit();
  
  		// now call object destructor and deallocate
! 		l->obj->freefun(hdr);
  	}
  #ifdef FLEXT_DEBUG
--- 440,451 ----
  	flext_hdr *hdr = (flext_hdr *)h;
  	const t_symbol *name = hdr->data->thisNameSym();
! 	libclass *lcl = FindName(name);
  
! 	if(lcl) {
  		// call virtual exit function
  		hdr->data->Exit();
  
  		// now call object destructor and deallocate
! 		lcl->freefun(hdr);
  	}
  #ifdef FLEXT_DEBUG

Index: flmeth.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/flext/source/flmeth.cpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** flmeth.cpp	3 Aug 2003 02:36:46 -0000	1.7
--- flmeth.cpp	22 Feb 2004 03:34:00 -0000	1.8
***************
*** 3,7 ****
  flext - C++ layer for Max/MSP and pd (pure data) externals
  
! Copyright (c) 2001-2003 Thomas Grill (xovo at gmx.net)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
--- 3,7 ----
  flext - C++ layer for Max/MSP and pd (pure data) externals
  
! Copyright (c) 2001-2004 Thomas Grill (xovo at gmx.net)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
***************
*** 21,26 ****
  
  
! flext_base::MethItem::MethItem(int in,const t_symbol *tg,AttrItem *conn): 
! 	Item(tg,in,conn),index(0),
  	argc(0),args(NULL)
  	,fun(NULL)
--- 21,26 ----
  
  
! flext_base::MethItem::MethItem(AttrItem *conn): 
! 	Item(conn),index(0),
  	argc(0),args(NULL)
  	,fun(NULL)
***************
*** 42,46 ****
  void flext_base::AddMethodDef(int inlet,const char *tag)
  {
! 	methhead->Add(new MethItem(inlet,tag?MakeSymbol(tag):NULL));
  }
  
--- 42,47 ----
  void flext_base::AddMethodDef(int inlet,const char *tag)
  {
!     const t_symbol *t = tag?MakeSymbol(tag):NULL;
! 	methhead->Add(new MethItem,t,inlet);
  }
  
***************
*** 85,110 ****
  	}
  	
! 	MethItem *mi = new MethItem(inlet,MakeSymbol(tag));
! 
  	mi->SetArgs(fun,argc,args);
! 
! 	ma->Add(mi);
! 
! 	// set index
! 	MethItem *last = (MethItem *)ma->Last();
! 	if(last) mi->index = last->index+1;
  }
  
- 
- struct methless : public std::binary_function <flext_base::MethItem *,flext_base::MethItem *, bool> 
- {
- 	bool operator()(const flext_base::MethItem *l,const flext_base::MethItem *r) const { 
- 		return l->index != r->index?l->index < r->index:strcmp(flext::GetString(l->tag),flext::GetString(r->tag)) < 0; 
- 	}
- };
- 
  void flext_base::ListMethods(AtomList &la,int inlet) const
  {
! 	typedef std::set<MethItem *,methless> MethList;
  	MethList list[2];
  
--- 86,98 ----
  	}
  	
! 	MethItem *mi = new MethItem;
!     mi->index = ma->Members();
  	mi->SetArgs(fun,argc,args);
! 	ma->Add(mi,MakeSymbol(tag),inlet);
  }
  
  void flext_base::ListMethods(AtomList &la,int inlet) const
  {
! 	typedef std::map<int,const t_symbol *> MethList;
  	MethList list[2];
  
***************
*** 112,124 ****
  	for(i = 0; i <= 1; ++i) {
  		ItemCont *a = i?methhead:clmethhead;
! 		if(a) {
! 			for(int ai = 0; ai < a->Size(); ++ai) {
! 				for(Item *l = a->GetItem(ai); l; l = l->nxt) {
! 					MethItem *aa = (MethItem *)l;
  
! 					// match inlet and see check it's not related to an attribute
! 					if(aa->inlet == inlet && !aa->IsAttr())
! 						list[i].insert(aa);
! 				}
  			}
  		}
--- 100,115 ----
  	for(i = 0; i <= 1; ++i) {
  		ItemCont *a = i?methhead:clmethhead;
! 		if(a && a->Contained(inlet)) {
!             ItemSet &ai = a->GetInlet(inlet);
!             for(ItemSet::iterator as = ai.begin(); as != ai.end(); ++as) {
!                 for(ItemList::iterator al = as->second.begin(); al != as->second.end(); ++al) {
! 					MethItem *aa = (MethItem *)*al;
  
! 					// check it's not related to an attribute
!                     if(!aa->IsAttr()) {
!                         list[i][aa->index] = as->first;
!                         break;
!                     }
!                 }
  			}
  		}
***************
*** 130,134 ****
  	for(i = 0; i <= 1; ++i)
  		for(it = list[i].begin(); it != list[i].end(); ++it) 
! 			SetSymbol(la[ix++],(*it)->tag);
  }
  
--- 121,125 ----
  	for(i = 0; i <= 1; ++i)
  		for(it = list[i].begin(); it != list[i].end(); ++it) 
! 			SetSymbol(la[ix++],it->second);
  }
  

Index: flmsg.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/flext/source/flmsg.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -d -r1.9 -r1.10
*** flmsg.cpp	1 Aug 2003 02:32:50 -0000	1.9
--- flmsg.cpp	22 Feb 2004 03:34:00 -0000	1.10
***************
*** 3,7 ****
  flext - C++ layer for Max/MSP and pd (pure data) externals
  
! Copyright (c) 2001-2003 Thomas Grill (xovo at gmx.net)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
--- 3,7 ----
  flext - C++ layer for Max/MSP and pd (pure data) externals
  
! Copyright (c) 2001-2004 Thomas Grill (xovo at gmx.net)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
***************
*** 73,130 ****
  }
  
! bool flext_base::TryMethTag(const MethItem *m,int inlet,const t_symbol *t,int argc,const t_atom *argv)
  {
! 	do {
! 		if(m->inlet == inlet && m->tag == t) {
! 			FLEXT_LOG3("found method tag %s: inlet=%i, argc=%i",GetString(m->tag),m->inlet,argc);
! 		
! 			if(m->attr) {
! 				// attributes are treated differently
  
! 				if(m->attr->IsGet())
! 					return DumpAttrib(m->attr);
! 				else
! 					return SetAttrib(m->attr,argc,argv);
! 			}
! 			else {
! 				if(m->argc == 1) {
! 					// try list
! 					if(m->args[0] == a_list && ((methfun_V)m->fun)(this,argc,const_cast<t_atom *>(argv))) return true;
  
! 					// try anything
! 					if(m->args[0] == a_any && ((methfun_A)m->fun)(this,m->tag,argc,const_cast<t_atom *>(argv))) return true;
! 				}
  
! 				// try matching number of args
! 				if(argc == m->argc && CallMeth(*m,argc,argv)) return true;
  			}
  		}
! 	} while((m = (const MethItem *)m->nxt) != NULL);
  	return false;
  }
  
! bool flext_base::TryMethSym(const MethItem *m,int inlet,const t_symbol *t,const t_symbol *s)
  {
! 	do {
! 		if(!m->IsAttr() && m->inlet == inlet && m->tag == t) {
! 			FLEXT_LOG3("found symbol method for %s: inlet=%i, symbol=%s",GetString(m->tag),m->inlet,GetString(s));
  
  			t_any sym; sym.st = const_cast<t_symbol *>(s);
  			if(((methfun_1)m->fun)(this,sym)) return true;
  		}
! 	} while((m = (const MethItem *)m->nxt) != NULL);
  	return false;
  }
  
! bool flext_base::TryMethAny(const MethItem *m,int inlet,const t_symbol *t,const t_symbol *s,int argc,const t_atom *argv)
  {
! 	do {
! 		if(!m->IsAttr() && m->inlet == inlet && m->tag == t) {
! 			FLEXT_LOG4("found any method for %s: inlet=%i, symbol=%s, argc=%i",GetString(m->tag),m->inlet,GetString(s),argc);
  
  			if(((methfun_A)m->fun)(this,s,argc,const_cast<t_atom *>(argv))) return true;
  		}
! 	} while((m = (const MethItem *)m->nxt) != NULL);
! 	return false;
  }
  
--- 73,134 ----
  }
  
! bool flext_base::TryMethTag(ItemList &lst,const t_symbol *tag,int argc,const t_atom *argv)
  {
!     for(ItemList::iterator it = lst.begin(); it != lst.end(); ++it) {
!         MethItem *m = (MethItem *)*it;
  
! //        FLEXT_LOG3("found method tag %s: inlet=%i, argc=%i",GetString(tag),m->inlet,argc);
! 	
! 		if(m->attr) {
! 			// attributes are treated differently
  
! 			if(m->attr->IsGet())
! 				return DumpAttrib(tag,m->attr);
! 			else
! 				return SetAttrib(tag,m->attr,argc,argv);
! 		}
! 		else {
! 			if(m->argc == 1) {
! 				// try list
! 				if(m->args[0] == a_list && ((methfun_V)m->fun)(this,argc,const_cast<t_atom *>(argv))) return true;
  
! 				// try anything
! 				if(m->args[0] == a_any && ((methfun_A)m->fun)(this,tag,argc,const_cast<t_atom *>(argv))) return true;
  			}
+ 
+ 			// try matching number of args
+ 			if(argc == m->argc && CallMeth(*m,argc,argv)) return true;
  		}
! 	}
  	return false;
  }
  
! bool flext_base::TryMethSym(ItemList &lst,const t_symbol *s)
  {
!     for(ItemList::iterator it = lst.begin(); it != lst.end(); ++it) {
!         MethItem *m = (MethItem *)*it;
! 
! 		if(!m->IsAttr()) {
! //			FLEXT_LOG3("found symbol method for %s: inlet=%i, symbol=%s",GetString(m->tag),m->inlet,GetString(s));
  
  			t_any sym; sym.st = const_cast<t_symbol *>(s);
  			if(((methfun_1)m->fun)(this,sym)) return true;
  		}
! 	}
  	return false;
  }
  
! bool flext_base::TryMethAny(ItemList &lst,const t_symbol *s,int argc,const t_atom *argv)
  {
!     for(ItemList::iterator it = lst.begin(); it != lst.end(); ++it) {
!         MethItem *m = (MethItem *)*it;
! 
! 		if(!m->IsAttr() && m->argc == 1 && m->args[0] == a_any) {
! //			FLEXT_LOG4("found any method for %s: inlet=%i, symbol=%s, argc=%i",GetString(m->tag),m->inlet,GetString(s),argc);
  
  			if(((methfun_A)m->fun)(this,s,argc,const_cast<t_atom *>(argv))) return true;
  		}
!     }
!     return false;
  }
  
***************
*** 134,152 ****
  bool flext_base::FindMeth(int inlet,const t_symbol *s,int argc,const t_atom *argv)
  {
! 	MethItem *m;
! 	
  	// search for exactly matching tag
! 	if((m = (MethItem *)methhead->Find(s,inlet)) != NULL && TryMethTag(m,inlet,s,argc,argv)) return true;
! 	if((m = (MethItem *)clmethhead->Find(s,inlet)) != NULL && TryMethTag(m,inlet,s,argc,argv)) return true;
  	
  	// if no list args, then search for pure symbol 
  	if(!argc) {
! 		if((m = (MethItem *)methhead->Find(sym_symbol,inlet)) != NULL && TryMethSym(m,inlet,sym_symbol,s)) return true;
! 		if((m = (MethItem *)clmethhead->Find(sym_symbol,inlet)) != NULL && TryMethSym(m,inlet,sym_symbol,s)) return true;
  	}
  	
  	// otherwise search for anything
! 	if((m = (MethItem *)methhead->Find(sym_anything,inlet)) != NULL && m->argc == 1 && m->args[0] == a_any && TryMethAny(m,inlet,sym_anything,s,argc,argv)) return true;
! 	if((m = (MethItem *)clmethhead->Find(sym_anything,inlet)) != NULL && m->argc == 1 && m->args[0] == a_any && TryMethAny(m,inlet,sym_anything,s,argc,argv)) return true;
  
  	// if nothing found try any inlet
--- 138,156 ----
  bool flext_base::FindMeth(int inlet,const t_symbol *s,int argc,const t_atom *argv)
  {
!     ItemList *lst;
! 
  	// search for exactly matching tag
! 	if((lst = methhead->FindList(s,inlet)) != NULL && TryMethTag(*lst,s,argc,argv)) return true;
! 	if((lst = clmethhead->FindList(s,inlet)) != NULL && TryMethTag(*lst,s,argc,argv)) return true;
  	
  	// if no list args, then search for pure symbol 
  	if(!argc) {
! 		if((lst = methhead->FindList(sym_symbol,inlet)) != NULL && TryMethSym(*lst,s)) return true;
! 		if((lst = clmethhead->FindList(sym_symbol,inlet)) != NULL && TryMethSym(*lst,s)) return true;
  	}
  	
  	// otherwise search for anything
! 	if((lst = methhead->FindList(sym_anything,inlet)) != NULL && TryMethAny(*lst,s,argc,argv)) return true;
! 	if((lst = clmethhead->FindList(sym_anything,inlet)) != NULL && TryMethAny(*lst,s,argc,argv)) return true;
  
  	// if nothing found try any inlet

Index: flprefix.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/flext/source/flprefix.h,v
retrieving revision 1.24
retrieving revision 1.25
diff -C2 -d -r1.24 -r1.25
*** flprefix.h	13 Nov 2003 03:33:09 -0000	1.24
--- flprefix.h	22 Feb 2004 03:34:00 -0000	1.25
***************
*** 224,228 ****
  		#if defined(linux) || defined(__linux__)
  			#define FLEXT_OS FLEXT_OS_LINUX
! 		#elif defined(__CYGWIN__) || defined(__CYGWIN32__)
  			#define FLEXT_OS FLEXT_OS_WIN
  		#elif defined(__APPLE__) && defined(__MACH__)
--- 224,228 ----
  		#if defined(linux) || defined(__linux__)
  			#define FLEXT_OS FLEXT_OS_LINUX
! 		#elif defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__MINGW32__)
  			#define FLEXT_OS FLEXT_OS_WIN
  		#elif defined(__APPLE__) && defined(__MACH__)

Index: flsupport.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/flext/source/flsupport.cpp,v
retrieving revision 1.30
retrieving revision 1.31
diff -C2 -d -r1.30 -r1.31
*** flsupport.cpp	10 Feb 2004 03:29:50 -0000	1.30
--- flsupport.cpp	22 Feb 2004 03:34:00 -0000	1.31
***************
*** 3,7 ****
  flext - C++ layer for Max/MSP and pd (pure data) externals
  
! Copyright (c) 2001-2003 Thomas Grill (xovo at gmx.net)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
--- 3,7 ----
  flext - C++ layer for Max/MSP and pd (pure data) externals
  
! Copyright (c) 2001-2004 Thomas Grill (xovo at gmx.net)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
***************
*** 274,294 ****
  }
  
- unsigned int flext::FoldBits(unsigned long h,int bits)
- {
- 	if(!bits) return 0;
- 	const int hmax = (1<<bits)-1;
- 	unsigned int ret = 0;
- 	for(unsigned int i = 0; i < sizeof(h)*8; i += bits)
- 		ret ^= (h>>i)&hmax;
- 	return ret;
- }
- 
- int flext::Int2Bits(unsigned long n)
- {
- 	int b;
- 	for(b = 0; n; ++b) n >>= 1;
- 	return b;
- }
- 
  
  void flext_root::post(const char *fmt, ...)
--- 274,277 ----

Index: flsupport.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/flext/source/flsupport.h,v
retrieving revision 1.63
retrieving revision 1.64
diff -C2 -d -r1.63 -r1.64
*** flsupport.h	29 Jan 2004 03:32:03 -0000	1.63
--- flsupport.h	22 Feb 2004 03:34:00 -0000	1.64
***************
*** 278,291 ****
  
  
! 	//! Get a 32 bit hash value frm an atom
  	static unsigned long AtomHash(const t_atom &a);
- 	
- 	/*! \brief Fold value to a number of bits
- 		\remark Good for hash tables
- 	*/
- 	static unsigned int FoldBits(unsigned long h,int bits);
- 	
- 	//! \brief How many bits are necessary to represent n
- 	static int Int2Bits(unsigned long n);
  
  //!		@} FLEXT_S_UTIL
--- 278,283 ----
  
  
! 	//! Get a 32 bit hash value from an atom
  	static unsigned long AtomHash(const t_atom &a);
  
  //!		@} FLEXT_S_UTIL





More information about the Pd-cvs mailing list