Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Jonathan Wilkes
flext
Commits
9ef50f77
Commit
9ef50f77
authored
Jul 29, 2002
by
thomas
Browse files
no message
git-svn-id:
https://svn.grrrr.org/ext/trunk@183
4d9ac71a-51e6-0310-8455-cad1006bcd31
parent
7e568750
Changes
10
Hide whitespace changes
Inline
Side-by-side
flext.dsp
View file @
9ef50f77
...
...
@@ -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
...
...
readme.txt
View file @
9ef50f77
...
...
@@ -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?)
...
...
source/flbase.h
View file @
9ef50f77
...
...
@@ -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); \
...
...
source/flclass.h
View file @
9ef50f77
...
...
@@ -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
...
...
source/fldefs.h
View file @
9ef50f77
...
...
@@ -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->
Dec
Thread
s
(); \
th->
Pop
Thread(); \
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->
Dec
Thread
s
(); \
th->
Pop
Thread(); \
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->
Dec
Thread
s
(); \
th->
Pop
Thread(); \
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->
Dec
Thread
s
(); \
th->
Pop
Thread(); \
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->
Dec
Thread
s
(); \
th->
Pop
Thread(); \
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->
Dec
Thread
s
(); \
th->
Pop
Thread(); \
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->
Dec
Thread
s
(); \
th->
Pop
Thread(); \
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->
Dec
Thread
s
(); \
th->
Pop
Thread(); \
return NULL; \
}
...
...
source/flext.cpp
View file @
9ef50f77
...
...
@@ -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.01
f
);
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
);
...
...
source/fllib.cpp
View file @
9ef50f77
...
...
@@ -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
*
);
...
...
source/flsetup.cpp
View file @
9ef50f77
/*
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
;
}
source/flthr.cpp
View file @
9ef50f77
...
...
@@ -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
);
}
...
...
source/flthr.h
View file @
9ef50f77
...
...
@@ -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