diff options
Diffstat (limited to 'externals/grill')
20 files changed, 537 insertions, 626 deletions
diff --git a/externals/grill/flext/build-pd-mingw.bat b/externals/grill/flext/build-pd-mingw.bat new file mode 100644 index 00000000..edab49fa --- /dev/null +++ b/externals/grill/flext/build-pd-mingw.bat @@ -0,0 +1,2 @@ +mingw32-make -f makefile.pd-mingw +mingw32-make -f makefile.pd-mingw install diff --git a/externals/grill/flext/changes.txt b/externals/grill/flext/changes.txt index da545079..6e5ef3a7 100644 --- a/externals/grill/flext/changes.txt +++ b/externals/grill/flext/changes.txt @@ -19,6 +19,8 @@ Version history: - fixed entry of local variables with attribute editor - help window for attribute editor - appended lacking ~ for tilde object help patches +- STL containers for all kinds of attribute, method, class handling +- support for MinGW 0.4.5: - added some more SIMD functions @@ -289,6 +291,8 @@ general: - support for Max qelem style +- unify STL containers so that there's only one code template + bugs: - attributes and attribute editor saving with patcher arguments (like $0-gugu ) diff --git a/externals/grill/flext/config-pd-mingw.txt b/externals/grill/flext/config-pd-mingw.txt new file mode 100644 index 00000000..a71d5c46 --- /dev/null +++ b/externals/grill/flext/config-pd-mingw.txt @@ -0,0 +1,28 @@ +# flext - C++ layer for Max/MSP and pd (pure data) externals +# Copyright (c) 2001-2004 Thomas Grill (xovo@gmx.net) +# + +# your c++ compiler (define only if it's different than g++) +# CXX=g++ + +# where is PD? +PDPATH=c:/programme/audio/pd + +# where is the SndObj include directory? +# (leave blank or comment out to disable SndObj support) +#SNDOBJ=/cygdrive/f/prog/audio/sndobj/include + +# where is the STK include directory? +# (leave blank or comment out to disable STK support) +#STK=/cygdrive/f/prog/audio/stk/include + +# where should flext libraries be built? +TARGDIR=./pd-mingw + +# where should flext libraries be installed? +# (leave blank to omit installation) +INSTDIR=${PDPATH}/flext + +# additional compiler flags +# (check if they fit for your system!) +UFLAGS=-mcpu=pentium4 -msse
\ No newline at end of file diff --git a/externals/grill/flext/flext.vcproj b/externals/grill/flext/flext.vcproj index 9dc85a0c..7c4600b0 100644 --- a/externals/grill/flext/flext.vcproj +++ b/externals/grill/flext/flext.vcproj @@ -285,6 +285,7 @@ PrecompiledHeaderThrough="flext.h" WarningLevel="3" SuppressStartupBanner="TRUE" + DebugInformationFormat="3" CompileAs="0"/> <Tool Name="VCCustomBuildTool"/> @@ -397,7 +398,7 @@ BrowseInformation="1" WarningLevel="3" SuppressStartupBanner="TRUE" - DebugInformationFormat="3" + DebugInformationFormat="0" CompileAs="0"/> <Tool Name="VCCustomBuildTool"/> @@ -532,7 +533,7 @@ copy F:\prog\max\flext\pd-msvc\flext.dll f:\prog\dll AdditionalDependencies="maxapi.lib maxext.lib maxaudio.lib stk.lib sndobj.lib" OutputFile=".\max-msvc\flext.max.dll" AdditionalLibraryDirectories=""F:\prog\audio\MaxWinSDK\c74support\max-includes\win-includes\debug";"F:\prog\audio\MaxWinSDK\c74support\msp-includes\win-includes\debug";f:\prog\packs\pthreads;F:\prog\audio\stk\lib;F:\prog\audio\sndobj\lib" - IgnoreAllDefaultLibraries="TRUE" + IgnoreAllDefaultLibraries="FALSE" GenerateDebugInformation="FALSE" OptimizeReferences="1" ImportLibrary="./max-msvc/flext_l.lib"/> diff --git a/externals/grill/flext/makefile.pd-cygwin b/externals/grill/flext/makefile.pd-cygwin index 5c7d5ddf..85b5d321 100644 --- a/externals/grill/flext/makefile.pd-cygwin +++ b/externals/grill/flext/makefile.pd-cygwin @@ -1,5 +1,5 @@ # 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) # # Makefile for gcc @ cygwin # @@ -17,12 +17,13 @@ include $(CONFIG) # compiler+linker stuff -INCLUDES=/usr/include $(PDPATH)/src +INCLUDES=$(PDPATH)/src # /usr/include FLAGS=-DFLEXT_SYS=2 $(UFLAGS) CFLAGS=-O2 -CFLAGS_D=-g +CFLAGS_D=-DFLEXT_DEBUG -g CFLAGS_T=-DFLEXT_THREADS +CFLAGS_S=-DFLEXT_SHARED LIBS= INSTDIR=$(PDPATH)/flext @@ -54,8 +55,13 @@ TARGET=$(TARGDIR)/$(NAME)-pdwin.lib TARGET_D=$(TARGDIR)/$(NAME)_d-pdwin.lib TARGET_T=$(TARGDIR)/$(NAME)_t-pdwin.lib TARGET_TD=$(TARGDIR)/$(NAME)_td-pdwin.lib +TARGET_S=$(TARGDIR)/$(NAME).dll +TARGET_SD=$(TARGDIR)/$(NAME)_d.dll -all: $(TARGDIR) $(TARGET) $(TARGET_D) $(TARGET_T) $(TARGET_TD) +TARGETS=$(TARGET) $(TARGET_D) $(TARGET_T) $(TARGET_TD) # $(TARGET_S) $(TARGET_SD) + + +all: $(TARGDIR) $(TARGETS) $(TARGDIR): -mkdir $(TARGDIR) @@ -75,25 +81,41 @@ $(TARGDIR)/%.to : $(SRCDIR)/%.cpp $(TARGDIR)/%.tdo : $(SRCDIR)/%.cpp $(CXX) -c $(CFLAGS_D) $(CFLAGS_T) $(FLAGS) $(patsubst %,-I%,$(INCLUDES) $(SRCDIR)) $< -o $@ +$(TARGDIR)/%.so : $(SRCDIR)/%.cpp + $(CXX) -c $(CFLAGS) $(CFLAGS_S) $(FLAGS) $(patsubst %,-I%,$(INCLUDES) $(SRCDIR)) $< -o $@ + +$(TARGDIR)/%.sdo : $(SRCDIR)/%.cpp + $(CXX) -c $(CFLAGS_D) $(CFLAGS_S) $(FLAGS) $(patsubst %,-I%,$(INCLUDES) $(SRCDIR)) $< -o $@ + + $(TARGET) : $(patsubst %.cpp,$(TARGDIR)/%.o,$(SRCS)) - ar rc $@ $^ + $(AR) rc $@ $^ chmod 755 $@ $(TARGET_D) : $(patsubst %.cpp,$(TARGDIR)/%.do,$(SRCS)) - ar rc $@ $^ + $(AR) rc $@ $^ chmod 755 $@ $(TARGET_T) : $(patsubst %.cpp,$(TARGDIR)/%.to,$(SRCS)) - ar rc $@ $^ + $(AR) rc $@ $^ chmod 755 $@ $(TARGET_TD) : $(patsubst %.cpp,$(TARGDIR)/%.tdo,$(SRCS)) - ar rc $@ $^ + $(AR) rc $@ $^ chmod 755 $@ +$(TARGET_S) : $(patsubst %.cpp,$(TARGDIR)/%.so,$(SRCS)) + $(CXX) -o $@ $^ + chmod 755 $@ + +$(TARGET_SD) : $(patsubst %.cpp,$(TARGDIR)/%.sdo,$(SRCS)) + $(CXX) -o $@ $^ + chmod 755 $@ + + .PHONY: clean install clean: - rm -f $(TARGDIR)/*.o $(TARGET) $(TARGET_D) + rm -f $(TARGDIR)/*.o $(TARGETS) ifdef INSTDIR $(INSTDIR): @@ -102,15 +124,5 @@ $(INSTDIR): install:: $(INSTDIR) endif -install:: $(TARGET) $(TARGET_D) $(TARGET_T) $(TARGET_TD) $(patsubst %,$(SRCDIR)/%,$(HDRS)) +install:: $(TARGETS) $(patsubst %,$(SRCDIR)/%,$(HDRS)) cp $^ $(INSTDIR) - - - - - - - - - - diff --git a/externals/grill/flext/makefile.pd-mingw b/externals/grill/flext/makefile.pd-mingw new file mode 100644 index 00000000..9a7db3a5 --- /dev/null +++ b/externals/grill/flext/makefile.pd-mingw @@ -0,0 +1,136 @@ +# flext - C++ layer for Max/MSP and pd (pure data) externals +# Copyright (c) 2001-2004 Thomas Grill (xovo@gmx.net) +# +# Makefile for gcc @ mingw +# +# usage: +# to build run "make -f makefile.pd-mingw" +# +# --------------------------------------------- +# +# compiling for threaded usage is not supported +# + +CONFIG=config-pd-mingw.txt + +include $(CONFIG) + + +# compiler+linker stuff +INCLUDES=$(PDPATH)/src # /usr/include + +FLAGS=-DFLEXT_SYS=2 $(UFLAGS) +CFLAGS=-O2 +CFLAGS_D=-DFLEXT_DEBUG -g +CFLAGS_T=-DFLEXT_THREADS +CFLAGS_S=-DFLEXT_SHARED +LIBS= + +INSTDIR=$(PDPATH)/flext + +# ---------------------------------------------- +# the rest can stay untouched +# ---------------------------------------------- + +NAME=flext +SRCDIR=source + +# all the source files from the package +include make-files.txt + +ifdef SNDOBJ +INCLUDES+=$(SNDOBJ) +SRCS+=$(SRCS_SNDOBJ) +HDRS+=$(HDRS_SNDOBJ) +endif + +ifdef STK +INCLUDES+=$(STK) +SRCS+=$(SRCS_STK) +HDRS+=$(HDRS_STK) +endif + +MAKEFILE=makefile.pd-mingw +TARGET=$(TARGDIR)/$(NAME)-pdwin.lib +TARGET_D=$(TARGDIR)/$(NAME)_d-pdwin.lib +TARGET_T=$(TARGDIR)/$(NAME)_t-pdwin.lib +TARGET_TD=$(TARGDIR)/$(NAME)_td-pdwin.lib + +TARGETS=$(TARGET) $(TARGET_D) # $(TARGET_T) $(TARGET_TD) $(TARGET_S) $(TARGET_SD) + + +all: $(TARGDIR) $(TARGETS) +$(TARGDIR): + -mkdir $(TARGDIR) + +$(SRCS): $(HDRS) $(IHDRS) $(MAKEFILE) $(CONFIG) + touch $@ + + +$(TARGDIR)/%.o : $(SRCDIR)/%.cpp + $(CXX) -c $(CFLAGS) $(FLAGS) $(patsubst %,-I%,$(INCLUDES) $(SRCDIR)) $< -o $@ + +$(TARGDIR)/%.do : $(SRCDIR)/%.cpp + $(CXX) -c $(CFLAGS_D) $(FLAGS) $(patsubst %,-I%,$(INCLUDES) $(SRCDIR)) $< -o $@ + +$(TARGDIR)/%.to : $(SRCDIR)/%.cpp + $(CXX) -c $(CFLAGS) $(CFLAGS_T) $(FLAGS) $(patsubst %,-I%,$(INCLUDES) $(SRCDIR)) $< -o $@ + +$(TARGDIR)/%.tdo : $(SRCDIR)/%.cpp + $(CXX) -c $(CFLAGS_D) $(CFLAGS_T) $(FLAGS) $(patsubst %,-I%,$(INCLUDES) $(SRCDIR)) $< -o $@ + +$(TARGDIR)/%.so : $(SRCDIR)/%.cpp + $(CXX) -c $(CFLAGS) $(CFLAGS_S) $(FLAGS) $(patsubst %,-I%,$(INCLUDES) $(SRCDIR)) $< -o $@ + +$(TARGDIR)/%.sdo : $(SRCDIR)/%.cpp + $(CXX) -c $(CFLAGS_D) $(CFLAGS_S) $(FLAGS) $(patsubst %,-I%,$(INCLUDES) $(SRCDIR)) $< -o $@ + + +$(TARGET) : $(patsubst %.cpp,$(TARGDIR)/%.o,$(SRCS)) + $(AR) rc $@ $^ + chmod 755 $@ + +$(TARGET_D) : $(patsubst %.cpp,$(TARGDIR)/%.do,$(SRCS)) + $(AR) rc $@ $^ + chmod 755 $@ + +$(TARGET_T) : $(patsubst %.cpp,$(TARGDIR)/%.to,$(SRCS)) + $(AR) rc $@ $^ + chmod 755 $@ + +$(TARGET_TD) : $(patsubst %.cpp,$(TARGDIR)/%.tdo,$(SRCS)) + $(AR) rc $@ $^ + chmod 755 $@ + +$(TARGET_S) : $(patsubst %.cpp,$(TARGDIR)/%.so,$(SRCS)) + $(CXX) -o $@ $^ + chmod 755 $@ + +$(TARGET_SD) : $(patsubst %.cpp,$(TARGDIR)/%.sdo,$(SRCS)) + $(CXX) -o $@ $^ + chmod 755 $@ + + +.PHONY: clean install +clean: + rm -f $(TARGDIR)/*.o $(TARGETS) + +ifdef INSTDIR +$(INSTDIR): + -mkdir $(INSTDIR) + +install:: $(INSTDIR) +endif + +install:: $(TARGETS) $(patsubst %,$(SRCDIR)/%,$(HDRS)) + cp $^ $(INSTDIR) + + + + + + + + + + diff --git a/externals/grill/flext/makefile.pd-msvc b/externals/grill/flext/makefile.pd-msvc index 3250df20..4e87f4e0 100644 --- a/externals/grill/flext/makefile.pd-msvc +++ b/externals/grill/flext/makefile.pd-msvc @@ -12,7 +12,7 @@ !include config-pd-msvc.txt -all: flext flext_t flext_d flext_td # flext_s flext_sd +all: flext flext_t flext_d flext_td flext_s flext_sd flext: nmake /f make-inc.pd-msvc NAME=$* diff --git a/externals/grill/flext/readme.txt b/externals/grill/flext/readme.txt index 14569af4..3b01b00c 100644 --- a/externals/grill/flext/readme.txt +++ b/externals/grill/flext/readme.txt @@ -1,6 +1,6 @@ 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. @@ -43,12 +43,17 @@ o Microsoft Visual C++ 6 or 7: run "build-pd-msvc.bat" o Borland C++ 5.5 (free): - edit "config-pd-bcc.txt" - run "build-pd-bcc.bat" + edit "config-pd-bcc.txt" and run "build-pd-bcc.bat" + BCC++ currently supports non-threaded static flext libraries only o Cygwin: edit "config-pd-cygwin.txt" & run "sh build-pd-cygwin.sh" additional settings (e.g. target processor, compiler flags) can be made in makefile.pd-cygwin +o MinGW: edit "config-pd-mingw.txt" & run "build-pd-mingw.bat" + the MinGW binaries have to be in the PATH + additional settings (e.g. target processor, compiler flags) can be made in makefile.pd-mingw + MinGW currently supports non-threaded static flext libraries only + With your project using flext, be sure to define "FLEXT_SYS=2". diff --git a/externals/grill/flext/source/flattr.cpp b/externals/grill/flext/source/flattr.cpp index 52d46872..2901b828 100644 --- a/externals/grill/flext/source/flattr.cpp +++ b/externals/grill/flext/source/flattr.cpp @@ -25,8 +25,8 @@ WARRANTIES, see the file, "license.txt," in this distribution. #define STD #endif -flext_base::AttrItem::AttrItem(const t_symbol *t,metharg tp,methfun f,int fl): - Item(t,0,NULL),index(0), +flext_base::AttrItem::AttrItem(metharg tp,methfun f,int fl): + Item(NULL),index(0), flags(fl|afl_shown), argtp(tp),fun(f), counter(NULL) @@ -46,39 +46,31 @@ void flext_base::AddAttrib(ItemCont *aa,ItemCont *ma,const char *attr,metharg tp 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); + 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(0,asym,a); + MethItem *mi = new MethItem(a); mi->SetArgs(sfun,1,new metharg(tp)); - ma->Add(mi); + ma->Add(mi,asym); } else a = NULL; 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); + b = new AttrItem(tp,gfun,AttrItem::afl_get); + b->index = aa->Members(); + aa->Add(b,asym); static char tmp[256] = "get"; strcpy(tmp+3,attr); // bind attribute to a method - MethItem *mi = new MethItem(0,MakeSymbol(tmp),b); + MethItem *mi = new MethItem(b); mi->SetArgs(gfun,0,NULL); - ma->Add(mi); + ma->Add(mi,MakeSymbol(tmp)); } else b = NULL; @@ -102,38 +94,22 @@ void flext_base::AddAttrib(t_classid c,const char *attr,metharg tp,methfun gfun, AddAttrib(ClAttrs(c),ClMeths(c),attr,tp,gfun,sfun); } -/* -//! 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; + 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) { - 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); - } + 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; + } } } } @@ -143,7 +119,7 @@ void flext_base::ListAttrib(AtomList &la) const AttrList::iterator it; for(i = 0; i <= 1; ++i) for(it = list[i].begin(); it != list[i].end(); ++it) - SetSymbol(la[ix++],(*it)->tag); + SetSymbol(la[ix++],it->second); } int flext_base::CheckAttrib(int argc,const t_atom *argv) @@ -173,7 +149,7 @@ bool flext_base::InitAttrib(int argc,const t_atom *argv) a.SetInitValue(nxt-cur-1,argv+cur+1); // pass value to object - SetAttrib(attr,a.GetInitValue()); + SetAttrib(tag,attr,a.GetInitValue()); } } return true; @@ -194,16 +170,29 @@ bool flext_base::ListAttrib() const flext_base::AttrItem *flext_base::FindAttrib(const t_symbol *tag,bool get,bool msg) const { // 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; + 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) { - a = (AttrItem *)clattrhead->Find(tag); - while(a && (a->tag != tag || a->inlet != 0 || (get?a->IsSet():a->IsGet()))) a = (AttrItem *)a->nxt; + 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) { + if(!a && msg) { // print a message error("%s - %s: attribute not found",thisName(),GetString(tag)); } @@ -215,12 +204,12 @@ bool flext_base::SetAttrib(const t_symbol *tag,int argc,const t_atom *argv) // search for matching attribute AttrItem *a = FindAttrib(tag,false,true); if(a) - return SetAttrib(a,argc,argv); + return SetAttrib(tag,a,argc,argv); else return true; } -bool flext_base::SetAttrib(AttrItem *a,int argc,const t_atom *argv) +bool flext_base::SetAttrib(const t_symbol *tag,AttrItem *a,int argc,const t_atom *argv) { if(a->fun) { bool ok = true; @@ -272,15 +261,15 @@ bool flext_base::SetAttrib(AttrItem *a,int argc,const t_atom *argv) } if(!ok) - post("%s - wrong arguments for attribute %s",thisName(),GetString(a->tag)); + post("%s - wrong arguments for attribute %s",thisName(),GetString(tag)); } else - post("%s - attribute %s has no get method",thisName(),GetString(a->tag)); + post("%s - attribute %s has no get method",thisName(),GetString(tag)); return true; } -bool flext_base::GetAttrib(AttrItem *a,AtomList &la) const +bool flext_base::GetAttrib(const t_symbol *tag,AttrItem *a,AtomList &la) const { bool ok = true; // main attribute tag @@ -323,12 +312,12 @@ bool flext_base::GetAttrib(AttrItem *a,AtomList &la) const } } else { - post("%s - attribute %s has no get method",thisName(),GetString(a->tag)); + post("%s - attribute %s has no get method",thisName(),GetString(tag)); ok = false; } } else { - error("%s - %s: attribute not found",thisName(),GetString(a->tag)); + error("%s - %s: attribute not found",thisName(),GetString(tag)); ok = false; } return ok; @@ -337,24 +326,24 @@ bool flext_base::GetAttrib(AttrItem *a,AtomList &la) const bool flext_base::GetAttrib(const t_symbol *s,AtomList &a) const { AttrItem *attr = FindAttrib(s,true); - return attr && GetAttrib(attr,a); + return attr && GetAttrib(s,attr,a); } -bool flext_base::DumpAttrib(AttrItem *a) const +bool flext_base::DumpAttrib(const t_symbol *tag,AttrItem *a) const { AtomList la; - bool ret = GetAttrib(a,la); - if(ret) ToOutAnything(GetOutAttr(),a->tag,la.Count(),la.Atoms()); + bool ret = GetAttrib(tag,a,la); + if(ret) ToOutAnything(GetOutAttr(),tag,la.Count(),la.Atoms()); return ret; } bool flext_base::DumpAttrib(const t_symbol *attr) const { AttrItem *item = FindAttrib(attr,true); - return item && DumpAttrib(item); + return item && DumpAttrib(attr,item); } -bool flext_base::BangAttrib(AttrItem *item) +bool flext_base::BangAttrib(const t_symbol *attr,AttrItem *item) { AtomList val; AttrItem *item2; @@ -362,7 +351,7 @@ bool flext_base::BangAttrib(AttrItem *item) item = item->Counterpart(); if(item) { item2 = item->Counterpart(); - return item2 && GetAttrib(item,val) && SetAttrib(item2,val); + return item2 && GetAttrib(attr,item,val) && SetAttrib(attr,item2,val); } else return false; @@ -371,26 +360,21 @@ bool flext_base::BangAttrib(AttrItem *item) bool flext_base::BangAttrib(const t_symbol *attr) { AttrItem *item = FindAttrib(attr,true); - return item && BangAttrib(item); + return item && BangAttrib(attr,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); + 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); + } + } } } return true; diff --git a/externals/grill/flext/source/flattr_ed.cpp b/externals/grill/flext/source/flattr_ed.cpp index 672e4e56..4d9f76ee 100644 --- a/externals/grill/flext/source/flattr_ed.cpp +++ b/externals/grill/flext/source/flattr_ed.cpp @@ -466,7 +466,7 @@ void flext_base::cb_GfxProperties(t_gobj *c, t_glist *) AtomList lv; if(gattr) { // gettable attribute is present // Retrieve attribute value - th->GetAttrib(gattr,lv); + th->GetAttrib(sym,gattr,lv); PrintList(lv.Count(),lv.Atoms(),b,sizeof(buf)+buf-b); b += strlen(b); } @@ -599,7 +599,7 @@ void flext_base::cb_GfxSave(t_gobj *c, t_binbuf *b) // 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); + th->GetAttrib(sym,attr,lv); lref = &lv; } } @@ -662,7 +662,7 @@ bool flext_base::cb_AttrDialog(flext_base *th,int argc,const t_atom *argv) // find puttable attribute AttrItem *attr = th->FindAttrib(aname,false); if(attr) { - bool ret = th->SetAttrib(attr,ccnt,argv+coffs); + bool ret = th->SetAttrib(aname,attr,ccnt,argv+coffs); FLEXT_ASSERT(ret); AttrDataCont::iterator it = th->attrdata->find(aname); diff --git a/externals/grill/flext/source/flbind.cpp b/externals/grill/flext/source/flbind.cpp index 815ffa45..01b23b6f 100644 --- a/externals/grill/flext/source/flbind.cpp +++ b/externals/grill/flext/source/flbind.cpp @@ -56,12 +56,17 @@ void flext_base::SetupBindProxy() } -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(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 pd_unbind(&px->obj.ob_pd,const_cast<t_symbol *>(tag)); @@ -73,7 +78,6 @@ flext_base::BindItem::~BindItem() #else # pragma warning("Not implemented") #endif - object_free(&px->obj); } } @@ -95,20 +99,19 @@ bool flext_base::BindMethod(const t_symbol *sym,bool (*fun)(flext_base *,t_symbo bindhead = new ItemCont; 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; + 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; + } } - - if(bindhead->Count() > 20) { - // Hash it! - bindhead->Finalize(); - } } SetupBindProxy(); @@ -122,8 +125,8 @@ bool flext_base::BindMethod(const t_symbol *sym,bool (*fun)(flext_base *,t_symbo #endif if(px) { - BindItem *mi = new BindItem(0,sym,fun,px); - bindhead->Add(mi); + BindItem *mi = new BindItem(fun,px); + bindhead->Add(mi,sym); px->init(this,mi,data); @@ -149,31 +152,33 @@ bool flext_base::UnbindMethod(const t_symbol *sym,bool (*fun)(flext_base *,t_sym { 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; - } + if(bindhead && bindhead->Contained(0)) { + ItemSet &set = bindhead->GetInlet(); + ItemSet::iterator it1,it2; + if(sym) { + // specific tag + it1 = it2 = set.find(sym); it2++; } - else { + else { // any tag + it1 = set.begin(),it2 = set.end(); + } - 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; + 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); - if(ok) delete it; + ok = bindhead->Remove(it,sym); + if(ok) { + it->Unbind(sym); + delete it; + } } } return ok; @@ -183,13 +188,17 @@ bool flext_base::GetBoundMethod(const t_symbol *sym,bool (*fun)(flext_base *,t_s { if(bindhead) { // Search for symbol - flext_base::BindItem *item = (flext_base::BindItem *)bindhead->Find(sym,0); + 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 - for(; item && item->tag == sym; item = (flext_base::BindItem *)item->nxt) - if(item->fun == fun) { - data = item->px->data; - return true; + // go through all items with matching tag + if(item->fun == fun) { + data = item->px->data; + return true; + } } } return false; @@ -197,21 +206,20 @@ bool flext_base::GetBoundMethod(const t_symbol *sym,bool (*fun)(flext_base *,t_s 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(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(); } -/* - if(memleak) - post("%s - Memory was not deallocated while unbinding methods",thisName()); -*/ return true; } diff --git a/externals/grill/flext/source/flclass.h b/externals/grill/flext/source/flclass.h index 721c3f5f..18af3baa 100644 --- a/externals/grill/flext/source/flclass.h +++ b/externals/grill/flext/source/flclass.h @@ -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. @@ -23,6 +23,7 @@ WARRANTIES, see the file, "license.txt," in this distribution. #include <map> #include <set> #include <list> +#include <vector> #ifdef _MSC_VER #pragma warning(disable: 4786) @@ -600,67 +601,56 @@ protected: class AttrItem; - class Item: - public flext_root + class Item { public: - Item(const t_symbol *t,int inl,AttrItem *a); - virtual ~Item(); + Item(AttrItem *a): attr(a) {} + virtual ~Item() {} bool IsAttr() const { return attr != NULL; } - const t_symbol *tag; - int inlet; AttrItem *attr; - Item *nxt; }; + 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: - public flext_root + private ItemVec { public: - ItemCont(); - ~ItemCont(); + 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); + void Add(Item *it,const t_symbol *tag,int inlet = 0); //! Remove an entry - bool Remove(Item *it); - //! Find an entry in the Item array - Item *Find(const t_symbol *tag,int inlet = 0) const; + 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]; } - //! Create hash table out of the preliminary linked lists - void Finalize(); + //! Get counter for total members (for index of new item) + int Members() const { return members; } - //! 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; + protected: + int members; }; - //! \brief This represents an item of the method list + //! \brief This represents an item of the method list class MethItem: - public Item { + public Item + { public: - MethItem(int inlet,const t_symbol *tg,AttrItem *conn = NULL); + MethItem(AttrItem *conn = NULL); virtual ~MethItem(); void SetArgs(methfun fun,int argc,metharg *args); @@ -673,9 +663,10 @@ protected: //! \brief This represents an item of the attribute list class AttrItem: - public Item { + public Item + { public: - AttrItem(const t_symbol *tag,metharg tp,methfun fun,int flags); + AttrItem(metharg tp,methfun fun,int flags); virtual ~AttrItem(); enum { @@ -737,13 +728,14 @@ private: public: //! \brief This represents an item of the symbol-bound method list - class BindItem - :public Item + 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); + 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; }; @@ -804,9 +796,9 @@ private: 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); + 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; mutable AttrDataCont *attrdata; @@ -818,13 +810,13 @@ private: bool ListMethods(int inlet = 0) const; bool ListAttrib() const; - bool DumpAttrib(AttrItem *a) const; - bool GetAttrib(AttrItem *a,AtomList &l) 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(AttrItem *a,int argc,const t_atom *argv); - bool SetAttrib(AttrItem *a,const AtomList &l) { return SetAttrib(a,l.Count(),l.Atoms()); } + 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(AttrItem *a); + bool BangAttrib(const t_symbol *tag,AttrItem *a); // show/hide the attribute bool ShowAttrib(AttrItem *a,bool show) const; diff --git a/externals/grill/flext/source/flext.cpp b/externals/grill/flext/source/flext.cpp index a6b651aa..b89e464b 100644 --- a/externals/grill/flext/source/flext.cpp +++ b/externals/grill/flext/source/flext.cpp @@ -122,18 +122,9 @@ bool flext_base::Init() if(ok) ok = InitInlets() && InitOutlets(); 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(); - + if(procattr && m_holdaargc && m_holdaargv) { // initialize creation attributes - if(m_holdaargc && m_holdaargv) - ok = InitAttrib(m_holdaargc,m_holdaargv); + ok = InitAttrib(m_holdaargc,m_holdaargv); } } 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 <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) +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<unsigned long>(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<<HASHBITS }; - - _itemarr(flext_obj::t_classid c,int i); - ~_itemarr(); +typedef std::map<flext_base::t_classid,flext_base::ItemCont *> ClassMap; +typedef std::vector<ClassMap> 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<unsigned long>(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; } diff --git a/externals/grill/flext/source/fllib.cpp b/externals/grill/flext/source/fllib.cpp index 6d9c32cd..c727bcb5 100755 --- a/externals/grill/flext/source/fllib.cpp +++ b/externals/grill/flext/source/fllib.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. @@ -125,68 +125,22 @@ libclass::libclass(t_class *&cl,flext_obj *(*newf)(int,t_atom *),void (*freef)(f argc(0),argv(NULL) {} -// 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) +//! Store or retrieve registered classes +static libclass *FindName(const t_symbol *s,libclass *o = NULL) { - return flext::FoldBits(reinterpret_cast<unsigned long>(s),HASHBITS); -} + typedef std::map<const t_symbol *,libclass *> LibMap; -libname *libname::Find(const t_symbol *s,libclass *o) -{ - if(!root) { - root = new libname *[HASHSIZE]; - memset(root,0,HASHSIZE*sizeof(*root)); - } + static LibMap libnames; - 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; + LibMap::iterator it = libnames.find(s); + if(it == libnames.end()) { + if(o) libnames[s] = o; + return o; + } + else + return it->second; } -libname **libname::root = NULL; - - // for Max/MSP, the library is represented by a special object (class) registered at startup // all objects in the library are clones of that library object - they share the same class @@ -194,7 +148,11 @@ libname **libname::root = NULL; static t_class *lib_class = NULL; static const t_symbol *lib_name = NULL; -flext_obj::t_classid flext_obj::thisClassId() const { return libname::Find(thisNameSym())->obj; } +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 @@ -308,19 +266,20 @@ void flext_obj::obj_add(bool lib,bool dsp,bool attr,const char *idname,const cha if(!c || !*c) break; // add to name list - libname *l = libname::Find(MakeSymbol(c),lo); + 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 *)l->name,A_GIMME,A_NULL); + ::class_addcreator((t_newmethod)obj_new,(t_symbol *)lsym,A_GIMME,A_NULL); #elif FLEXT_SYS == FLEXT_SYS_MAX if(ix > 0 || lib) // in Max/MSP the first alias gets its name from the name of the object file, // unless it is a library (then the name can be different) ::alias(const_cast<char *>(c)); #elif FLEXT_SYS == FLEXT_SYS_JMAX - if(ix > 0) fts_class_alias(lo->clss,l->name); + if(ix > 0) fts_class_alias(lo->clss,lsym); #else #error #endif @@ -346,11 +305,10 @@ flext_hdr *flext_obj::obj_new(const t_symbol *s,int _argc_,t_atom *argv) { flext_hdr *obj = NULL; #endif - libname *l = libname::Find(s); - if(l) { + libclass *lo = FindName(s); + if(lo) { bool ok = true; t_atom args[FLEXT_MAXNEWARGS]; - libclass *lo = l->obj; int argc = _argc_; if(lo->attr) { @@ -410,7 +368,7 @@ flext_hdr *flext_obj::obj_new(const t_symbol *s,int _argc_,t_atom *argv) // post("NEWINST CLID %p",clid); flext_obj::m_holder = obj; - flext_obj::m_holdname = l->name; + flext_obj::m_holdname = s; flext_obj::m_holdattr = lo->attr; // get actual flext object (newfun calls "new flext_obj()") @@ -481,14 +439,14 @@ void flext_obj::obj_free(flext_hdr *h) { flext_hdr *hdr = (flext_hdr *)h; const t_symbol *name = hdr->data->thisNameSym(); - libname *l = libname::Find(name); + libclass *lcl = FindName(name); - if(l) { + if(lcl) { // call virtual exit function hdr->data->Exit(); // now call object destructor and deallocate - l->obj->freefun(hdr); + lcl->freefun(hdr); } #ifdef FLEXT_DEBUG else diff --git a/externals/grill/flext/source/flmeth.cpp b/externals/grill/flext/source/flmeth.cpp index ce49b5c5..6f8e5844 100755 --- a/externals/grill/flext/source/flmeth.cpp +++ b/externals/grill/flext/source/flmeth.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. @@ -20,8 +20,8 @@ WARRANTIES, see the file, "license.txt," in this distribution. #include <set> -flext_base::MethItem::MethItem(int in,const t_symbol *tg,AttrItem *conn): - Item(tg,in,conn),index(0), +flext_base::MethItem::MethItem(AttrItem *conn): + Item(conn),index(0), argc(0),args(NULL) ,fun(NULL) {} @@ -41,7 +41,8 @@ void flext_base::MethItem::SetArgs(methfun _fun,int _argc,metharg *_args) void flext_base::AddMethodDef(int inlet,const char *tag) { - methhead->Add(new MethItem(inlet,tag?MakeSymbol(tag):NULL)); + const t_symbol *t = tag?MakeSymbol(tag):NULL; + methhead->Add(new MethItem,t,inlet); } /*! \brief Add a method to the queue @@ -84,42 +85,32 @@ void flext_base::AddMethod(ItemCont *ma,int inlet,const char *tag,methfun fun,me va_end(marker); } - MethItem *mi = new MethItem(inlet,MakeSymbol(tag)); - + MethItem *mi = new MethItem; + mi->index = ma->Members(); mi->SetArgs(fun,argc,args); - - ma->Add(mi); - - // set index - MethItem *last = (MethItem *)ma->Last(); - if(last) mi->index = last->index+1; + ma->Add(mi,MakeSymbol(tag),inlet); } - -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; + typedef std::map<int,const t_symbol *> MethList; MethList list[2]; int i; 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); - } + 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; + } + } } } } @@ -129,7 +120,7 @@ void flext_base::ListMethods(AtomList &la,int inlet) const MethList::iterator it; for(i = 0; i <= 1; ++i) for(it = list[i].begin(); it != list[i].end(); ++it) - SetSymbol(la[ix++],(*it)->tag); + SetSymbol(la[ix++],it->second); } bool flext_base::ListMethods(int inlet) const diff --git a/externals/grill/flext/source/flmsg.cpp b/externals/grill/flext/source/flmsg.cpp index 3086ff74..b778940f 100755 --- a/externals/grill/flext/source/flmsg.cpp +++ b/externals/grill/flext/source/flmsg.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. @@ -72,60 +72,64 @@ bool flext_base::CallMeth(const MethItem &m,int argc,const t_atom *argv) return ret; } -bool flext_base::TryMethTag(const MethItem *m,int inlet,const t_symbol *t,int argc,const t_atom *argv) +bool flext_base::TryMethTag(ItemList &lst,const t_symbol *tag,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 + for(ItemList::iterator it = lst.begin(); it != lst.end(); ++it) { + MethItem *m = (MethItem *)*it; - 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; +// FLEXT_LOG3("found method tag %s: inlet=%i, argc=%i",GetString(tag),m->inlet,argc); + + if(m->attr) { + // attributes are treated differently - // try anything - if(m->args[0] == a_any && ((methfun_A)m->fun)(this,m->tag,argc,const_cast<t_atom *>(argv))) return true; - } + 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 matching number of args - if(argc == m->argc && CallMeth(*m,argc,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; } - } 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) +bool flext_base::TryMethSym(ItemList &lst,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)); + 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; } - } 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) +bool flext_base::TryMethAny(ItemList &lst,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); + 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; } - } while((m = (const MethItem *)m->nxt) != NULL); - return false; + } + return false; } /*! \brief Find a method item for a specific tag and arguments @@ -133,21 +137,21 @@ bool flext_base::TryMethAny(const MethItem *m,int inlet,const t_symbol *t,const */ bool flext_base::FindMeth(int inlet,const t_symbol *s,int argc,const t_atom *argv) { - MethItem *m; - + ItemList *lst; + // 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((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((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; + 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((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((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 return inlet >= 0 && FindMeth(-1,s,argc,argv); diff --git a/externals/grill/flext/source/flprefix.h b/externals/grill/flext/source/flprefix.h index 693d8630..71cdaee9 100755 --- a/externals/grill/flext/source/flprefix.h +++ b/externals/grill/flext/source/flprefix.h @@ -223,7 +223,7 @@ WARRANTIES, see the file, "license.txt," in this distribution. #ifndef FLEXT_OS #if defined(linux) || defined(__linux__) #define FLEXT_OS FLEXT_OS_LINUX - #elif defined(__CYGWIN__) || defined(__CYGWIN32__) + #elif defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__MINGW32__) #define FLEXT_OS FLEXT_OS_WIN #elif defined(__APPLE__) && defined(__MACH__) #define FLEXT_OS FLEXT_OS_MAC diff --git a/externals/grill/flext/source/flsupport.cpp b/externals/grill/flext/source/flsupport.cpp index fad8db16..6c203124 100644 --- a/externals/grill/flext/source/flsupport.cpp +++ b/externals/grill/flext/source/flsupport.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. @@ -273,23 +273,6 @@ unsigned long flext::AtomHash(const t_atom &a) #endif } -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, ...) { diff --git a/externals/grill/flext/source/flsupport.h b/externals/grill/flext/source/flsupport.h index d2a8cb90..d61f6013 100644 --- a/externals/grill/flext/source/flsupport.h +++ b/externals/grill/flext/source/flsupport.h @@ -277,16 +277,8 @@ public: static void ZeroSamples(t_sample *dst,int cnt) { SetSamples(dst,cnt,0); } - //! Get a 32 bit hash value frm an atom + //! Get a 32 bit hash value from 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 |