From 0ed7a8b68dd73e2b0473b8127aeca99f3bac9061 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Wed, 1 Apr 2009 21:13:09 +0000 Subject: cleaned up grill externals - replaced with svn:externals to svn.grrrr.org/ext/trunk/ svn path=/trunk/; revision=10951 --- externals/grill/flext/source/fllib.cpp | 578 --------------------------------- 1 file changed, 578 deletions(-) delete mode 100644 externals/grill/flext/source/fllib.cpp (limited to 'externals/grill/flext/source/fllib.cpp') diff --git a/externals/grill/flext/source/fllib.cpp b/externals/grill/flext/source/fllib.cpp deleted file mode 100644 index 3b196f55..00000000 --- a/externals/grill/flext/source/fllib.cpp +++ /dev/null @@ -1,578 +0,0 @@ -/* - -flext - C++ layer for Max/MSP and pd (pure data) externals - -Copyright (c) 2001-2006 Thomas Grill (gr@grrrr.org) -For information on usage and redistribution, and for a DISCLAIMER OF ALL -WARRANTIES, see the file, "license.txt," in this distribution. - -*/ - -/*! \file fllib.cpp - \brief Code for handling of object (and library) creation functions. -*/ - -#include "flext.h" -#include "flinternal.h" - -#include -#include -#include -#include - -#define ALIASDEL ',' - -#define ALIASSLASHES ":/\\" -#if FLEXT_OS == FLEXT_OS_MAC - #define ALIASSLASH ':' -#elif FLEXT_OS == FLEXT_OS_WIN - #if FLEXT_SYS == FLEXT_SYS_PD - #define ALIASSLASH '/' - #elif FLEXT_SYS == FLEXT_SYS_MAX - #define ALIASSLASH '/' - #else - #error "Undefined" - #endif -#else - // default to "/" - #define ALIASSLASH '/' -#endif - -//! Extract space-delimited words from a string -static const char *extract(const char *name,int ix = 0) -{ - char tmp[1024]; - const char *n = name; - - const char *del = strchr(name,ALIASDEL); - - if(del) { -#if 0 - char *t = tmp; - while(n < del && (isspace(*n) || strchr(ALIASSLASHES,*n))) ++n; - while(n < del && !isspace(*n)) { - char c = *(n++); - *(t++) = strchr(ALIASSLASHES,c)?ALIASSLASH:c; - } - while(*t == ALIASSLASH && t > tmp) --t; - *t = 0; -#endif - if(ix < 0) { - // eat white space in front of help definition - ++del; - while(*del && isspace(*del)) ++del; - return del; - } - - strncpy(tmp,name,del-name); - tmp[del-name] = 0; - n = tmp; - } - else if(ix < 0) - return NULL; // no explicit help name - - while(*n && isspace(*n)) ++n; - - for(int i = 0; n && *n; ++i) { - if(i == ix) { - char *t = tmp; - - for(; *n && !isspace(*n); ++t,++n) *t = *n; - *t = 0; - return *tmp?tmp:NULL; - } - else { - while(*n && !isspace(*n)) ++n; - while(*n && isspace(*n)) ++n; - } - } - - return NULL; -} - - -//! Check if object's name ends with a tilde -bool flext::chktilde(const char *objname) -{ -// int stplen = strlen(setupfun); - bool tilde = true; //!strncmp(setupfun,"_tilde",6); - - if((objname[strlen(objname)-1] == '~'?1:0)^(tilde?1:0)) { - if(tilde) - error("flext: %s (no trailing ~) is defined as a tilde object",objname); - else - error("flext::check_tilde: %s is no tilde object",objname); - return true; - } - else - return false; -} - -// this class stands for one library of objects -// there can be more if flext is a shared library -class flext_library -{ -public: - flext_library(const t_symbol *nm) - : name(nm) -#if FLEXT_SYS == FLEXT_SYS_MAX - , clss(NULL),dsp(false) -#endif - {} - - const t_symbol *name; -#if FLEXT_SYS == FLEXT_SYS_MAX - t_class *clss; - bool dsp; -#endif -}; - -// this class stands for one registered object -// it holds the class, type flags, constructor and destructor of the object and the creation arg types -// it will never be destroyed -class flext_class: - public flext_root -{ -public: - flext_class(t_class *&cl,flext_obj *(*newf)(int,t_atom *),void (*freef)(flext_hdr *)); - - t_class *const &clss; - - flext_obj *(*newfun)(int,t_atom *); - void (*freefun)(flext_hdr *c); - - int argc; - int *argv; - - flext_library *lib; - bool dsp:1,noi:1,attr:1,dist:1; - - flext_base::ItemCont meths,attrs; -}; - -flext_class::flext_class(t_class *&cl,flext_obj *(*newf)(int,t_atom *),void (*freef)(flext_hdr *)): - clss(cl), - newfun(newf),freefun(freef), - argc(0),argv(NULL) - , dist(false) -{} - -typedef TablePtrMap LibMap; -// static initialization (with constructor) doesn't work for Codewarrior -static LibMap *libnames = NULL; - -//! Store or retrieve registered classes -static flext_class *FindName(const t_symbol *s,flext_class *o = NULL) -{ - if(!libnames) libnames = new LibMap; - flext_class *cl = libnames->find(s); - if(!cl && o) - libnames->insert(s,cl = o); - return cl; -} - - -t_class *flext_obj::getClass(t_classid cl) { return cl->clss; } -bool flext_obj::HasAttributes(t_classid cl) { return cl->attr; } -bool flext_obj::IsDSP(t_classid cl) { return cl->dsp; } -bool flext_obj::HasDSPIn(t_classid cl) { return !cl->noi; } -bool flext_obj::IsLib(t_classid cl) { return cl->lib != NULL; } - -bool flext_obj::HasAttributes() const { return clss->attr; } -bool flext_obj::IsDSP() const { return clss->dsp; } -bool flext_obj::HasDSPIn() const { return !clss->noi; } -bool flext_obj::IsLib() const { return clss->lib != NULL; } - -#if FLEXT_SYS == FLEXT_SYS_MAX -bool flext_obj::NeedDSP() const { return clss->dsp || (clss->lib && clss->lib->dsp); } -#endif - -static flext_library *curlib = NULL; - -void flext_obj::lib_init(const char *name,void setupfun()) -{ - // make new library instance - curlib = new flext_library(MakeSymbol(name)); - - flext::Setup(); - - // first register all classes - try { - setupfun(); - } - catch(std::exception &x) { - error("%s - %s",name,x.what()); - return; - } - catch(char *txt) { - error("%s - %s",name,txt); - return; - } - catch(...) { - error("%s - Unknown exception at library setup",name); - return; - } - -#if FLEXT_SYS == FLEXT_SYS_MAX - // then see if we got DSP classes - - // 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 - ::setup( - (t_messlist **)&curlib->clss, - (t_newmethod)obj_new,(t_method)obj_free, - sizeof(flext_hdr),NULL,A_GIMME,A_NULL); - - // for all classes in library add methods - flext_base::AddMessageMethods(curlib->clss,curlib->dsp,true); -#endif - - curlib = NULL; -} - -void flext_obj::obj_add(bool lib,bool dsp,bool noi,bool attr,const char *idname,const char *names,void setupfun(t_classid),flext_obj *(*newfun)(int,t_atom *),void (*freefun)(flext_hdr *),int argtp1,...) -{ - // get first possible object name - const t_symbol *nsym = MakeSymbol(extract(names)); - -#ifdef FLEXT_DEBUG - if(dsp) chktilde(GetString(nsym)); -#endif - - if(lib) { - FLEXT_ASSERT(curlib); -#if FLEXT_SYS == FLEXT_SYS_MAX - curlib->dsp |= dsp; -#endif - } - else { - FLEXT_ASSERT(!curlib); -// process_attributes = attr; - } - - // set dynamic class pointer - t_class **cl = -#if FLEXT_SYS == FLEXT_SYS_MAX - lib?&curlib->clss: -#endif - new t_class *; - - // register object class -#if FLEXT_SYS == FLEXT_SYS_PD - *cl = ::class_new( - (t_symbol *)nsym, - (t_newmethod)obj_new,(t_method)obj_free, - sizeof(flext_hdr),CLASS_DEFAULT,A_GIMME,A_NULL); -#elif FLEXT_SYS == FLEXT_SYS_MAX - if(!lib) { - ::setup( - (t_messlist **)cl, - (t_newmethod)obj_new,(t_method)obj_free, - sizeof(flext_hdr),NULL,A_GIMME,A_NULL); - // attention: in Max/MSP the *cl variable is not initialized after that call. - // just the address is stored, the initialization then occurs with the first object instance! - } -#else -#error Platform not implemented -#endif - - // make new dynamic object - flext_class *lo = new flext_class(*cl,newfun,freefun); - lo->lib = curlib; - lo->dsp = dsp; - lo->noi = noi; - lo->attr = attr; - -// post("ADDCLASS %s,%s = %p -> LIBOBJ %p -> %p (lib=%i,dsp=%i)",idname,names,*cl,lo,lo->clss,lib?1:0,dsp?1:0); - - // parse the argument type list and store it with the object - if(argtp1 == FLEXTTPN_VAR) - lo->argc = -1; - else { - int argtp,i; - va_list marker; - - // parse a first time and count only - va_start(marker,argtp1); - for(argtp = argtp1; argtp != FLEXTTPN_NULL; ++lo->argc) argtp = (int)va_arg(marker,int); - va_end(marker); - - lo->argv = new int[lo->argc]; - - // now parse and store - va_start(marker,argtp1); - for(argtp = argtp1,i = 0; i < lo->argc; ++i) { - lo->argv[i] = argtp; - argtp = (int)va_arg(marker,int); - } - va_end(marker); - } - - // get unique class id - t_classid clid = lo; - - // make help reference - const char *helptxt = extract(names,-1); - if(helptxt) { - const char *sl = strchr(helptxt,'/'); - if(sl && !sl[1]) - // helptxt is only the path (path with trailing /) - flext_obj::DefineHelp(clid,idname,helptxt,dsp); - else - // helptxt is path and patch name - flext_obj::DefineHelp(clid,helptxt,NULL,dsp); - } - - for(int ix = 0; ; ++ix) { - // in this loop register all the possible aliases of the object - - const char *c = ix?extract(names,ix):GetString(nsym); - if(!c || !*c) break; - - // add to name list - const t_symbol *lsym = MakeSymbol(c); - 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) - // 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(c)); -#else -#error -#endif - } - - try { - // call class setup function - setupfun(clid); - } - catch(std::exception &x) { - error("%s: %s",idname,x.what()); - } - catch(char *txt) { - error("%s: %s",idname,txt); - } - catch(...) { - error("%s - Unknown exception while initializing class",idname); - } -} - - -#define NEWARGS 256 // must be larger than FLEXT_NEWARGS = 5 - -typedef flext_obj *(*libfun)(int,t_atom *); - -#if FLEXT_SYS == FLEXT_SYS_MAX -flext_hdr *flext_obj::obj_new(const t_symbol *s,short _argc_,t_atom *argv) -#else -flext_hdr *flext_obj::obj_new(const t_symbol *s,int _argc_,t_atom *argv) -#endif -{ - flext_hdr *obj = NULL; - flext_class *lo = FindName(s); - if(lo) { -// post("NEWOBJ %s = %p -> %p",GetString(s),lo,lo->clss); - - bool ok = true; - t_atom args[NEWARGS]; - - int argc = _argc_; - if(lo->attr) { - argc = flext_base::CheckAttrib(argc,argv); - } - - if(lo->argc >= 0) { -#ifdef FLEXT_DEBUG - if(lo->argc > FLEXT_MAXNEWARGS) { ERRINTERNAL(); ok = false; } -#endif - - int misnum = 0; - if(argc > lo->argc) { ok = false; misnum = 1; } - - for(int i = 0; ok && i < lo->argc; ++i) { - switch(lo->argv[i]) { -#if FLEXT_SYS != FLEXT_SYS_PD - case FLEXTTPN_INT: - case FLEXTTPN_DEFINT: - if(i >= argc) - if(lo->argv[i] == FLEXTTPN_DEFINT) SetInt(args[i],0); - else { misnum = -1,ok = false; break; } - else if(IsInt(argv[i])) args[i] = argv[i]; - else if(IsFloat(argv[i])) SetInt(args[i],(int)GetFloat(argv[i])); - else ok = false; - break; -#endif - case FLEXTTPN_FLOAT: - case FLEXTTPN_DEFFLOAT: - if(i >= argc) - if(lo->argv[i] == FLEXTTPN_DEFFLOAT) SetFloat(args[i],0); - else { misnum = -1,ok = false; break; } - else if(IsInt(argv[i])) SetFloat(args[i],(float)GetInt(argv[i])); - else if(IsFloat(argv[i])) args[i] = argv[i]; - else ok = false; - break; - case FLEXTTPN_SYM: - case FLEXTTPN_DEFSYM: - // \todo shall we analyze the patcher args????... should already be done! - if(i >= argc) - if(lo->argv[i] == FLEXTTPN_DEFSYM) SetSymbol(args[i],sym__); - else { misnum = -1,ok = false; break; } - else if(IsSymbol(argv[i])) -// SetSymbol(args[i],GetParamSym(GetSymbol(argv[i]),NULL)); - args[i] = argv[i]; - else ok = false; - break; - } - } - - if(!ok) - if(misnum) - error("%s: %s creation arguments",GetString(s),misnum < 0?"Not enough":"Too many"); - else - error("%s: Creation arguments do not match",GetString(s)); - } - - - if(ok) { - try { -#if FLEXT_SYS == FLEXT_SYS_PD - obj = (flext_hdr *)::pd_new(lo->clss); -#elif FLEXT_SYS == FLEXT_SYS_MAX - obj = (flext_hdr *)::newobject(lo->clss); -#else -#error -#endif - - flext_obj::m_holder = obj; - flext_obj::m_holdclass = lo; - flext_obj::m_holdname = s; - flext_obj::initing = true; - flext_obj::init_ok = true; - - // get actual flext object (newfun calls "new flext_obj()") - if(lo->argc >= 0) - obj->data = lo->newfun(lo->argc,args); - else - obj->data = lo->newfun(argc,argv); - - flext_obj::m_holder = NULL; - flext_obj::m_holdclass = NULL; - flext_obj::m_holdname = NULL; - - ok = obj->data && - // check constructor exit flag - flext_obj::init_ok; - - if(ok) { - if(lo->attr) { - // DON'T convert eventual patcher args here... this is done by the actual attribute stuff - // so that the initial $- or #- be preserved! - - // store creation args for attribute initialization (inside flext_base::Init()) - flext_obj::m_holdaargc = _argc_-argc; - flext_obj::m_holdaargv = argv+argc; - } - else { - flext_obj::m_holdaargc = 0; - flext_obj::m_holdaargv = NULL; - } - - // call virtual init function - // here, inlets, outlets, methods and attributes can be set up - ok = obj->data->Init(); - - flext_obj::initing = false; - - // call another virtual init function - if(ok) ok = obj->data->Finalize(); - - flext_obj::m_holdaargc = 0; - flext_obj::m_holdaargv = NULL; - } - - } //try - catch(std::exception &x) { - error("%s - Exception while creating object: %s",GetString(s),x.what()); - ok = false; - } - catch(char *txt) { - error("%s - Exception while creating object: %s",GetString(s),txt); - ok = false; - } - catch(...) { - error("%s - Unknown exception while creating object",GetString(s)); - ok = false; - } - - flext_obj::initing = false; - - if(!ok) { - // there was some init error, free object - lo->freefun(obj); - obj = NULL; - } - } - } -#ifdef FLEXT_DEBUG - else -#if FLEXT_SYS == FLEXT_SYS_MAX - // in Max/MSP an object with the name of the library exists, even if not explicitly declared! -// if(!lo->lib || s != lo->lib->name) -#endif - error("Class %s not found in library!",s->s_name); -#endif - - return obj; -} - -void flext_obj::obj_free(flext_hdr *h) -{ - flext_hdr *hdr = (flext_hdr *)h; - const t_symbol *name = hdr->data->thisNameSym(); - flext_class *lcl = FindName(name); - - if(lcl) { - try { - flext_obj::exiting = true; - - // call virtual exit function - hdr->data->Exit(); - - // now call object destructor and deallocate - lcl->freefun(hdr); - } //try - catch(std::exception &x) { - error("%s - Exception while destroying object: %s",GetString(name),x.what()); - } - catch(char *txt) { - error("%s - Exception while destroying object: %s",GetString(name),txt); - } - catch(...) { - error("%s - Unknown exception while destroying object",GetString(name)); - } - - flext_obj::exiting = false; - } -#ifdef FLEXT_DEBUG - else -#if FLEXT_SYS == FLEXT_SYS_MAX - // in Max/MSP an object with the name of the library exists, even if not explicitely declared! -// if(!lo->lib || s != lo->lib->name) -#endif - error("Class %s not found in library!",name); -#endif -} - - -t_class *flext_obj::thisClass() const { FLEXT_ASSERT(x_obj); return thisClassId()->clss; } - -void flext_base::SetDist(t_classid c,bool d) { c->dist = d; } -bool flext_base::DoDist() const { return thisClassId()->dist; } - -flext_base::ItemCont *flext_base::ClMeths(t_classid c) { return &c->meths; } -flext_base::ItemCont *flext_base::ClAttrs(t_classid c) { return &c->attrs; } -- cgit v1.2.1