From f81282808b0d9147fc0c980e418c56774d1f6735 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Sat, 14 Jun 2003 02:32:39 +0000 Subject: "" svn path=/trunk/; revision=702 --- externals/grill/flext/source/flqueue.cpp | 178 ++++++++++++++++++++----------- 1 file changed, 118 insertions(+), 60 deletions(-) (limited to 'externals/grill/flext/source/flqueue.cpp') diff --git a/externals/grill/flext/source/flqueue.cpp b/externals/grill/flext/source/flqueue.cpp index 9d0b27c6..4c819ae7 100755 --- a/externals/grill/flext/source/flqueue.cpp +++ b/externals/grill/flext/source/flqueue.cpp @@ -19,10 +19,10 @@ WARRANTIES, see the file, "license.txt," in this distribution. #include "flext.h" #include "flinternal.h" -class flext_base::qmsg +class qmsg { public: - qmsg(): nxt(NULL),tp(tp_none) {} + qmsg(flext_base *b): th(b),nxt(NULL),tp(tp_none) {} ~qmsg(); qmsg *nxt; @@ -33,9 +33,10 @@ public: void SetFloat(int o,float f) { Clear(); out = o; tp = tp_float; _float = f; } void SetInt(int o,int i) { Clear(); out = o; tp = tp_int; _int = i; } void SetSymbol(int o,const t_symbol *s) { Clear(); out = o; tp = tp_sym; _sym = s; } - void SetList(int o,int argc,const t_atom *argv) { Clear(); out = o; tp = tp_list; _list.argc = argc,_list.argv = CopyList(argc,argv); } - void SetAny(int o,const t_symbol *s,int argc,const t_atom *argv) { Clear(); out = o; tp = tp_any; _any.s = s,_any.argc = argc,_any.argv = CopyList(argc,argv); } + void SetList(int o,int argc,const t_atom *argv) { Clear(); out = o; tp = tp_list; _list.argc = argc,_list.argv = flext::CopyList(argc,argv); } + void SetAny(int o,const t_symbol *s,int argc,const t_atom *argv) { Clear(); out = o; tp = tp_any; _any.s = s,_any.argc = argc,_any.argv = flext::CopyList(argc,argv); } + flext_base *th; int out; enum { tp_none,tp_bang,tp_float,tp_int,tp_sym,tp_list,tp_any } tp; union { @@ -47,43 +48,42 @@ public: }; }; -flext_base::qmsg::~qmsg() +qmsg::~qmsg() { Clear(); if(nxt) delete nxt; } -void flext_base::qmsg::Clear() +void 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; } -#if FLEXT_SYS == FLEXT_SYS_JMAX -void flext_base::QTick(fts_object_t *c, int winlet, fts_symbol_t s, int ac, const fts_atom_t *at) -{ - flext_base *th = thisObject(c); +static qmsg *qhead = NULL,*qtail = NULL; + +#ifdef FLEXT_QTHR +static flext::ThrCond qthrcond; #else -void flext_base::QTick(flext_base *th) -{ +static t_qelem *qclk = NULL; #endif -// post("qtick"); -#if defined(FLEXT_THREADS) && defined(FLEXT_DEBUG) && !defined(FLEXT_PDLOCK) - if(!th->IsSystemThread()) { - error("flext - Queue tick called by wrong thread!"); - return; - } + +#ifdef FLEXT_THREADS +static flext::ThrMutex qmutex; #endif +static void QWork(bool qlock,bool syslock) +{ #ifdef FLEXT_THREADS - th->qmutex.Lock(); + if(qlock) qmutex.Lock(); #endif -#ifdef FLEXT_PDLOCK - pd_lock(); +#ifdef FLEXT_QTHR + if(syslock) pd_lock(); #endif + for(;;) { - qmsg *m = th->qhead; + qmsg *m = qhead; if(!m) break; if(m->out < 0) { @@ -94,30 +94,30 @@ void flext_base::QTick(flext_base *th) switch(m->tp) { case qmsg::tp_bang: - th->m_methodmain(n,sym_bang,0,&tmp); + m->th->m_methodmain(n,flext::sym_bang,0,&tmp); break; case qmsg::tp_float: - SetFloat(tmp,m->_float); - th->m_methodmain(n,sym_float,1,&tmp); + flext::SetFloat(tmp,m->_float); + m->th->m_methodmain(n,flext::sym_float,1,&tmp); break; case qmsg::tp_int: - SetInt(tmp,m->_int); + flext::SetInt(tmp,m->_int); #if FLEXT_SYS == FLEXT_SYS_PD - th->m_methodmain(n,sym_float,1,&tmp); + m->th->m_methodmain(n,flext::sym_float,1,&tmp); #elif FLEXT_SYS == FLEXT_SYS_MAX - th->m_methodmain(n,sym_int,1,&tmp); + m->th->m_methodmain(n,flext::sym_int,1,&tmp); #else #error Not implemented! #endif case qmsg::tp_sym: - SetSymbol(tmp,m->_sym); - th->m_methodmain(n,sym_symbol,1,&tmp); + flext::SetSymbol(tmp,m->_sym); + m->th->m_methodmain(n,flext::sym_symbol,1,&tmp); break; case qmsg::tp_list: - th->m_methodmain(n,sym_list,m->_list.argc,m->_list.argv); + m->th->m_methodmain(n,flext::sym_list,m->_list.argc,m->_list.argv); break; case qmsg::tp_any: - th->m_methodmain(n,m->_any.s,m->_any.argc,m->_any.argv); + m->th->m_methodmain(n,m->_any.s,m->_any.argc,m->_any.argv); break; #ifdef FLEXT_DEBUG default: ERRINTERNAL(); @@ -128,32 +128,64 @@ void flext_base::QTick(flext_base *th) // message to outlet 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; + case qmsg::tp_bang: m->th->ToOutBang(m->out); break; + case qmsg::tp_float: m->th->ToOutFloat(m->out,m->_float); break; + case qmsg::tp_int: m->th->ToOutInt(m->out,m->_int); break; + case qmsg::tp_sym: m->th->ToOutSymbol(m->out,m->_sym); break; + case qmsg::tp_list: m->th->ToOutList(m->out,m->_list.argc,m->_list.argv); break; + case qmsg::tp_any: m->th->ToOutAnything(m->out,m->_any.s,m->_any.argc,m->_any.argv); break; #ifdef FLEXT_DEBUG default: ERRINTERNAL(); #endif } } - th->qhead = m->nxt; - if(!th->qhead) th->qtail = NULL; + qhead = m->nxt; + if(!qhead) qtail = NULL; m->nxt = NULL; delete m; } -#ifdef FLEXT_PDLOCK - pd_unlock(); +#ifdef FLEXT_QTHR + if(syslock) pd_unlock(); +#endif +#ifdef FLEXT_THREADS + if(qlock) qmutex.Unlock(); +#endif +} + +#if FLEXT_SYS == FLEXT_SYS_JMAX +static void QTick(fts_object_t *c,int winlet, fts_symbol_t s, int ac, const fts_atom_t *at) +{ +#else +static void QTick(flext_base *c) +{ +#endif +// post("qtick"); +#if defined(FLEXT_THREADS) && defined(FLEXT_DEBUG) && !defined(FLEXT_QTHR) + if(!flext::IsSystemThread()) { + error("flext - Queue tick called by wrong thread!"); + return; + } #endif + QWork(true,true); +} + +/* +It would be sufficient to only flush messages belonging to object th +But then the order of sent messages is not as intended +*/ +void flext_base::QFlush(flext_base *th) +{ #ifdef FLEXT_THREADS - th->qmutex.Unlock(); + if(!IsSystemThread()) { + error("flext - Queue flush called by wrong thread!"); + return; + } #endif + while(qhead) QWork(true,false); } -void flext_base::Queue(qmsg *m) +static void Queue(qmsg *m) { // post("Queue"); @@ -168,11 +200,11 @@ void flext_base::Queue(qmsg *m) #endif #if FLEXT_SYS == FLEXT_SYS_PD - #ifdef FLEXT_PDLOCK + #ifdef FLEXT_QTHR // wake up a worker thread // (instead of triggering the clock) - clock_delay(qclk,0); - #else + qthrcond.Signal(); + #else clock_delay(qclk,0); #endif #elif FLEXT_SYS == FLEXT_SYS_MAX @@ -181,50 +213,76 @@ void flext_base::Queue(qmsg *m) // this is dangerous because there may be other timers on this object! fts_timebase_add_call(fts_get_timebase(), (fts_object_t *)thisHdr(), QTick, NULL, 0); #else -#error +#error Not implemented +#endif +} + +#ifdef FLEXT_QTHR +void QWorker(flext::thr_params *) +{ + for(;;) { + qthrcond.Wait(); + QWork(true,true); + } +} +#endif + +void flext_base::StartQueue() +{ + // message queue ticker + qhead = qtail = NULL; + +#ifdef FLEXT_QTHR + LaunchThread(QWorker,NULL); +#else +#if FLEXT_SYS == FLEXT_SYS_PD || FLEXT_SYS == FLEXT_SYS_MAX + qclk = (t_qelem *)(qelem_new(NULL,(t_method)QTick)); +#else +#error Not implemented! +#endif #endif } void flext_base::ToQueueBang(int o) const { - qmsg *m = new qmsg(); + qmsg *m = new qmsg(const_cast(this)); m->SetBang(o); - const_cast(*this).Queue(m); + Queue(m); } void flext_base::ToQueueFloat(int o,float f) const { - qmsg *m = new qmsg; + qmsg *m = new qmsg(const_cast(this)); m->SetFloat(o,f); - const_cast(*this).Queue(m); + Queue(m); } void flext_base::ToQueueInt(int o,int f) const { - qmsg *m = new qmsg; + qmsg *m = new qmsg(const_cast(this)); m->SetInt(o,f); - const_cast(*this).Queue(m); + Queue(m); } void flext_base::ToQueueSymbol(int o,const t_symbol *s) const { - qmsg *m = new qmsg; + qmsg *m = new qmsg(const_cast(this)); m->SetSymbol(o,s); - const_cast(*this).Queue(m); + Queue(m); } void flext_base::ToQueueList(int o,int argc,const t_atom *argv) const { - qmsg *m = new qmsg; + qmsg *m = new qmsg(const_cast(this)); m->SetList(o,argc,argv); - const_cast(*this).Queue(m); + Queue(m); } void flext_base::ToQueueAnything(int o,const t_symbol *s,int argc,const t_atom *argv) const { - qmsg *m = new qmsg; + qmsg *m = new qmsg(const_cast(this)); m->SetAny(o,s,argc,argv); - const_cast(*this).Queue(m); + Queue(m); } -- cgit v1.2.1