Commit 5e2ad619 authored by thomas's avatar thomas
Browse files

no message


git-svn-id: https://svn.grrrr.org/ext/trunk@177 4d9ac71a-51e6-0310-8455-cad1006bcd31
parent de49696d
......@@ -130,7 +130,15 @@ SOURCE=.\flstdc.h
# End Source File
# Begin Source File
SOURCE=.\flthr.cpp
# End Source File
# Begin Source File
SOURCE=.\flthr.h
# End Source File
# Begin Source File
SOURCE=.\flutil.cpp
# End Source File
# End Target
# End Project
......@@ -71,10 +71,13 @@ see flext.h for the documented base classes
Version history:
0.2.4:
0.3.0:
- added threaded methods along with a message queue for ToOut* functions
- check/update function for buffer change (resize etc.)
- description text for inlets/outlets (e.g. for MaxMSPs assist function)
- added buffer resize (to be implemented for MaxMSP!)
- added some utility functions: Sleep, CopyList
- fixed type warning for class constructors with int arguments in PD
0.2.3:
- restructured files and started usable inline documentation
......
......@@ -407,7 +407,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; \
obj->data = new NEW_CLASS(arg1); \
obj->data = new NEW_CLASS((TYPE1)arg1); \
flext_obj::m_holder = NULL; \
return(obj); \
} \
......@@ -497,7 +497,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; \
obj->data = new NEW_CLASS(arg1, arg2); \
obj->data = new NEW_CLASS((TYPE1)arg1, (TYPE2)arg2); \
flext_obj::m_holder = NULL; \
return(obj); \
} \
......@@ -542,7 +542,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; \
obj->data = new NEW_CLASS(arg1,arg2,arg3); \
obj->data = new NEW_CLASS((TYPE1)arg1,(TYPE2)arg2,(TYPE3)arg3); \
flext_obj::m_holder = NULL; \
return(obj); \
} \
......@@ -586,7 +586,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; \
obj->data = new NEW_CLASS(arg1,arg2,arg3,arg4); \
obj->data = new NEW_CLASS((TYPE1)arg1,(TYPE2)arg2,(TYPE3)arg3,(TYPE4)arg4); \
flext_obj::m_holder = NULL; \
return(obj); \
} \
......
......@@ -150,8 +150,8 @@ void flext_base::buffer::Frames(int fr,bool keep)
{
#ifdef PD
garray_resize(arr,(float)fr);
#elif
error("buffer: resize not implemented!");
#else
#pragma message ("flext - Buffer resize not implemented!")
#endif
}
......
......@@ -345,12 +345,28 @@ public:
// static void SetPointer(t_atom &,void *) {}
#endif
#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; }
#endif // FLEXT_THREADS
// --- list creation stuff ----------------------------------------
// --- clock stuff ------------------------------------------------
// --- utilities --------------------------------------------------
static void CopyAtom(t_atom *dst,const t_atom *src) { *dst = *src; }
static t_atom *CopyList(int argc,const t_atom *argv);
static void Sleep(int ms);
// xxx internal stuff xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
protected:
......@@ -428,6 +444,19 @@ private:
methitem *mlst;
#ifdef FLEXT_THREADS
bool shouldexit;
int thrcount;
class qmsg;
qmsg *qhead,*qtail;
t_clock *qclk;
pthread_mutex_t qmutex;
static void QTick(flext_base *th);
void Queue(qmsg *m);
#endif
#ifdef PD
// proxy object (for additional inlets) stuff
struct px_object;
......
......@@ -241,13 +241,14 @@ static void cb_ ## M_FUN(flext_base *c,TP1 &arg1,TP2 &arg2,TP3 &arg3,TP4 &arg4,T
#define FLEXT_THREAD(M_FUN) \
static void cb_ ## M_FUN(flext_base *c) { \
thr_params *p = new thr_params(c); \
pthread_t thrid; \
pthread_create (&thrid,NULL,(void *(*)(void *))(thr_ ## M_FUN),p); \
StartThread(thr_ ## M_FUN,p,#M_FUN); \
} \
static void *thr_ ## M_FUN(thr_params *p) { \
thisType *th = static_cast<thisType *>(p->cl); \
delete p; \
th->IncThreads(); \
th->M_FUN(); \
th->DecThreads(); \
return NULL; \
}
......@@ -255,14 +256,15 @@ static void *thr_ ## M_FUN(thr_params *p) { \
#define FLEXT_THREAD_A(M_FUN) \
static void cb_ ## M_FUN(flext_base *c,t_symbol *s,int argc,t_atom *argv) { \
thr_params *p = new thr_params(c); p->set_any(s,argc,argv); \
pthread_t thrid; \
pthread_create (&thrid,NULL,(void *(*)(void *))(thr_ ## M_FUN),p); \
StartThread(thr_ ## M_FUN,p,#M_FUN); \
} \
static void *thr_ ## M_FUN(thr_params *p) { \
thisType *th = static_cast<thisType *>(p->cl); \
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(); \
return NULL; \
}
......@@ -270,14 +272,15 @@ static void *thr_ ## M_FUN(thr_params *p) { \
#define FLEXT_THREAD_G(M_FUN) \
static void cb_ ## M_FUN(flext_base *c,int argc,t_atom *argv) { \
thr_params *p = new thr_params(c); p->set_gimme(argc,argv); \
pthread_t thrid; \
pthread_create (&thrid,NULL,(void *(*)(void *))(thr_ ## M_FUN),p); \
StartThread(thr_ ## M_FUN,p,#M_FUN); \
} \
static void *thr_ ## M_FUN(thr_params *p) { \
thisType *th = static_cast<thisType *>(p->cl); \
int argc; t_atom argv; p->get_gimme(argc,argv); \
delete p; \
th->IncThreads(); \
th->M_FUN(argc,argv); \
th->DecThreads(); \
return NULL; \
}
......@@ -285,14 +288,15 @@ static void *thr_ ## M_FUN(thr_params *p) { \
#define FLEXT_THREAD_B(M_FUN) \
static void cb_ ## M_FUN(flext_base *c,int &arg1) { \
thr_params *p = new thr_params(c); p->var[0]._bool = arg1 != 0; \
pthread_t thrid; \
pthread_create (&thrid,NULL,(void *(*)(void *))(thr_ ## M_FUN),p); \
StartThread(thr_ ## M_FUN,p,#M_FUN); \
} \
static void *thr_ ## M_FUN(thr_params *p) { \
thisType *th = static_cast<thisType *>(p->cl); \
bool b = p->var[0]; \
delete p; \
th->IncThreads(); \
th->M_FUN(b); \
th->DecThreads(); \
return NULL; \
}
......@@ -301,14 +305,15 @@ static void *thr_ ## M_FUN(thr_params *p) { \
static void cb_ ## M_FUN(flext_base *c,TP1 &arg1) { \
thr_params *p = new thr_params(c); \
p->var[0]._ ## TP1 = arg1; \
pthread_t thrid; \
pthread_create (&thrid,NULL,(void *(*)(void *))(thr_ ## M_FUN),p); \
StartThread(thr_ ## M_FUN,p,#M_FUN); \
} \
static void *thr_ ## M_FUN(thr_params *p) { \
thisType *th = static_cast<thisType *>(p->cl); \
const TP1 v1 = p->var[0]._ ## TP1; \
delete p; \
th->IncThreads(); \
th->M_FUN(v1); \
th->DecThreads(); \
return NULL; \
}
......@@ -318,15 +323,16 @@ static void cb_ ## M_FUN(flext_base *c,TP1 &arg1,TP2 &arg2) { \
thr_params *p = new thr_params(c); \
p->var[0]._ ## TP1 = arg1; \
p->var[1]._ ## TP2 = arg2; \
pthread_t thrid; \
pthread_create (&thrid,NULL,(void *(*)(void *))(thr_ ## M_FUN),p); \
StartThread(thr_ ## M_FUN,p,#M_FUN); \
} \
static void *thr_ ## M_FUN(thr_params *p) { \
thisType *th = static_cast<thisType *>(p->cl); \
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(); \
return NULL; \
}
......@@ -337,8 +343,7 @@ static void cb_ ## M_FUN(flext_base *c,TP1 &arg1,TP2 &arg2,TP3 &arg3) { \
p->var[0]._ ## TP1 = arg1; \
p->var[1]._ ## TP2 = arg2; \
p->var[2]._ ## TP3 = arg3; \
pthread_t thrid; \
pthread_create (&thrid,NULL,(void *(*)(void *))(thr_ ## M_FUN),p); \
StartThread(thr_ ## M_FUN,p,#M_FUN); \
} \
static void *thr_ ## M_FUN(thr_params *p) { \
thisType *th = static_cast<thisType *>(p->cl); \
......@@ -346,7 +351,9 @@ static void *thr_ ## M_FUN(thr_params *p) { \
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(); \
return NULL; \
}
......@@ -358,8 +365,7 @@ static void cb_ ## M_FUN(flext_base *c,TP1 &arg1,TP2 &arg2,TP3 &arg3,TP4 &arg4)
p->var[1]._ ## TP2 = arg2; \
p->var[2]._ ## TP3 = arg3; \
p->var[3]._ ## TP4 = arg4; \
pthread_t thrid; \
pthread_create (&thrid,NULL,(void *(*)(void *))(thr_ ## M_FUN),p); \
StartThread(thr_ ## M_FUN,p,#M_FUN); \
} \
static void *thr_ ## M_FUN(thr_params *p) { \
thisType *th = static_cast<thisType *>(p->cl); \
......@@ -368,7 +374,9 @@ static void *thr_ ## M_FUN(thr_params *p) { \
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(); \
return NULL; \
}
......@@ -381,8 +389,7 @@ static void cb_ ## M_FUN(flext_base *c,TP1 &arg1,TP2 &arg2,TP3 &arg3,TP4 &arg4,T
p->var[2]._ ## TP3 = arg3; \
p->var[3]._ ## TP4 = arg4; \
p->var[4]._ ## TP5 = arg5; \
pthread_t thrid; \
pthread_create (&thrid,NULL,(void *(*)(void *))(thr_ ## M_FUN),p); \
StartThread(thr_ ## M_FUN,p,#M_FUN); \
} \
static void *thr_ ## M_FUN(thr_params *p) { \
thisType *th = static_cast<thisType *>(p->cl); \
......@@ -392,7 +399,9 @@ static void *thr_ ## M_FUN(thr_params *p) { \
const TP4 v4 = p->var[3]._ ## TP4; \
const TP5 v5 = p->var[4]._ ## TP5; \
delete p; \
th->IncThreads(); \
th->M_FUN(v1,v2,v3,v4,v5); \
th->DecThreads(); \
return NULL; \
}
......
......@@ -137,10 +137,28 @@ flext_base::flext_base():
distmsgs(false)
{
LOG("Logging is on");
#ifdef FLEXT_THREAD
thrcount = 0;
shouldexit = false;
qhead = qtail = NULL;
pthread_mutex_init(&qmutex,NULL);
qclk = clock_new(this,(t_method)QTick);
#endif
}
flext_base::~flext_base()
{
#ifdef FLEXT_THREAD
// wait for thread termination
shouldexit = true;
while(thrcount) Sleep(1);
while(qhead) QTick(this);
clock_free(qclk);
pthread_mutex_destroy(&qmutex);
#endif
if(inlist) delete inlist;
if(outlist) delete outlist;
if(outlets) delete[] outlets;
......@@ -430,11 +448,6 @@ bool flext_base::SetupInOut()
case xlet::tp_float:
outlets[ix] = (outlet *)newout_float(&x_obj->obj);
break;
/*
case xlet::tp_flint:
outlets[ix] = (outlet *)newout_flint(&x_obj->obj);
break;
*/
case xlet::tp_int:
outlets[ix] = (outlet *)newout_flint(&x_obj->obj);
break;
......
/*
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.
*/
#ifdef FLEXT_THREADS
#include <flext.h>
bool flext_base::StartThread(void *(*meth)(thr_params *p),thr_params *p,char *methname)
{
#ifdef DEBUG
if(!p) {
error("%s - No parameters given for method launch!",methname);
return false;
}
#endif
pthread_t thrid;
if(pthread_create (&thrid,NULL,(void *(*)(void *))meth,p)) {
error("%s - Could not launch method!",methname);
delete p;
return false;
}
else
return true;
}
class flext_base::qmsg
{
public:
qmsg(): nxt(NULL),tp(tp_none) {}
~qmsg();
qmsg *nxt;
void Clear();
void SetBang(outlet *o) { Clear(); out = o; tp = tp_bang; }
void SetFloat(outlet *o,float f) { Clear(); out = o; tp = tp_float; _float = f; }
void SetInt(outlet *o,int i) { Clear(); out = o; tp = tp_int; _int = i; }
void SetSymbol(outlet *o,const t_symbol *s) { Clear(); out = o; tp = tp_sym; _sym = s; }
void SetList(outlet *o,int argc,t_atom *argv) { Clear(); out = o; tp = tp_list; _list.argc = argc,_list.argv = flext_base::CopyList(argc,argv); }
void SetAny(outlet *o,const t_symbol *s,int argc,t_atom *argv) { Clear(); out = o; tp = tp_any; _any.s = s,_any.argc = argc,_any.argv = flext_base::CopyList(argc,argv); }
outlet *out;
enum { tp_none,tp_bang,tp_float,tp_int,tp_sym,tp_list,tp_any } tp;
union {
float _float;
int _int;
const t_symbol *_sym;
struct { int argc; t_atom *argv; } _list;
struct { const t_symbol *s; int argc; t_atom *argv; } _any;
};
void Add(qmsg *o);
};
flext_base::qmsg::~qmsg()
{
Clear();
if(nxt) delete nxt;
}
void flext_base::qmsg::Clear()
{
if(tp == tp_list) { if(_list.argv) delete[] _list.argv; }
else if(tp == tp_any) { if(_any.argv) delete[] _any.argv; }
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)
{
#ifdef DEBUG
if(!th->IsSystemThread()) {
error("Queue tick called by wrong thread!");
return;
}
#endif
pthread_mutex_lock(&th->qmutex);
while(th->qhead) {
qmsg *m = th->qhead;
switch(m->tp) {
case qmsg::tp_bang: th->ToOutBang(m->out); break;
case qmsg::tp_float: th->ToOutFloat(m->out,m->_float); break;
case qmsg::tp_int: th->ToOutInt(m->out,m->_int); break;
case qmsg::tp_sym: th->ToOutSymbol(m->out,m->_sym); break;
case qmsg::tp_list: th->ToOutList(m->out,m->_list.argc,m->_list.argv); break;
case qmsg::tp_any: th->ToOutAnything(m->out,m->_any.s,m->_any.argc,m->_any.argv); break;
#ifdef DEBUG
default: error("flext: Internal error in file " __FILE__ ", line " __LINE__ " - please report");
#endif
}
th->qhead = m->nxt;
if(!th->qhead) th->qtail = NULL;
m->nxt = NULL;
delete m;
}
pthread_mutex_unlock(&th->qmutex);
}
void flext_base::Queue(qmsg *m)
{
pthread_mutex_lock(&qmutex);
if(qhead) qtail->Add(m);
else qhead = qtail = m;
pthread_mutex_unlock(&qmutex);
clock_delay(qclk,0);
}
void flext_base::QueueBang(outlet *o)
{
qmsg *m = new qmsg();
m->SetBang(o);
Queue(m);
}
void flext_base::QueueFloat(outlet *o,float f)
{
qmsg *m = new qmsg;
m->SetFloat(o,f);
Queue(m);
}
void flext_base::QueueInt(outlet *o,int f)
{
qmsg *m = new qmsg;
m->SetInt(o,f);
Queue(m);
}
void flext_base::QueueSymbol(outlet *o,const t_symbol *s)
{
qmsg *m = new qmsg;
m->SetSymbol(o,s);
Queue(m);
}
void flext_base::QueueList(outlet *o,int argc,t_atom *argv)
{
qmsg *m = new qmsg;
m->SetList(o,argc,argv);
Queue(m);
}
void flext_base::QueueAnything(outlet *o,const t_symbol *s,int argc,t_atom *argv)
{
qmsg *m = new qmsg;
m->SetAny(o,s,argc,argv);
Queue(m);
}
#endif // FLEXT_THREADS
......@@ -20,7 +20,7 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#include <pthread.h>
class thr_params {
class flext_base::thr_params {
public:
thr_params(flext_base *c): cl(c) {}
......
/*
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.
*/
#include <flext.h>
#ifdef NT
#include <windows.h>
#endif
t_atom *flext_base::CopyList(int argc,const t_atom *argv)
{
int i;
t_atom *dst = new t_atom[argc];
for(i = 0; i < argc; ++i) CopyAtom(dst+i,argv+i);
return dst;
}
void flext_base::Sleep(int ms)
{
#ifdef NT
::Sleep(ms);
#else
#pragma message ("flext - Sleep not implemented!")
#endif
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment