aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/flext/source/fllib.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'externals/grill/flext/source/fllib.cpp')
-rw-r--r--externals/grill/flext/source/fllib.cpp578
1 files changed, 0 insertions, 578 deletions
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 <stdarg.h>
-#include <string.h>
-#include <ctype.h>
-#include <map>
-
-#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<const t_symbol *,flext_class *,8> 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<char *>(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; }