Commit fbf6fc6e authored by thomas's avatar thomas
Browse files

no message


git-svn-id: https://svn.grrrr.org/ext/trunk@473 4d9ac71a-51e6-0310-8455-cad1006bcd31
parent 4ddcbfba
No preview for this file type
......@@ -115,6 +115,7 @@ Version history:
0.4.1:
- full port for Max@OSX
- completely redesigned message and attribute handling: now hashed and much more efficient
- greatly enhanced object creation and destruction (esp. for library objects)
- added some prerequisites for usage of flext as a shared library
- completed Max/MSPs inlet/outlet assist description functionality
- Max/MSP signal objects: fixed bug of reporting wrong number of inlets
......
......@@ -88,7 +88,7 @@ void flext_base::AddAttrib(const char *attr,metharg tp,methfun gfun,methfun sfun
error("%s - attribute procession is not enabled!",thisName());
}
void flext_base::AddAttrib(t_class *c,const char *attr,metharg tp,methfun gfun,methfun sfun)
void flext_base::AddAttrib(t_classid c,const char *attr,metharg tp,methfun gfun,methfun sfun)
{
AddAttrib(ClAttrs(c),ClMeths(c),attr,tp,gfun,sfun);
}
......
......@@ -145,12 +145,25 @@ class FLEXT_SHARE flext_obj:
//! Get the class name (as a symbol)
const t_symbol *thisNameSym() const { return m_name; }
#if FLEXT_SYS == FLEXT_SYS_PD
//! Get the class pointer
t_class *thisClass() { return (t_class *)((t_object *)(x_obj))->te_g.g_pd; }
typedef t_class *t_classid;
//! Get unique id for object class
t_classid thisClassId() const { void *p = thisClass(); return reinterpret_cast<unsigned long>(p); }
//! Get class pointer from class id
static t_class *getClass(t_classid c) { return c; }
#elif FLEXT_SYS == FLEXT_SYS_MAX
//! Get the class pointer
t_class *thisClass() { return (t_class *)(((t_tinyobject *)x_obj)->t_messlist-1); }
typedef void *t_classid;
//! Get unique id for object class (for Max/MSP library object share the same (t_class *)!)
t_classid thisClassId() const; // { return classid; }
//! Get class pointer from class id
static t_class *getClass(t_classid);
#endif
//! @} FLEXT_O_INFO
......@@ -201,7 +214,7 @@ class FLEXT_SHARE flext_obj:
public:
//! Creation callback
static void __setup__(t_class *) { flext::Setup(); }
static void __setup__(t_classid) { flext::Setup(); }
/*! \brief This is a temporary holder
\warning don't touch it!
......@@ -223,7 +236,7 @@ class FLEXT_SHARE flext_obj:
// Definitions for library objects
static void lib_init(const char *name,void setupfun(),bool attr);
static void obj_add(bool lib,bool dsp,bool attr,const char *idname,const char *names,void setupfun(t_class *),flext_obj *(*newfun)(int,t_atom *),void (*freefun)(flext_hdr *),int argtp1,...);
static void obj_add(bool lib,bool dsp,bool attr,const char *idname,const char *names,void setupfun(t_classid),flext_obj *(*newfun)(int,t_atom *),void (*freefun)(flext_hdr *),int argtp1,...);
static flext_hdr *obj_new(const t_symbol *s,int argc,t_atom *argv);
static void obj_free(flext_hdr *o);
......@@ -272,8 +285,8 @@ static flext_obj *__init__(int argc,t_atom *argv); \
static void __free__(flext_hdr *hdr) \
{ flext_obj *mydata = hdr->data; delete mydata; \
hdr->flext_hdr::~flext_hdr(); } \
static void __setup__(t_class *classPtr) { \
PARENT_CLASS::__setup__(classPtr); } \
static void __setup__(t_classid classid) { \
PARENT_CLASS::__setup__(classid); } \
protected: \
static inline NEW_CLASS *thisObject(void *c) { return FLEXT_CAST<NEW_CLASS *>(((flext_hdr *)c)->data); }
......@@ -285,9 +298,9 @@ static flext_obj *__init__(int argc,t_atom *argv); \
static void __free__(flext_hdr *hdr) \
{ flext_obj *mydata = hdr->data; delete mydata; \
hdr->flext_hdr::~flext_hdr(); } \
static void __setup__(t_class *classPtr) \
{ PARENT_CLASS::__setup__(classPtr); \
NEW_CLASS::SETUPFUN(classPtr); } \
static void __setup__(t_classid classid) \
{ PARENT_CLASS::__setup__(classid); \
NEW_CLASS::SETUPFUN(classid); } \
protected: \
static inline NEW_CLASS *thisObject(void *c) { return FLEXT_CAST<NEW_CLASS *>(((flext_hdr *)c)->data); }
......
......@@ -350,33 +350,33 @@ public:
@{
*/
static void AddMethod(t_class *c,int inlet,bool (*m)(flext_base *,int,t_atom *)) { AddMethod(ClMeths(c),inlet,"list",(methfun)m,a_list,a_null); }
static void AddMethod(t_class *c,int inlet,bool (*m)(flext_base *,int,const t_atom *)) { AddMethod(ClMeths(c),inlet,"list",(methfun)m,a_list,a_null); }
static void AddMethod(t_class *c,int inlet,const char *tag,bool (*m)(flext_base *)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_null); } // pure method
static void AddMethod(t_class *c,int inlet,bool (*m)(flext_base *,t_symbol *,int,t_atom *)) { AddMethod(ClMeths(c),inlet,"anything",(methfun)m,a_any,a_null); } // anything
static void AddMethod(t_class *c,int inlet,bool (*m)(flext_base *,const t_symbol *,int,const t_atom *)) { AddMethod(ClMeths(c),inlet,"anything",(methfun)m,a_any,a_null); } // anything
static void AddMethod(t_class *c,int inlet,bool (*m)(flext_base *,t_symbol *&)) { AddMethod(ClMeths(c),inlet,"symbol",(methfun)m,a_symbol,a_null); } // single symbol
static void AddMethod(t_class *c,int inlet,bool (*m)(flext_base *,const t_symbol *&)) { AddMethod(ClMeths(c),inlet,"symbol",(methfun)m,a_symbol,a_null); } // single symbol
static void AddMethod(t_class *c,int inlet,bool (*m)(flext_base *,float &)) { AddMethod(ClMeths(c),inlet,"float",(methfun)m,a_float,a_null); } // single float
static void AddMethod(t_class *c,int inlet,bool (*m)(flext_base *,float &,float &)) { AddMethod(ClMeths(c),inlet,"list",(methfun)m,a_float,a_float,a_null); } // list of 2 floats
static void AddMethod(t_class *c,int inlet,bool (*m)(flext_base *,float &,float &,float &)) { AddMethod(ClMeths(c),inlet,"list",(methfun)m,a_float,a_float,a_float,a_null); } // list of 3 floats
static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,int,t_atom *)) { AddMethod(ClMeths(c),inlet,"list",(methfun)m,a_list,a_null); }
static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,int,const t_atom *)) { AddMethod(ClMeths(c),inlet,"list",(methfun)m,a_list,a_null); }
static void AddMethod(t_classid c,int inlet,const char *tag,bool (*m)(flext_base *)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_null); } // pure method
static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,t_symbol *,int,t_atom *)) { AddMethod(ClMeths(c),inlet,"anything",(methfun)m,a_any,a_null); } // anything
static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,const t_symbol *,int,const t_atom *)) { AddMethod(ClMeths(c),inlet,"anything",(methfun)m,a_any,a_null); } // anything
static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,t_symbol *&)) { AddMethod(ClMeths(c),inlet,"symbol",(methfun)m,a_symbol,a_null); } // single symbol
static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,const t_symbol *&)) { AddMethod(ClMeths(c),inlet,"symbol",(methfun)m,a_symbol,a_null); } // single symbol
static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,float &)) { AddMethod(ClMeths(c),inlet,"float",(methfun)m,a_float,a_null); } // single float
static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,float &,float &)) { AddMethod(ClMeths(c),inlet,"list",(methfun)m,a_float,a_float,a_null); } // list of 2 floats
static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,float &,float &,float &)) { AddMethod(ClMeths(c),inlet,"list",(methfun)m,a_float,a_float,a_float,a_null); } // list of 3 floats
#if FLEXT_SYS == FLEXT_SYS_PD
static void AddMethod(t_class *c,int inlet,bool (*m)(flext_base *,int &)) { AddMethod(ClMeths(c),inlet,"float",(methfun)m,a_int,a_null); } // single float
static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,int &)) { AddMethod(ClMeths(c),inlet,"float",(methfun)m,a_int,a_null); } // single float
#elif FLEXT_SYS == FLEXT_SYS_MAX
static void AddMethod(t_class *c,int inlet,bool (*m)(flext_base *,int &)) { AddMethod(ClMeths(c),inlet,"int",(methfun)m,a_int,a_null); } // single float
static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,int &)) { AddMethod(ClMeths(c),inlet,"int",(methfun)m,a_int,a_null); } // single float
#else
#error
#endif
static void AddMethod(t_class *c,int inlet,bool (*m)(flext_base *,int &,int &)) { AddMethod(ClMeths(c),inlet,"list",(methfun)m,a_int,a_int,a_null); } // list of 2 floats
static void AddMethod(t_class *c,int inlet,bool (*m)(flext_base *,int &,int &,int &)) { AddMethod(ClMeths(c),inlet,"list",(methfun)m,a_int,a_int,a_int,a_null); } // list of 3 floats
static void AddMethod(t_class *c,int inlet,const char *tag,bool (*m)(flext_base *,int,t_atom *)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_list,a_null); } // method+gimme
static void AddMethod(t_class *c,int inlet,const char *tag,bool (*m)(flext_base *,int,const t_atom *)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_list,a_null); } // method+gimme
static void AddMethod(t_class *c,int inlet,const char *tag,bool (*m)(flext_base *,t_symbol *,int,t_atom *)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_any,a_null); } // method+gimme
static void AddMethod(t_class *c,int inlet,const char *tag,bool (*m)(flext_base *,const t_symbol *,int,const t_atom *)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_any,a_null); } // method+gimme
static void AddMethod(t_class *c,int inlet,const char *tag,bool (*m)(flext_base *,t_symbol *&)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_symbol,a_null); } // method+symbol
static void AddMethod(t_class *c,int inlet,const char *tag,bool (*m)(flext_base *,const t_symbol *&)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_symbol,a_null); } // method+symbol
static void AddMethod(t_class *c,int inlet,const char *tag,bool (*m)(flext_base *,float &)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_float,a_null); } // method+float
static void AddMethod(t_class *c,int inlet,const char *tag,bool (*m)(flext_base *,int &)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_int,a_null); } // method+int
static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,int &,int &)) { AddMethod(ClMeths(c),inlet,"list",(methfun)m,a_int,a_int,a_null); } // list of 2 floats
static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,int &,int &,int &)) { AddMethod(ClMeths(c),inlet,"list",(methfun)m,a_int,a_int,a_int,a_null); } // list of 3 floats
static void AddMethod(t_classid c,int inlet,const char *tag,bool (*m)(flext_base *,int,t_atom *)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_list,a_null); } // method+gimme
static void AddMethod(t_classid c,int inlet,const char *tag,bool (*m)(flext_base *,int,const t_atom *)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_list,a_null); } // method+gimme
static void AddMethod(t_classid c,int inlet,const char *tag,bool (*m)(flext_base *,t_symbol *,int,t_atom *)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_any,a_null); } // method+gimme
static void AddMethod(t_classid c,int inlet,const char *tag,bool (*m)(flext_base *,const t_symbol *,int,const t_atom *)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_any,a_null); } // method+gimme
static void AddMethod(t_classid c,int inlet,const char *tag,bool (*m)(flext_base *,t_symbol *&)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_symbol,a_null); } // method+symbol
static void AddMethod(t_classid c,int inlet,const char *tag,bool (*m)(flext_base *,const t_symbol *&)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_symbol,a_null); } // method+symbol
static void AddMethod(t_classid c,int inlet,const char *tag,bool (*m)(flext_base *,float &)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_float,a_null); } // method+float
static void AddMethod(t_classid c,int inlet,const char *tag,bool (*m)(flext_base *,int &)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_int,a_null); } // method+int
//! @} FLEXT_C_CADDMETHOD
......@@ -482,12 +482,12 @@ protected:
@{
*/
static void AddAttrib(t_class *c,const char *attr,bool (*get)(flext_base *,float &),bool (*set)(flext_base *,float &)) { AddAttrib(c,attr,a_float,(methfun)get,(methfun)set); }
static void AddAttrib(t_class *c,const char *attr,bool (*get)(flext_base *,int &),bool (*set)(flext_base *,int &)) { AddAttrib(c,attr,a_int,(methfun)get,(methfun)set); }
static void AddAttrib(t_class *c,const char *attr,bool (*get)(flext_base *,const t_symbol *&),bool (*set)(flext_base *,const t_symbol *&)) { AddAttrib(c,attr,a_symbol,(methfun)get,(methfun)set); }
static void AddAttrib(t_class *c,const char *attr,bool (*get)(flext_base *,t_symbol *&),bool (*set)(flext_base *,t_symbol *&)) { AddAttrib(c,attr,a_symbol,(methfun)get,(methfun)set); }
static void AddAttrib(t_class *c,const char *attr,bool (*get)(flext_base *,AtomList *&),bool (*set)(flext_base *,AtomList *&)) { AddAttrib(c,attr,a_LIST,(methfun)get,(methfun)set); }
static void AddAttrib(t_class *c,const char *attr,bool (*get)(flext_base *,AtomAnything *&),bool (*set)(flext_base *,AtomAnything *&)) { AddAttrib(c,attr,a_ANY,(methfun)get,(methfun)set); }
static void AddAttrib(t_classid c,const char *attr,bool (*get)(flext_base *,float &),bool (*set)(flext_base *,float &)) { AddAttrib(c,attr,a_float,(methfun)get,(methfun)set); }
static void AddAttrib(t_classid c,const char *attr,bool (*get)(flext_base *,int &),bool (*set)(flext_base *,int &)) { AddAttrib(c,attr,a_int,(methfun)get,(methfun)set); }
static void AddAttrib(t_classid c,const char *attr,bool (*get)(flext_base *,const t_symbol *&),bool (*set)(flext_base *,const t_symbol *&)) { AddAttrib(c,attr,a_symbol,(methfun)get,(methfun)set); }
static void AddAttrib(t_classid c,const char *attr,bool (*get)(flext_base *,t_symbol *&),bool (*set)(flext_base *,t_symbol *&)) { AddAttrib(c,attr,a_symbol,(methfun)get,(methfun)set); }
static void AddAttrib(t_classid c,const char *attr,bool (*get)(flext_base *,AtomList *&),bool (*set)(flext_base *,AtomList *&)) { AddAttrib(c,attr,a_LIST,(methfun)get,(methfun)set); }
static void AddAttrib(t_classid c,const char *attr,bool (*get)(flext_base *,AtomAnything *&),bool (*set)(flext_base *,AtomAnything *&)) { AddAttrib(c,attr,a_ANY,(methfun)get,(methfun)set); }
//! @} FLEXT_C_CATTR
......@@ -601,20 +601,20 @@ protected:
//! @} FLEXT_CLASS
itemarr *ThMeths() { return methhead; }
static itemarr *ClMeths(t_class *c) { return GetClassArr(c,0); }
static itemarr *ClMeths(t_classid c) { return GetClassArr(c,0); }
static void AddMethod(itemarr *ma,int inlet,const char *tag,methfun fun,metharg tp,...);
itemarr *ThAttrs() { return attrhead; }
static itemarr *ClAttrs(t_class *c) { return GetClassArr(c,1); }
static itemarr *ClAttrs(t_classid c) { return GetClassArr(c,1); }
static void AddAttrib(itemarr *aa,itemarr *ma,const char *attr,metharg tp,methfun gfun,methfun sfun);
void AddAttrib(const char *attr,metharg tp,methfun gfun,methfun sfun);
static void AddAttrib(t_class *c,const char *attr,metharg tp,methfun gfun,methfun sfun);
static void AddAttrib(t_classid c,const char *attr,metharg tp,methfun gfun,methfun sfun);
private:
static void Setup(t_class *c);
static void Setup(t_classid c);
xlet *inlist,*outlist;
const t_symbol *curtag;
......@@ -644,7 +644,7 @@ private:
typedef bool (*methfun_4)(flext_base *c,t_any &,t_any &,t_any &,t_any &);
typedef bool (*methfun_5)(flext_base *c,t_any &,t_any &,t_any &,t_any &,t_any &);
static itemarr *GetClassArr(t_class *c,int ix);
static itemarr *GetClassArr(t_classid,int ix);
itemarr *methhead,*clmethhead;
......@@ -663,14 +663,11 @@ private:
bool InitAttrib(int argc,const t_atom *argv);
bool ListAttrib();
// bool GetAttrib(const t_symbol *s);
bool GetAttrib(attritem *a);
bool SetAttrib(const t_symbol *s,int argc,const t_atom *argv);
bool SetAttrib(attritem *a,int argc,const t_atom *argv);
static bool cb_ListAttrib(flext_base *c) { return c->ListAttrib(); }
// static bool cb_GetAttrib(flext_base *c,const t_symbol *s,int argc,const t_atom *argv) { return c->GetAttrib(s,argc,argv); }
// static bool cb_SetAttrib(flext_base *c,const t_symbol *s,int argc,const t_atom *argv) { return c->SetAttrib(s,argc,argv); }
// queue stuff
......
......@@ -20,8 +20,10 @@ WARRANTIES, see the file, "license.txt," in this distribution.
// === flext_dsp ==============================================
void flext_dsp::Setup(t_class *c)
void flext_dsp::Setup(t_classid id)
{
t_class *c = getClass(id);
#if FLEXT_SYS == FLEXT_SYS_MAX
// dsp_initclass();
dsp_initboxclass();
......
......@@ -137,7 +137,7 @@ private:
int chnsin,chnsout;
// setup function
static void Setup(t_class *c);
static void Setup(t_classid c);
// callback functions
......
......@@ -27,8 +27,8 @@ flext_base::flext_base():
insigs(0),outsigs(0),
outlets(NULL),outattr(NULL),
distmsgs(false),
methhead(new itemarr),attrhead(new itemarr), //attrcnt(0),
clmethhead(ClMeths(thisClass())),clattrhead(ClAttrs(thisClass())),
methhead(new itemarr),attrhead(new itemarr),
clmethhead(ClMeths(thisClassId())),clattrhead(ClAttrs(thisClassId())),
inlets(NULL)
#if FLEXT_SYS == FLEXT_SYS_MAX
,indesc(NULL),outdesc(NULL)
......@@ -125,8 +125,10 @@ bool flext_base::Init()
/*! Set up proxy classes and basic methods at class creation time
This ensures that they are processed before the registered flext messages
*/
void flext_base::Setup(t_class *c)
void flext_base::Setup(t_classid id)
{
t_class *c = getClass(id);
add_method(c,cb_help,"help");
add_loadbang(c,cb_loadbang);
#if FLEXT_SYS == FLEXT_SYS_MAX
......
......@@ -26,7 +26,7 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#define FLEXT_VERSION 401
//! \brief flext version string
#define FLEXT_VERSTR "0.4.1pre"
#define FLEXT_VERSTR "0.4.1"
//! @}
......
......@@ -30,10 +30,12 @@ flext_base::itemarr::itemarr():
arr(new item *[2]),cnt(0),bits(-1)
{
arr[0] = arr[1] = NULL;
// post("NEWARR %p",this);
}
flext_base::itemarr::~itemarr()
{
// post("DELARR %p",this);
int c = Ready()?Size():2;
for(int i = 0; i < c; ++i)
......@@ -54,9 +56,11 @@ void flext_base::itemarr::Add(item *it)
a->nxt = it;
}
else arr[ix] = it;
// post("RDY inlet=%i,tag=%s,hash=%i",it->inlet,GetString(it->tag),ix);
}
else {
// post("ADD %i,%s",it->inlet,GetString(it->tag));
// 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;
......@@ -70,6 +74,8 @@ void flext_base::itemarr::Finalize()
{
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
......@@ -85,20 +91,6 @@ void flext_base::itemarr::Finalize()
l->nxt = NULL;
Add(l);
/*
// retrieve array index
int ix = Hash(l->tag,l->inlet,bits);
// post("ADD %i,%s -> index %i",l->inlet,GetString(l->tag),ix);
// add to array slot
if(arr[ix]) {
item *a = arr[ix];
while(a->nxt) a = a->nxt;
a->nxt = l;
}
else arr[ix] = l;
*/
}
#if 0
......@@ -126,9 +118,11 @@ flext_base::item *flext_base::itemarr::Find(const t_symbol *tag,int inlet) const
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;
......@@ -148,23 +142,23 @@ class _itemarr
public:
enum { HASHBITS=7, HASHSIZE=1<<HASHBITS };
_itemarr(t_class *c,int i);
_itemarr(flext_obj::t_classid c,int i);
~_itemarr(); // will never be called
static int Hash(t_class *c,int ix);
static int Hash(flext_obj::t_classid c,int ix);
int Hash() const { return Hash(cl,ix); }
int Hash() const { return Hash(clid,ix); }
void Add(_itemarr *a);
t_class *cl;
flext_obj::t_classid clid;
int ix;
flext_base::itemarr *arr;
_itemarr *nxt;
};
_itemarr::_itemarr(t_class *c,int i):
cl(c),ix(i),
_itemarr::_itemarr(flext_obj::t_classid c,int i):
clid(c),ix(i),
arr(new flext_base::itemarr),
nxt(NULL)
{}
......@@ -175,7 +169,7 @@ void _itemarr::Add(_itemarr *a)
else nxt = a;
}
int _itemarr::Hash(t_class *c,int ix)
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);
......@@ -183,7 +177,7 @@ int _itemarr::Hash(t_class *c,int ix)
static _itemarr **_arrs = NULL;
flext_base::itemarr *flext_base::GetClassArr(t_class *c,int ix)
flext_base::itemarr *flext_base::GetClassArr(t_classid c,int ix)
{
if(!_arrs) {
_arrs = new _itemarr *[_itemarr::HASHSIZE];
......@@ -193,7 +187,9 @@ flext_base::itemarr *flext_base::GetClassArr(t_class *c,int ix)
int hash = _itemarr::Hash(c,ix);
_itemarr *a = _arrs[hash];
_itemarr *pa = NULL;
while(a && (a->cl != c || a->ix != ix)) pa = a,a = a->nxt;
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);
......
......@@ -123,41 +123,70 @@ libobject::libobject(t_class *&cl,flext_obj *(*newf)(int,t_atom *),void (*freef)
// it will never be destroyed
class libname {
public:
libname(const t_symbol *n,libobject *o): name(n),obj(o),nxt(NULL) {}
const t_symbol *name;
libobject *obj;
static void add(libname *n);
static libname *find(const t_symbol *s);
static libname *Find(const t_symbol *s,libobject *o = NULL);
protected:
libname(const t_symbol *n,libobject *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 addrec(libname *n);
static libname *root;
void Add(libname *n);
static libname **root;
};
void libname::addrec(libname *n) { if(nxt) nxt->addrec(n); else nxt = n; }
libname **libname::root = NULL;
libname *libname::root = NULL;
void libname::Add(libname *n) { if(nxt) nxt->Add(n); else nxt = n; }
void libname::add(libname *l) {
if(root) root->addrec(l);
else root = l;
int libname::Hash(const t_symbol *s)
{
return flext::FoldBits(reinterpret_cast<unsigned long>(s),HASHBITS);
}
libname *libname::find(const t_symbol *s) {
libname *l;
for(l = root; l; l = l->nxt)
if(s == l->name) break;
return l;
libname *libname::Find(const t_symbol *s,libobject *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;
}
// 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
#if FLEXT_SYS == FLEXT_SYS_MAX
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; }
t_class *flext_obj::getClass(t_classid id) { return reinterpret_cast<libobject *>(id)->clss; }
#endif
void flext_obj::lib_init(const char *name,void setupfun(),bool attr)
......@@ -173,7 +202,7 @@ void flext_obj::lib_init(const char *name,void setupfun(),bool attr)
setupfun();
}
void flext_obj::obj_add(bool lib,bool dsp,bool attr,const char *idname,const char *names,void setupfun(t_class *),flext_obj *(*newfun)(int,t_atom *),void (*freefun)(flext_hdr *),int argtp1,...)
void flext_obj::obj_add(bool lib,bool dsp,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));
......@@ -203,6 +232,8 @@ void flext_obj::obj_add(bool lib,bool dsp,bool attr,const char *idname,const cha
(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
......@@ -214,6 +245,8 @@ void flext_obj::obj_add(bool lib,bool dsp,bool attr,const char *idname,const cha
lo->dsp = dsp;
lo->attr = process_attributes;
// post("ADDCLASS %p -> LIBOBJ %p -> %p",*cl,lo,lo->clss);
// parse the argument type list and store it with the object
if(argtp1 == A_GIMME)
lo->argc = -1;
......@@ -247,8 +280,7 @@ 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 = new libname(MakeSymbol(c),lo);
libname::add(l);
libname *l = libname::Find(MakeSymbol(c),lo);
#if FLEXT_SYS == FLEXT_SYS_PD
if(ix > 0)
......@@ -264,8 +296,16 @@ void flext_obj::obj_add(bool lib,bool dsp,bool attr,const char *idname,const cha
#endif
}
// get unique class id
#if FLEXT_SYS == FLEXT_SYS_PD
t_classid clid = lo->clss;
#else
// in Max/MSP the t_class *value can't be used because it's possible that's it's not yet set!!
t_classid clid = lo;
#endif
// call class setup function
setupfun(lo->clss);
setupfun(clid);
}
......@@ -274,7 +314,7 @@ typedef flext_obj *(*libfun)(int,t_atom *);
flext_hdr *flext_obj::obj_new(const t_symbol *s,int _argc_,t_atom *argv)
{
flext_hdr *obj = NULL;
libname *l = libname::find(s);
libname *l = libname::Find(s);
if(l) {
bool ok = true;
t_atom args[FLEXT_MAXNEWARGS];
......@@ -322,13 +362,19 @@ flext_hdr *flext_obj::obj_new(const t_symbol *s,int _argc_,t_atom *argv)
}
if(ok) {
t_classid clid;
#if FLEXT_SYS == FLEXT_SYS_PD
clid = lo->clss;
obj = (flext_hdr *)::pd_new(lo->clss);
#elif FLEXT_SYS == FLEXT_SYS_MAX
clid = lo;
obj = (flext_hdr *)::newobject(lo->clss);
#else
#error
#endif
// post("NEWINST CLID %p",clid);
flext_obj::m_holder = obj;
flext_obj::m_holdname = l->name;
flext_obj::m_holdattr = lo->attr;
......@@ -386,7 +432,7 @@ flext_hdr *flext_obj::obj_new(const t_symbol *s,int _argc_,t_atom *argv)
void flext_obj::obj_free(flext_hdr *hdr)
{
const t_symbol *name = hdr->data->thisNameSym();
libname *l = libname::find(name);
libname *l = libname::Find(name);
if(l) {
// call virtual exit function
......
......@@ -159,7 +159,7 @@ bool flext_base::m_methodmain(int inlet,const t_symbol *s,int argc,const t_atom