Commit 9ef50f77 authored by thomas's avatar thomas
Browse files

no message


git-svn-id: https://svn.grrrr.org/ext/trunk@183 4d9ac71a-51e6-0310-8455-cad1006bcd31
parent 7e568750
......@@ -134,6 +134,10 @@ SOURCE=.\flinternal.h
# End Source File
# Begin Source File
SOURCE=.\flsetup.cpp
# End Source File
# Begin Source File
SOURCE=.\flstdc.h
# End Source File
# Begin Source File
......
......@@ -77,6 +77,8 @@ Version history:
- description text for inlets/outlets (e.g. for MaxMSPs assist function)
- added buffer resize (to be implemented for MaxMSP!)
- added some utility functions: Sleep, CopyAtom, CopyList
- added List manipulation classes: AtomList, AtomAnything
- Alias object names (simply specify with FLEXT_NEW*, separated by whitespace)
- fixed type warning for class constructors with int arguments in PD
0.2.3:
......@@ -169,7 +171,7 @@ general:
- 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)
- clean up headers (eliminate flstdc.h?)
bugs:
- PD: problems with timed buffer redrawing (takes a lot of cpu time)
......@@ -178,18 +180,15 @@ bugs:
tests:
- PD: figure out what "pointer" messages do and where they occur
- some more mutexes needed for thread safety?
- test alias names with MaxMSP
features:
- abstraction for parsing argument lists
- abstraction for creating lists and anythings
- abstraction for clock functions
- sending messages to own inlet (passing computation to other patch objects - message queue?)
- adding/removing methods anytime
premature thoughts:
- explore jMax interface style
- interface for supercollider, csound?
- interface for VST, DX, ...?
- interface for scripting language modules? (python?)
......
......@@ -302,7 +302,7 @@ return 0; \
#ifdef PD
#define FLEXT_NEWFN ::class_new
#define FLEXT_CLREF(NAME,CLASS) gensym(NAME)
#define FLEXT_CLREF(NAME,CLASS) gensym(const_cast<char *>(NAME))
//#define FLEXT_MAIN(MAINNAME) MAINNAME
#define CLNEW_OPTIONS 0 // flags for class creation
//#define LIB_INIT(NAME,NEWMETH,FREEMETH,ARG1,ARG2,ARG3,ARG4) ((void(0))
......@@ -346,6 +346,23 @@ return 0; \
#define CHECK_TILDE(OBJNAME,SETUPFUN) ((void)0)
#endif
#ifdef PD
#define FLEXT_ADDALIAS(NAME,FUN) ::class_addcreator((t_newmethod)FUN,::gensym(const_cast<char *>(NAME)),A_NULL)
#define FLEXT_ADDALIAS1(NAME,FUN,ARG1) ::class_addcreator((t_newmethod)FUN,::gensym(const_cast<char *>(NAME)),ARG1,A_NULL)
#define FLEXT_ADDALIAS2(NAME,FUN,ARG1,ARG2) ::class_addcreator((t_newmethod)FUN,::gensym(const_cast<char *>(NAME)),ARG1,ARG2,A_NULL)
#define FLEXT_ADDALIAS3(NAME,FUN,ARG1,ARG2,ARG3) ::class_addcreator((t_newmethod)FUN,::gensym(const_cast<char *>(NAME)),ARG1,ARG2,ARG3,A_NULL)
#define FLEXT_ADDALIAS4(NAME,FUN,ARG1,ARG2,ARG3,ARG4) ::class_addcreator((t_newmethod)FUN,::gensym(const_cast<char *>(NAME)),ARG1,ARG2,ARG3,ARG4,A_NULL)
#elif defined(MAXMSP)
#define FLEXT_ADDALIAS(NAME,FUN) ::alias(const_cast<char *>(NAME))
#define FLEXT_ADDALIAS1(NAME,FUN,ARG1) FLEXT_ADDALIAS(NAME,FUN)
#define FLEXT_ADDALIAS2(NAME,FUN,ARG1,ARG2) FLEXT_ADDALIAS(NAME,FUN)
#define FLEXT_ADDALIAS3(NAME,FUN,ARG1,ARG2,ARG3) FLEXT_ADDALIAS(NAME,FUN)
#define FLEXT_ADDALIAS4(NAME,FUN,ARG1,ARG2,ARG3,ARG4) FLEXT_ADDALIAS(NAME,FUN)
#else
#error "No alias function defined!"
#endif
const char *extractname(const char *name,int ix = 0);
// ----------------------------------------------------
// These should never be called or used directly!!!
......@@ -362,7 +379,7 @@ flext_hdr* class_ ## NEW_CLASS () \
{ \
flext_hdr *obj = new (newobject(NEW_CLASS ## _class),(void *)NULL) flext_hdr; \
flext_obj::m_holder = obj; \
flext_obj::m_holdname = NAME; \
flext_obj::m_holdname = extractname(NAME); \
obj->data = new NEW_CLASS; \
flext_obj::m_holder = NULL; \
return(obj); \
......@@ -371,11 +388,15 @@ FLEXT_EXP(LIB) void NEW_CLASS ## SETUP_FUNCTION() \
{ \
CHECK_TILDE(NAME,#SETUP_FUNCTION); \
NEW_CLASS ## _class = FLEXT_NEWFN( \
FLEXT_CLREF(NAME,NEW_CLASS ## _class), \
FLEXT_CLREF(extractname(NAME),NEW_CLASS ## _class), \
(t_newmethod)class_ ## NEW_CLASS, \
(t_method)&NEW_CLASS::callb_free, \
sizeof(flext_hdr), CLNEW_OPTIONS, \
A_NULL); \
for(int ix = 1; ; ++ix) { \
const char *c = extractname(NAME,ix); if(!c) break; \
FLEXT_ADDALIAS(c,(t_newmethod)class_ ## NEW_CLASS); \
} \
NEW_CLASS::callb_setup(NEW_CLASS ## _class); \
}
......@@ -384,7 +405,7 @@ flext_hdr* class_ ## NEW_CLASS () \
{ \
flext_hdr *obj = new (newobject(flext_obj::lib_class),(void *)NULL) flext_hdr; \
flext_obj::m_holder = obj; \
flext_obj::m_holdname = NAME; \
flext_obj::m_holdname = extractname(NAME); \
obj->data = new NEW_CLASS; \
flext_obj::m_holder = NULL; \
return(obj); \
......@@ -406,7 +427,7 @@ flext_hdr* class_ ## NEW_CLASS (CALLBTP(TYPE1) arg1) \
{ \
flext_hdr *obj = new (newobject(NEW_CLASS ## _class),(void *)NULL) flext_hdr; \
flext_obj::m_holder = obj; \
flext_obj::m_holdname = NAME; \
flext_obj::m_holdname = extractname(NAME); \
obj->data = new NEW_CLASS((TYPE1)arg1); \
flext_obj::m_holder = NULL; \
return(obj); \
......@@ -415,12 +436,16 @@ FLEXT_EXP(LIB) void NEW_CLASS ## SETUP_FUNCTION() \
{ \
CHECK_TILDE(NAME,#SETUP_FUNCTION); \
NEW_CLASS ## _class = FLEXT_NEWFN( \
FLEXT_CLREF(NAME,NEW_CLASS ## _class), \
FLEXT_CLREF(extractname(NAME),NEW_CLASS ## _class), \
(t_newmethod)class_ ## NEW_CLASS, \
(t_method)&NEW_CLASS::callb_free, \
sizeof(flext_hdr), CLNEW_OPTIONS, \
FLEXTTP(TYPE1), \
A_NULL); \
for(int ix = 1; ; ++ix) { \
const char *c = extractname(NAME,ix); if(!c) break; \
FLEXT_ADDALIAS1(c,(t_newmethod)class_ ## NEW_CLASS,FLEXTTP(TYPE1)); \
} \
NEW_CLASS::callb_setup(NEW_CLASS ## _class); \
}
......@@ -429,7 +454,7 @@ flext_hdr* class_ ## NEW_CLASS (const flext_obj::lib_arg &arg1) \
{ \
flext_hdr *obj = new (newobject(flext_obj::lib_class),(void *)NULL) flext_hdr; \
flext_obj::m_holder = obj; \
flext_obj::m_holdname = NAME; \
flext_obj::m_holdname = extractname(NAME); \
obj->data = new NEW_CLASS(ARGCAST(arg1,TYPE1)); \
flext_obj::m_holder = NULL; \
return(obj); \
......@@ -451,7 +476,7 @@ flext_hdr* class_ ## NEW_CLASS (t_symbol *s,int argc,t_atom *argv) \
{ \
flext_hdr *obj = new (newobject(NEW_CLASS ## _class),(void *)NULL) flext_hdr; \
flext_obj::m_holder = obj; \
flext_obj::m_holdname = NAME; \
flext_obj::m_holdname = extractname(NAME); \
obj->data = new NEW_CLASS(argc,argv); \
flext_obj::m_holder = NULL; \
return(obj); \
......@@ -460,12 +485,16 @@ FLEXT_EXP(LIB) void NEW_CLASS ## SETUP_FUNCTION() \
{ \
CHECK_TILDE(NAME,#SETUP_FUNCTION); \
NEW_CLASS ## _class = FLEXT_NEWFN( \
FLEXT_CLREF(NAME,NEW_CLASS ## _class), \
FLEXT_CLREF(extractname(NAME),NEW_CLASS ## _class), \
(t_newmethod)class_ ## NEW_CLASS, \
(t_method)&NEW_CLASS::callb_free, \
sizeof(flext_hdr), CLNEW_OPTIONS, \
A_GIMME, \
A_NULL); \
for(int ix = 1; ; ++ix) { \
const char *c = extractname(NAME,ix); if(!c) break; \
FLEXT_ADDALIAS1(c,(t_newmethod)class_ ## NEW_CLASS,A_GIMME); \
} \
NEW_CLASS::callb_setup(NEW_CLASS ## _class); \
}
......@@ -474,7 +503,7 @@ flext_hdr* class_ ## NEW_CLASS (t_symbol *s,int argc,t_atom *argv) \
{ \
flext_hdr *obj = new (newobject(flext_obj::lib_class),(void *)NULL) flext_hdr; \
flext_obj::m_holder = obj; \
flext_obj::m_holdname = NAME; \
flext_obj::m_holdname = extractname(NAME); \
obj->data = new NEW_CLASS(argc,argv); \
flext_obj::m_holder = NULL; \
return(obj); \
......@@ -496,7 +525,7 @@ flext_hdr* class_ ## NEW_CLASS (CALLBTP(TYPE1) arg1, CALLBTP(TYPE2) arg2) \
{ \
flext_hdr *obj = new (newobject(NEW_CLASS ## _class),(void *)NULL) flext_hdr; \
flext_obj::m_holder = obj; \
flext_obj::m_holdname = NAME; \
flext_obj::m_holdname = extractname(NAME); \
obj->data = new NEW_CLASS((TYPE1)arg1, (TYPE2)arg2); \
flext_obj::m_holder = NULL; \
return(obj); \
......@@ -505,12 +534,16 @@ FLEXT_EXP(LIB) void NEW_CLASS ## SETUP_FUNCTION() \
{ \
CHECK_TILDE(NAME,#SETUP_FUNCTION); \
NEW_CLASS ## _class = FLEXT_NEWFN( \
FLEXT_CLREF(NAME,NEW_CLASS ## _class), \
FLEXT_CLREF(extractname(NAME),NEW_CLASS ## _class), \
(t_newmethod)class_ ## NEW_CLASS, \
(t_method)&NEW_CLASS::callb_free, \
sizeof(flext_hdr), CLNEW_OPTIONS, \
FLEXTTP(TYPE1), FLEXTTP(TYPE2), \
A_NULL); \
for(int ix = 1; ; ++ix) { \
const char *c = extractname(NAME,ix); if(!c) break; \
FLEXT_ADDALIAS2(c,(t_newmethod)class_ ## NEW_CLASS,FLEXTTP(TYPE1),FLEXTTP(TYPE2)); \
} \
NEW_CLASS::callb_setup(NEW_CLASS ## _class); \
}
......@@ -519,7 +552,7 @@ flext_hdr* class_ ## NEW_CLASS (const flext_obj::lib_arg &arg1,const flext_obj::
{ \
flext_hdr *obj = new (newobject(flext_obj::lib_class),(void *)NULL) flext_hdr; \
flext_obj::m_holder = obj; \
flext_obj::m_holdname = NAME; \
flext_obj::m_holdname = extractname(NAME); \
obj->data = new NEW_CLASS(ARGCAST(arg1,TYPE1),ARGCAST(arg2,TYPE2)); \
flext_obj::m_holder = NULL; \
return(obj); \
......@@ -541,7 +574,7 @@ flext_hdr* class_ ## NEW_CLASS (CALLBTP(TYPE1) arg1,CALLBTP(TYPE2) arg2,CALLBTP(
{ \
flext_hdr *obj = new (newobject(NEW_CLASS ## _class),(void *)NULL) flext_hdr; \
flext_obj::m_holder = obj; \
flext_obj::m_holdname = NAME; \
flext_obj::m_holdname = extractname(NAME); \
obj->data = new NEW_CLASS((TYPE1)arg1,(TYPE2)arg2,(TYPE3)arg3); \
flext_obj::m_holder = NULL; \
return(obj); \
......@@ -550,12 +583,16 @@ FLEXT_EXP(LIB) void NEW_CLASS ## SETUP_FUNCTION() \
{ \
CHECK_TILDE(NAME,#SETUP_FUNCTION); \
NEW_CLASS ## _class = FLEXT_NEWFN( \
FLEXT_CLREF(NAME,NEW_CLASS ## _class), \
FLEXT_CLREF(extractname(NAME),NEW_CLASS ## _class), \
(t_newmethod)class_ ## NEW_CLASS, \
(t_method)&NEW_CLASS::callb_free, \
sizeof(flext_hdr), CLNEW_OPTIONS, \
FLEXTTP(TYPE1), FLEXTTP(TYPE2),FLEXTTP(TYPE3), \
A_NULL); \
for(int ix = 1; ; ++ix) { \
const char *c = extractname(NAME,ix); if(!c) break; \
FLEXT_ADDALIAS3(c,(t_newmethod)class_ ## NEW_CLASS,FLEXTTP(TYPE1),FLEXTTP(TYPE2),FLEXTTP(TYPE3)); \
} \
NEW_CLASS::callb_setup(NEW_CLASS ## _class); \
}
......@@ -564,7 +601,7 @@ flext_hdr* class_ ## NEW_CLASS (const flext_obj::lib_arg &arg1,const flext_obj::
{ \
flext_hdr *obj = new (newobject(flext_obj::lib_class),(void *)NULL) flext_hdr; \
flext_obj::m_holder = obj; \
flext_obj::m_holdname = NAME; \
flext_obj::m_holdname = extractname(NAME); \
obj->data = new NEW_CLASS(ARGCAST(arg1,TYPE1),ARGCAST(arg2,TYPE2),ARGCAST(arg3,TYPE3)); \
flext_obj::m_holder = NULL; \
return(obj); \
......@@ -585,7 +622,7 @@ flext_hdr* class_ ## NEW_CLASS (CALLBTP(TYPE1) arg1,CALLBTP(TYPE2) arg2,CALLBTP(
{ \
flext_hdr *obj = new (newobject(NEW_CLASS ## _class),(void *)NULL) flext_hdr; \
flext_obj::m_holder = obj; \
flext_obj::m_holdname = NAME; \
flext_obj::m_holdname = extractname(NAME); \
obj->data = new NEW_CLASS((TYPE1)arg1,(TYPE2)arg2,(TYPE3)arg3,(TYPE4)arg4); \
flext_obj::m_holder = NULL; \
return(obj); \
......@@ -594,12 +631,16 @@ FLEXT_EXP(LIB) void NEW_CLASS ## SETUP_FUNCTION() \
{ \
CHECK_TILDE(NAME,#SETUP_FUNCTION); \
NEW_CLASS ## _class = FLEXT_NEWFN( \
FLEXT_CLREF(NAME,NEW_CLASS ## _class), \
FLEXT_CLREF(extractname(NAME),NEW_CLASS ## _class), \
(t_newmethod)class_ ## NEW_CLASS, \
(t_method)&NEW_CLASS::callb_free, \
sizeof(flext_hdr), CLNEW_OPTIONS, \
FLEXTTP(TYPE1), FLEXTTP(TYPE2),FLEXTTP(TYPE3),FLEXTTP(TYPE4), \
A_NULL); \
for(int ix = 1; ; ++ix) { \
const char *c = extractname(NAME,ix); if(!c) break; \
FLEXT_ADDALIAS4(c,(t_newmethod)class_ ## NEW_CLASS,FLEXTTP(TYPE1),FLEXTTP(TYPE2),FLEXTTP(TYPE3),FLEXTTP(TYPE4)); \
} \
NEW_CLASS::callb_setup(NEW_CLASS ## _class); \
}
......@@ -608,7 +649,7 @@ flext_hdr* class_ ## NEW_CLASS (const flext_obj::lib_arg &arg1,const flext_obj::
{ \
flext_hdr *obj = new (newobject(flext_obj::lib_class),(void *)NULL) flext_hdr; \
flext_obj::m_holder = obj; \
flext_obj::m_holdname = NAME; \
flext_obj::m_holdname = extractname(NAME); \
obj->data = new NEW_CLASS(ARGCAST(arg1,TYPE1),ARGCAST(arg2,TYPE2),ARGCAST(arg3,TYPE3),ARGCAST(arg4,TYPE4)); \
flext_obj::m_holder = NULL; \
return(obj); \
......
......@@ -347,10 +347,6 @@ public:
#ifdef FLEXT_THREADS
// --- thread stuff -----------------------------------------------
class thr_params;
static bool StartThread(void *(*)(thr_params *p),thr_params *p,char *methname);
void IncThreads() { ++thrcount; }
void DecThreads() { --thrcount; }
bool ShouldExit() const { return shouldexit; }
......@@ -433,6 +429,13 @@ public:
// xxx internal stuff xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// --- thread stuff -----------------------------------------------
class thr_params;
static bool StartThread(void *(*)(thr_params *p),thr_params *p,char *methname);
void PushThread();
void PopThread();
protected:
flext_base();
......@@ -519,6 +522,10 @@ private:
static void QTick(flext_base *th);
void Queue(qmsg *m);
class thr_entry;
thr_entry *thrhead,*thrtail;
ThrMutex tlmutex;
#endif
#ifdef PD
......
......@@ -245,10 +245,10 @@ static void cb_ ## M_FUN(flext_base *c) { \
} \
static void *thr_ ## M_FUN(thr_params *p) { \
thisType *th = static_cast<thisType *>(p->cl); \
th->PushThread(); \
delete p; \
th->IncThreads(); \
th->M_FUN(); \
th->DecThreads(); \
th->PopThread(); \
return NULL; \
}
......@@ -260,11 +260,11 @@ static void cb_ ## M_FUN(flext_base *c,t_symbol *s,int argc,t_atom *argv) { \
} \
static void *thr_ ## M_FUN(thr_params *p) { \
thisType *th = static_cast<thisType *>(p->cl); \
th->PushThread(); \
t_symbol *s; int argc; t_atom argv; p->get_any(s,argc,argv); \
delete p; \
th->IncThreads(); \
th->M_FUN(s,argc,argv); \
th->DecThreads(); \
th->PopThread(); \
return NULL; \
}
......@@ -276,11 +276,11 @@ static void cb_ ## M_FUN(flext_base *c,int argc,t_atom *argv) { \
} \
static void *thr_ ## M_FUN(thr_params *p) { \
thisType *th = static_cast<thisType *>(p->cl); \
th->PushThread(); \
int argc; t_atom argv; p->get_gimme(argc,argv); \
delete p; \
th->IncThreads(); \
th->M_FUN(argc,argv); \
th->DecThreads(); \
th->PopThread(); \
return NULL; \
}
......@@ -292,11 +292,11 @@ static void cb_ ## M_FUN(flext_base *c,int &arg1) { \
} \
static void *thr_ ## M_FUN(thr_params *p) { \
thisType *th = static_cast<thisType *>(p->cl); \
th->PushThread(); \
bool b = p->var[0]; \
delete p; \
th->IncThreads(); \
th->M_FUN(b); \
th->DecThreads(); \
th->PopThread(); \
return NULL; \
}
......@@ -309,11 +309,11 @@ static void cb_ ## M_FUN(flext_base *c,TP1 &arg1) { \
} \
static void *thr_ ## M_FUN(thr_params *p) { \
thisType *th = static_cast<thisType *>(p->cl); \
th->PushThread(); \
const TP1 v1 = p->var[0]._ ## TP1; \
delete p; \
th->IncThreads(); \
th->M_FUN(v1); \
th->DecThreads(); \
th->PopThread(); \
return NULL; \
}
......@@ -327,12 +327,12 @@ static void cb_ ## M_FUN(flext_base *c,TP1 &arg1,TP2 &arg2) { \
} \
static void *thr_ ## M_FUN(thr_params *p) { \
thisType *th = static_cast<thisType *>(p->cl); \
th->PushThread(); \
const TP1 v1 = p->var[0]._ ## TP1; \
const TP1 v2 = p->var[1]._ ## TP2; \
delete p; \
th->IncThreads(); \
th->M_FUN(v1,v2); \
th->DecThreads(); \
th->PopThread(); \
return NULL; \
}
......@@ -347,13 +347,13 @@ static void cb_ ## M_FUN(flext_base *c,TP1 &arg1,TP2 &arg2,TP3 &arg3) { \
} \
static void *thr_ ## M_FUN(thr_params *p) { \
thisType *th = static_cast<thisType *>(p->cl); \
th->PushThread(); \
const TP1 v1 = p->var[0]._ ## TP1; \
const TP2 v2 = p->var[1]._ ## TP2; \
const TP3 v3 = p->var[2]._ ## TP3; \
delete p; \
th->IncThreads(); \
th->M_FUN(v1,v2,v3); \
th->DecThreads(); \
th->PopThread(); \
return NULL; \
}
......@@ -369,14 +369,14 @@ static void cb_ ## M_FUN(flext_base *c,TP1 &arg1,TP2 &arg2,TP3 &arg3,TP4 &arg4)
} \
static void *thr_ ## M_FUN(thr_params *p) { \
thisType *th = static_cast<thisType *>(p->cl); \
th->PushThread(); \
const TP1 v1 = p->var[0]._ ## TP1; \
const TP2 v2 = p->var[1]._ ## TP2; \
const TP3 v3 = p->var[2]._ ## TP3; \
const TP4 v4 = p->var[3]._ ## TP4; \
delete p; \
th->IncThreads(); \
th->M_FUN(v1,v2,v3,v4); \
th->DecThreads(); \
th->PopThread(); \
return NULL; \
}
......
......@@ -139,10 +139,10 @@ flext_base::flext_base():
LOG("Logging is on");
#ifdef FLEXT_THREAD
thrcount = 0;
shouldexit = false;
qhead = qtail = NULL;
qclk = clock_new(this,(t_method)QTick);
thrhead = thrtail = NULL;
#endif
}
......@@ -151,7 +151,16 @@ flext_base::~flext_base()
#ifdef FLEXT_THREAD
// wait for thread termination
shouldexit = true;
while(thrcount) Sleep(1);
for(int wi = 0; thrhead && wi < 100; ++wi) Sleep(0.01f);
tlmutex.Lock();
// timeout -> hard termination
while(thrhead) {
thr_entry *t = thrhead;
if(pthread_cancel(t->thrid)) post("%s - Thread could not be terminated!",thisName());
thrhead = t->nxt;
t->nxt = NULL; delete t;
}
tlmutex.Unlock();
while(qhead) QTick(this);
clock_free(qclk);
......
......@@ -40,32 +40,37 @@ void libfunction::add(libfunction *n) { if(nxt) nxt->add(n); else nxt = n; }
void flext_obj::libfun_add(const char *name,t_newmethod newfun,void (*freefun)(flext_hdr *),int argtp1,...)
{
alias(const_cast<char *>(name)); // make object name available to Max
for(int ix = 0; ; ++ix) {
const char *c = extractname(name,ix);
if(!c || !*c) break;
alias(const_cast<char *>(c)); // make object name available to Max
libfunction *l = new libfunction(gensym(const_cast<char *>(name)),newfun,freefun);
libfunction *l = new libfunction(gensym(const_cast<char *>(c)),newfun,freefun);
if(argtp1 == A_GIMME)
l->argc = -1;
else {
int argtp,i;
va_list marker;
va_start(marker,argtp1);
l->argc = 0;
for(argtp = argtp1; argtp != A_NULL; ++l->argc) argtp = (int)va_arg(marker,int);
va_end(marker);
l->argv = new int[l->argc];
if(argtp1 == A_GIMME)
l->argc = -1;
else {
int argtp,i;
va_list marker;
va_start(marker,argtp1);
l->argc = 0;
for(argtp = argtp1; argtp != A_NULL; ++l->argc) argtp = (int)va_arg(marker,int);
va_end(marker);
l->argv = new int[l->argc];
va_start(marker,argtp1);
for(argtp = argtp1,i = 0; i < l->argc; ++i) {
l->argv[i] = argtp;
argtp = (int)va_arg(marker,int);
va_start(marker,argtp1);
for(argtp = argtp1,i = 0; i < l->argc; ++i) {
l->argv[i] = argtp;
argtp = (int)va_arg(marker,int);
}
va_end(marker);
}
va_end(marker);
}
if(libfuncs) libfuncs->add(l);
else libfuncs = l;
if(libfuncs) libfuncs->add(l);
else libfuncs = l;
}
}
typedef flext_hdr *(*libfunG)(t_symbol *,int,t_atom *);
......
/*
flext - C++ layer for Max/MSP and pd (pure data) externals
Copyright (c) 2001,2002 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.
*/
/*! \file flsetup.cpp
\brief Helper functions for object setup
!Lacking Details.!
*/
#include <flext.h>
#include <ctype.h>
const char *extractname(const char *name,int ix)
{
static char tmp[1024];
const char *n = name;
for(int i = 0; n && *n; ++i) {
if(i == ix) {
for(char *t = tmp; *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;
}
......@@ -31,6 +31,36 @@ bool flext_base::StartThread(void *(*meth)(thr_params *p),thr_params *p,char *me
return true;
}
void flext_base::PushThread()
{
tlmutex.Lock();
thr_entry *nt = new thr_entry;
if(thrtail) thrtail->nxt = nt;
else thrhead = nt;
thrtail = nt;
tlmutex.Unlock();
}
void flext_base::PopThread()
{
tlmutex.Lock();
thr_entry *prv = NULL;
for(thr_entry *ti = thrhead; ti && !ti->Is(); prv = ti,ti = ti->nxt);
if(ti) {
if(prv)
prv->nxt = ti->nxt;
else
thrhead = thrtail = ti;
ti->nxt = NULL;
delete ti;
}
else {
post("%s - Internal error - Thread not found!",thisName());
}
tlmutex.Unlock();
}
class flext_base::qmsg
......@@ -60,7 +90,7 @@ public:
struct { const t_symbol *s; int argc; t_atom *argv; } _any;
};
void Add(qmsg *o);
// void Add(qmsg *o);
};
flext_base::qmsg::~qmsg()
......@@ -76,11 +106,13 @@ void flext_base::qmsg::Clear()
tp = tp_none;
}
/*
void flext_base::qmsg::Add(qmsg *o)
{
if(nxt) nxt->Add(o);
else nxt = o;
}
*/
void flext_base::QTick(flext_base *th)
{
......@@ -118,8 +150,9 @@ void flext_base::QTick(flext_base *th)
void flext_base::Queue(qmsg *m)
{
qmutex.Lock();
if(qhead) qtail->Add(m);
else qhead = qtail = m;
if(qtail) qtail->nxt = m;
else qhead = m;
qtail = m;
qmutex.Unlock();
clock_delay(qclk,0);
}
......
......@@ -20,7 +20,8 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#include <pthread.h>
class flext_base::thr_params {
class flext_base::thr_params
{
public:
thr_params(flext_base *c): cl(c) {}
......@@ -41,6 +42,17 @@ public:
} var[5];
};
class flext_base::thr_entry