Commit edde48d1 authored by thomas's avatar thomas
Browse files

no message


git-svn-id: https://svn.grrrr.org/ext/trunk@323 4d9ac71a-51e6-0310-8455-cad1006bcd31
parent 06ab353e
......@@ -55,8 +55,8 @@ OBJPATH=sd
# ----------------------------------------------
# all the source files from the package
SRCS=flbase.cpp flext.cpp flbuf.cpp fldsp.cpp fllib.cpp flxlet.cpp flsetup.cpp flutil.cpp flatom.cpp flthr.cpp
HDRS=flstdc.h flbase.h flclass.h fldefs.h flext.h flthr.h fldsp.h flinternal.h
SRCS=flbase.cpp flext.cpp flbuf.cpp fldsp.cpp fllib.cpp flxlet.cpp flsetup.cpp flsupport.cpp flattr.cpp flutil.cpp flatom.cpp flthr.cpp
HDRS=flstdc.h flbase.h flclass.h fldefs.h flext.h flthr.h fldsp.h flsupport.h flinternal.h
IHDRS=
!ifdef SNDOBJ
......
......@@ -35,8 +35,8 @@ CFLAGS=-6 -O2 -OS -ff -tWD
# ----------------------------------------------
# all the source files from the package
SRCS=flbase.cpp flext.cpp flbuf.cpp fldsp.cpp fllib.cpp flxlet.cpp flsetup.cpp flutil.cpp flatom.cpp
HDRS=flstdc.h flbase.h flclass.h fldefs.h flext.h flinternal.h
SRCS=flbase.cpp flext.cpp flbuf.cpp fldsp.cpp fllib.cpp flxlet.cpp flattr.cpp flsupport.cpp flsetup.cpp flutil.cpp flatom.cpp
HDRS=flstdc.h flbase.h flclass.h fldefs.h flext.h flsupport.h flinternal.h
IHDRS=
!ifdef SNDOBJ
......
......@@ -31,8 +31,8 @@ INSTDIR=$(PDPATH)/flext
NAME=flext
# all the source files from the package
SRCS=flbase.cpp flext.cpp flbuf.cpp fldsp.cpp fllib.cpp flxlet.cpp flsetup.cpp flutil.cpp flatom.cpp flthr.cpp
HDRS=flstdc.h flbase.h flclass.h fldefs.h flext.h fldsp.h flthr.h flinternal.h
SRCS=flbase.cpp flext.cpp flbuf.cpp fldsp.cpp fllib.cpp flxlet.cpp flattr.cpp flsupport.cpp flsetup.cpp flutil.cpp flatom.cpp flthr.cpp
HDRS=flstdc.h flbase.h flclass.h fldefs.h flext.h fldsp.h flthr.h flsupport.h flinternal.h
IHDRS=
ifdef SNDOBJ
......
......@@ -26,9 +26,9 @@ LIBS=
NAME=flext
# all the source files from the package
SRCS=flbase.cpp flext.cpp flbuf.cpp fldsp.cpp fllib.cpp flxlet.cpp flsetup.cpp \
SRCS=flbase.cpp flext.cpp flbuf.cpp fldsp.cpp fllib.cpp flxlet.cpp flattr.cpp flsupport.cpp flsetup.cpp \
flutil.cpp flatom.cpp flthr.cpp
HDRS=flstdc.h flbase.h flclass.h fldefs.h flext.h flthr.h fldsp.h flinternal.h
HDRS=flstdc.h flbase.h flclass.h fldefs.h flext.h flthr.h flsupport.h fldsp.h flinternal.h
IHDRS=
ifdef SNDOBJ
......
......@@ -25,9 +25,9 @@ LIBS=
NAME=flext
# all the source files from the package
SRCS=flbase.cpp flext.cpp flbuf.cpp fldsp.cpp fllib.cpp flxlet.cpp flsetup.cpp \
SRCS=flbase.cpp flext.cpp flbuf.cpp fldsp.cpp fllib.cpp flxlet.cpp flattr.cpp flsupport.cpp flsetup.cpp \
flutil.cpp flatom.cpp flthr.cpp
HDRS=flstdc.h flbase.h flclass.h fldefs.h flext.h flthr.h fldsp.h flinternal.h
HDRS=flstdc.h flbase.h flclass.h fldefs.h flext.h flthr.h flsupport.h fldsp.h flinternal.h
IHDRS=
ifdef SNDOBJ
......
......@@ -20,10 +20,11 @@ Package files:
- flclass.h,flext.cpp: actual base classes for message (flext_base) and dsp (flext_dsp) processing
- fldsp.h,fldsp.cpp: code for signal externals
- flthr.h,flthr.cpp: code for threaded methods
- flsupport.h: various flext support functions and classes
- flsupport.h,flsupport.cpp: various flext support functions and classes
- flatom.cpp: code for functions dealing with lists of atoms
- flutil.cpp: additional utility functions
- flxlet.cpp: code for variable inlet/outlet stuff
- flattr.cpp: code for attribute stuff
- flinternals.h: internal definitions for flext library
- flbuf.cpp: buffer object handling for base classes
- fllib.cpp: code for handling external libraries in MaxMSP
......@@ -73,7 +74,6 @@ cons:
- introduces a small overhead to speed of message handling
- overhead in object size (due to possibly unneeded code)
see flext.h, fldefs.h and flclass.h for the documented base definitions and classes
----------------------------------------------------------------------------
......@@ -81,8 +81,13 @@ see flext.h, fldefs.h and flclass.h for the documented base definitions and clas
Version history:
0.4.0:
- introduced a flext namespace instead of using numerous static class functions (better isolation of functions, easier usage of flext functions outside inherited flext classes)
- completely redesigned class and object setup -> all argument checking is now handled by flext
- introduced Max/Jitter-like attribute functionality ("@value" command line, "getvalue" get and "value" set functions)
- introduced a flext static class for general flext functions (to clean up the flext_base class)
- creation argument handling is now done by flext
no more weird PD re-ordering of arguments
- calling SetupInOut() has become obsolete - flext creates all inlets/outlets by itself at the right time
- completely redesigned FLEXT_NEW macros, usage of dynamic classes (in fllib.cpp)
- added ToQueue* functions - like ToOut* but messages or not directly sent (well suited for deadlock situations)
- added OSX/darwin support (originally done by Adam T. Lindsay)
- SndObj interface now also available for cygwin and BCC
- added prepend and append functions to AtomList class
......@@ -91,6 +96,7 @@ Version history:
0.3.3:
- PD: fixed bug for DSP objects having no signal inlets
this also enables floats into a non-signal leftmost inlet
- revisited priority stuff for detached threads
- Bind/unbind functions for flext classes (in MaxMSP only one object can be bound)
- made "t_symtype" another synonym for "t_symbol *"
......@@ -209,17 +215,14 @@ Notes:
Platform specific:
- PD does not allow signal and message to go into the same inlet
- PD doesn't allow a signal object to receive float messages in the leftmost inlet... these are converted to a static signal
- PD needs all t_symbol or pointer args before float args -> you have to use variable argument lists in that case
Restrictions in compatibility mode:
- Max allows only 9 float/int inlets
- Max allows only 3 type-checked creation arguments -> use variable argument lists for more
Porting to new compilers/platforms:
- enums must be int-sized
- compiler must support bool type
- no need of C++ exceptions or RTTI
- no need of C++ exceptions or RTTI (RTTI only for GUI objects)
----------------------------------------------------------------------------
......@@ -228,8 +231,6 @@ TODO list:
general:
- documentation
- add log messages for debugging version
- exchange more preprocessor definitions for C++ base class code (esp. pd and max calls)
- should we use a namespace?
- where to put flext source/lib in linux: /usr/local/lib,/usr/local/include ?
- clean up headers (eliminate flstdc.h?)
- check that SetupInOut is only called once
......@@ -246,8 +247,8 @@ tests:
- PD: figure out what "pointer" messages do and where they occur
- some more mutexes needed for thread safety?
- buffer resize: flext_base::buffer::Frames(): should we use buffer or system sample rate?
- PD: test argument order (t_symbol, pointers before floats)
- what about FLEXT_ADDMETHOD_V (for var arg lists) and FLEXT_ADDMETHOD_A (anythings)... nonsense?
- queued messages... triggering timer should not be necessary for MaxMSP qmsg
features:
- abstraction for clock functions
......
......@@ -39,12 +39,11 @@ void flext_base::AddAttrItem(attritem *m)
void flext_base::AddAttrib(const char *attr,metharg tp,methfun gfun,methfun sfun)
{
/*
if(incnt) {
post("%s - Attributes must be defined prior to SetupInOut()",thisName());
if(!procattr) {
error("%s - Attribute processing is not enabled",thisName());
return;
}
*/
char tmp[1024];
sprintf(tmp,"get%s",attr);
AddAttrItem(new attritem(MakeSymbol(attr),MakeSymbol(tmp),tp,gfun,sfun));
......@@ -62,135 +61,116 @@ void flext_base::AddAttrib(const char *attr,metharg tp,methfun gfun,methfun sfun
bool flext_base::ListAttrib()
{
if(outattr) {
AtomList la(attrcnt);
attritem *a = attrhead;
for(int i = 0; i < attrcnt; ++i,a = a->nxt) SetSymbol(la[i],a->tag);
AtomList la(attrcnt);
attritem *a = attrhead;
for(int i = 0; i < attrcnt; ++i,a = a->nxt) SetSymbol(la[i],a->tag);
ToOutAnything(outattr,thisTag(),la.Count(),la.Atoms());
return true;
}
else return false;
ToOutAnything(outattr,thisTag(),la.Count(),la.Atoms());
return true;
}
bool flext_base::cb_NoGetAttrib(flext_base *c,const t_symbol *tag,int argc,const t_atom *argv)
{
if(c->outattr) {
post("%s - attribute %s has no get method",c->thisName(),GetString(tag));
return true;
}
else
return false;
post("%s - attribute %s has no get method",c->thisName(),GetString(tag));
return true;
}
bool flext_base::cb_NoSetAttrib(flext_base *c,const t_symbol *tag,int argc,const t_atom *argv)
{
if(c->outattr) {
post("%s - attribute %s has no set method",c->thisName(),GetString(tag));
return true;
}
else
return false;
post("%s - attribute %s has no set method",c->thisName(),GetString(tag));
return true;
}
bool flext_base::SetAttrib(const t_symbol *tag,int argc,const t_atom *argv)
{
if(outattr) {
attritem *a = attrhead;
for(; a && a->tag != tag; a = a->nxt) {}
if(a) {
bool ok = true;
AtomList la;
t_any any;
switch(a->argtp) {
case a_float:
if(argc == 1 && CanbeFloat(argv[0])) {
any.ft = GetAFloat(argv[0]);
((methfun_1)a->gfun)(this,any);
}
else ok = false;
break;
case a_int:
if(argc == 1 && CanbeInt(argv[0])) {
any.it = GetAInt(argv[0]);
((methfun_1)a->gfun)(this,any);
}
else ok = false;
break;
case a_symbol:
if(argc == 1 && IsSymbol(argv[0])) {
any.st = GetSymbol(argv[0]);
((methfun_1)a->gfun)(this,any);
}
else ok = false;
break;
case a_LIST:
any.vt = &(la(argc,argv));
((methfun_1)a->gfun)(this,any);
break;
default:
ERRINTERNAL();
attritem *a = attrhead;
for(; a && a->tag != tag; a = a->nxt) {}
if(a) {
bool ok = true;
AtomList la;
t_any any;
switch(a->argtp) {
case a_float:
if(argc == 1 && CanbeFloat(argv[0])) {
any.ft = GetAFloat(argv[0]);
((methfun_1)a->sfun)(this,any);
}
if(ok)
ToOutAnything(outattr,tag,la.Count(),la.Atoms());
else
post("%s - wrong arguments for attribute %s",thisName(),GetString(tag));
else ok = false;
break;
case a_int:
if(argc == 1 && CanbeInt(argv[0])) {
any.it = GetAInt(argv[0]);
((methfun_1)a->sfun)(this,any);
}
else ok = false;
break;
case a_symbol:
if(argc == 1 && IsSymbol(argv[0])) {
any.st = GetSymbol(argv[0]);
((methfun_1)a->sfun)(this,any);
}
else ok = false;
break;
case a_LIST:
any.vt = &(la(argc,argv));
((methfun_1)a->sfun)(this,any);
break;
default:
ERRINTERNAL();
}
else
error("%s - %s: attribute not found",thisName(),tag);
return true;
if(!ok)
post("%s - wrong arguments for attribute %s",thisName(),GetString(tag));
}
else return false;
else
error("%s - %s: attribute not found",thisName(),tag);
return true;
}
bool flext_base::GetAttrib(const t_symbol *tag,int argc,const t_atom *argv)
{
if(outattr) {
if(argc)
post("%s - %s: arguments ignored",thisName(),GetString(tag));
attritem *a = attrhead;
for(; a && a->tag != tag; a = a->nxt) {}
if(a) {
AtomList la;
t_any any;
switch(a->argtp) {
case a_float: {
((methfun_1)a->gfun)(this,any);
la(1);
SetFloat(la[0],any.ft);
break;
}
case a_int: {
((methfun_1)a->gfun)(this,any);
la(1);
SetInt(la[0],any.it);
break;
}
case a_symbol: {
((methfun_1)a->gfun)(this,any);
la(1);
SetSymbol(la[0],any.st);
break;
}
case a_LIST: {
any.vt = &la;
((methfun_1)a->gfun)(this,any);
break;
}
default:
ERRINTERNAL();
}
ToOutAnything(outattr,tag,la.Count(),la.Atoms());
if(argc)
post("%s - %s: arguments ignored",thisName(),GetString(tag));
attritem *a = attrhead;
for(; a && a->gtag != tag; a = a->nxt) {}
if(a) {
AtomList la;
t_any any;
switch(a->argtp) {
case a_float: {
((methfun_1)a->gfun)(this,any);
la(1);
SetFloat(la[0],any.ft);
break;
}
else
error("%s - %s: attribute not found",thisName(),tag);
return true;
case a_int: {
((methfun_1)a->gfun)(this,any);
la(1);
SetInt(la[0],any.it);
break;
}
case a_symbol: {
((methfun_1)a->gfun)(this,any);
la(1);
SetSymbol(la[0],any.st);
break;
}
case a_LIST: {
any.vt = &la;
((methfun_1)a->gfun)(this,any);
break;
}
default:
ERRINTERNAL();
}
ToOutAnything(outattr,a->tag,la.Count(),la.Atoms());
}
else return false;
else
error("%s - %s: attribute not found",thisName(),tag);
return true;
}
......@@ -66,6 +66,7 @@ void flext_obj::DefineHelp(t_class *c,const char *ref,const char *dir,bool addti
strcpy(tmp,ref);
::class_sethelpsymbol(c,gensym(const_cast<char *>(tmp)));
#else
// no solution for MaxMSP yet
#endif
}
......
......@@ -161,7 +161,7 @@ class FLEXT_EXT flext_obj:
public:
//! Creation callback
static void __setup__(t_class *) {}
static void __setup__(t_class *) { flext::Setup(); }
/*! \brief This is a temporary holder
\warning don't touch it!
......@@ -193,6 +193,13 @@ class FLEXT_EXT flext_obj:
// max. 5 method args (see the following macros)
#define FLEXT_MAXMETHARGS 5
// prefixes for the macro generated handler functions
#define FLEXT_CALL_PRE(F) flext_c_##F
#define FLEXT_THR_PRE(F) flext_t_##F
#define FLEXT_GET_PRE(F) flext_g_##F
#define FLEXT_SET_PRE(F) flext_s_##F
// ----------------------------------------
// These should be used in the header
// ----------------------------------------
......@@ -253,6 +260,9 @@ cl##_setup()
extern void cl##_tilde_setup(); \
cl##_tilde_setup()
// deprecated
#define FLEXT_TILDE_SETUP FLEXT_DSP_SETUP
#ifdef PD
#define FLEXT_LIB_SETUP(NAME,SETUPFUN) extern "C" FLEXT_EXT void NAME##_setup() { flext_obj::lib_init(#NAME,SETUPFUN); }
#else // MAXMSP
......
......@@ -144,15 +144,10 @@ public:
void AddOutList(int m = 1) { AddOutlet(xlet::tp_list,m); }
void AddOutList(const char *desc,int m = 1) { AddOutlet(xlet::tp_list,m,desc); }
//! Add outlet(s) for attribute dump
void AddOutAttr();
/*! \brief Set up inlets and outlets
\remark Must be called ONCE to actually set up the defined inlets/outlets.
\param attr Set to false to inhibit procession of attributes (default = true)
\return True on successful creation of all inlets and outlets
\note this is deprecated... inlets and outlets are now set up automatically
*/
bool SetupInOut();
bool SetupInOut() { return true; }
//! Get number of inlets
int CntIn() const { return incnt; }
......@@ -168,12 +163,15 @@ public:
// class AtomList;
// class AtomAnything;
//! Retrieve currently processed message tag (NULL if no message processing)
const t_symbol *thisTag() const { return curtag; }
//! Get pointer to outlet (_after_ calling setup_inout()!)
outlet *GetOut(int ix) { return (outlets && ix < outcnt)?outlets[ix]:NULL; }
// output messages
void ToOutBang(outlet *o);
void ToOutBang(outlet *o);
//! Output bang (index n starts with 0)
void ToOutBang(int n) { outlet *o = GetOut(n); if(o) ToOutBang(o); }
......@@ -189,7 +187,7 @@ public:
//! Output symbol (index n starts with 0)
void ToOutSymbol(int n,const t_symbol *s) { outlet *o = GetOut(n); if(o) ToOutSymbol(o,s); }
void ToOutString(outlet *o,const char *s) { ToOutSymbol(o,gensym(const_cast<char *>(s))); }
void ToOutString(outlet *o,const char *s) { ToOutSymbol(o,MakeSymbol(s)); }
//! Output string (index n starts with 0)
void ToOutString(int n,const char *s) { outlet *o = GetOut(n); if(o) ToOutString(o,s); }
......@@ -205,6 +203,22 @@ public:
//! Output anything (index n starts with 0)
void ToOutAnything(int n,const AtomAnything &any) { ToOutAnything(n,any.Header(),any.Count(),any.Atoms()); }
void ToQueueBang(outlet *o);
void ToQueueBang(int n) { outlet *o = GetOut(n); if(o) ToQueueBang(o); }
void ToQueueFloat(outlet *o,float f);
void ToQueueFloat(int n,float f) { outlet *o = GetOut(n); if(o) ToQueueFloat(o,f); }
void ToQueueInt(outlet *o,int f);
void ToQueueInt(int n,int f) { outlet *o = GetOut(n); if(o) ToQueueInt(o,f); }
void ToQueueSymbol(outlet *o,const t_symbol *s);
void ToQueueSymbol(int n,const t_symbol *s) { outlet *o = GetOut(n); if(o) ToQueueSymbol(o,s); }
void ToQueueString(int n,const char *s) { ToQueueSymbol(n,MakeSymbol(s)); }
void ToQueueList(outlet *o,int argc,const t_atom *argv);
void ToQueueList(int n,int argc,const t_atom *argv) { outlet *o = GetOut(n); if(o) ToQueueList(o,argc,argv); }
void ToQueueList(int n,const AtomList &list) { ToQueueList(n,list.Count(),list.Atoms()); }
void ToQueueAnything(outlet *o,const t_symbol *s,int argc,const t_atom *argv);
void ToQueueAnything(int n,const t_symbol *s,int argc,const t_atom *argv) { outlet *o = GetOut(n); if(o) ToQueueAnything(o,s,argc,argv); }
void ToQueueAnything(int n,const AtomAnything &any) { ToQueueAnything(n,any.Header(),any.Count(),any.Atoms()); }
//! @}
......@@ -214,10 +228,11 @@ public:
a_null = 0,
a_float,a_int,
a_symbol,a_pointer,
a_gimme,a_xgimme
a_list,a_any,
a_LIST,a_ANY
};
typedef bool (*methfun)(t_class *c);
typedef bool (*methfun)(flext_base *c);
/*! \defgroup FLEXT_C_ADDMETHOD Flext method handling
\internal
......@@ -225,13 +240,12 @@ public:
@{
*/
void AddMethodDef(int inlet); // call virtual function for inlet
void AddMethodDef(int inlet,const char *tag); // call virtual function for tag && inlet
void AddMethodDef(int inlet,const char *tag = NULL); // call virtual function for tag && inlet
void AddMethod(int inlet,const char *tag,methfun fun,metharg tp,...);
void AddMethod(int inlet,bool (*m)(flext_base *,int,t_atom *)) { AddMethod(inlet,"list",(methfun)m,a_gimme,a_null); }
void AddMethod(int inlet,bool (*m)(flext_base *,int,t_atom *)) { AddMethod(inlet,"list",(methfun)m,a_list,a_null); }
void AddMethod(int inlet,const char *tag,bool (*m)(flext_base *)) { AddMethod(inlet,tag,(methfun)m,a_null); } // pure method
void AddMethod(int inlet,bool (*m)(flext_base *,const t_symbol *,int,t_atom *)) { AddMethod(inlet,"anything",(methfun)m,a_xgimme,a_null); } // anything
void AddMethod(int inlet,bool (*m)(flext_base *,const t_symbol *,int,t_atom *)) { AddMethod(inlet,"anything",(methfun)m,a_any,a_null); } // anything
void AddMethod(int inlet,bool (*m)(flext_base *,t_symbol *&)) { AddMethod(inlet,"symbol",(methfun)m,a_symbol,a_null); } // single symbol
void AddMethod(int inlet,bool (*m)(flext_base *,float &)) { AddMethod(inlet,"float",(methfun)m,a_float,a_null); } // single float
void AddMethod(int inlet,bool (*m)(flext_base *,float &,float &)) { AddMethod(inlet,"list",(methfun)m,a_float,a_float,a_null); } // list of 2 floats
......@@ -243,8 +257,8 @@ public:
#endif
void AddMethod(int inlet,bool (*m)(flext_base *,int &,int &)) { AddMethod(inlet,"list",(methfun)m,a_int,a_int,a_null); } // list of 2 floats
void AddMethod(int inlet,bool (*m)(flext_base *,int &,int &,int &)) { AddMethod(inlet,"list",(methfun)m,a_int,a_int,a_int,a_null); } // list of 3 floats
void AddMethod(int inlet,const char *tag,bool (*m)(flext_base *,int,t_atom *)) { AddMethod(inlet,tag,(methfun)m,a_gimme,a_null); } // method+gimme
void AddMethod(int inlet,const char *tag,bool (*m)(flext_base *,const t_symbol *,int,t_atom *)) { AddMethod(inlet,tag,(methfun)m,a_xgimme,a_null); } // method+gimme
void AddMethod(int inlet,const char *tag,bool (*m)(flext_base *,int,t_atom *)) { AddMethod(inlet,tag,(methfun)m,a_list,a_null); } // method+gimme
void AddMethod(int inlet,const char *tag,bool (*m)(flext_base *,const t_symbol *,int,t_atom *)) { AddMethod(inlet,tag,(methfun)m,a_any,a_null); } // method+gimme
void AddMethod(int inlet,const char *tag,bool (*m)(flext_base *,t_symbol *&)) { AddMethod(inlet,tag,(methfun)m,a_symbol,a_null); } // method+symbol
void AddMethod(int inlet,const char *tag,bool (*m)(flext_base *,float &)) { AddMethod(inlet,tag,(methfun)m,a_float,a_null); } // method+float
void AddMethod(int inlet,const char *tag,bool (*m)(flext_base *,int &)) { AddMethod(inlet,tag,(methfun)m,a_int,a_null); } // method+int
......@@ -327,9 +341,6 @@ public:
//! @}
// xxx internal stuff xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// --- thread stuff -----------------------------------------------
......@@ -343,22 +354,17 @@ public:
protected:
flext_base();
flext_base(bool attr = false);
virtual ~flext_base();
// attributes
//! Flag for attribute procession
bool procattr;
// inlets and outlets
struct xlet {
enum type {
tp_none = 0,
tp_float,tp_int,tp_sym,tp_list,tp_any,
tp_sig,
tp_attr
tp_LIST,tp_ANY, // use AtomList and AtomAnything
tp_sig
};
xlet(type t,const char *desc = NULL);
......@@ -374,11 +380,10 @@ protected:
@{
*/
void AddAttrib(const char *attr,xlet::type tp,void (*set)(flext_obj &,float),void (*dump)(flext_obj &));
void AddAttrib(const char *attr,xlet::type tp,void (*set)(flext_obj &,int),void (*dump)(flext_obj &));
void AddAttrib(const char *attr,xlet::type tp,void (*set)(flext_obj &,const t_symbol *),void (*dump)(flext_obj &));
void AddAttrib(const char *attr,xlet::type tp,void (*set)(flext_obj &,const AtomList &),void (*dump)(flext_obj &));
void AddAttrib(const char *attr,xlet::type tp,void (*set)(flext_obj &,const AtomAnything &),void (*dump)(flext_obj &));
void AddAttrib(const char *attr,bool (*get)(flext_base *,float &),bool (*set)(flext_base *,float &)) { AddAttrib(attr,a_float,(methfun)get,(methfun)set); }
void AddAttrib(const char *attr,bool (*get)(flext_base *,int &),bool (*set)(flext_base *,int &)) { AddAttrib(attr,a_int,(methfun)get,(methfun)set); }
void AddAttrib(const char *attr,bool (*get)(flext_base *,t_symbol *&),bool (*set)(flext_base *,t_symbol *&)) { AddAttrib(attr,a_symbol,(methfun)get,(methfun)set); }
void AddAttrib(const char *attr,bool (*get)(flext_base *,AtomList &),bool (*set)(flext_base *,AtomList &)) { AddAttrib(attr,a_LIST,(methfun)get,(methfun)set); }
//! @}
......@@ -399,26 +404,16 @@ protected:
//! @}
#ifdef FLEXT_THREADS
void QueueBang(outlet *o);
void QueueFloat(outlet *o,float f);
void QueueInt(outlet *o,int f);
void QueueSymbol(outlet *o,const t_symbol *s);
void QueueList(outlet *o,int argc,t_atom *argv);
void QueueAnything(outlet *o,const t_symbol *s,int argc,t_atom *argv);
#endif
// method handling
class methitem {
public:
methitem(int inlet,t_symbol *t);
methitem(int inlet,const t_symbol *t);
~methitem();
void SetArgs(methfun fun,int argc,metharg *args);
t_symbol *tag;
const t_symbol *tag;
int inlet;
int argc;
metharg *args;
......@@ -427,21 +422,77 @@ protected:
methitem *nxt;
};
void AddMethItem(