aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--externals/grill/flext/changes.txt3
-rw-r--r--externals/grill/flext/source/flclass.h2
-rwxr-xr-xexternals/grill/flext/source/flmsg.cpp277
-rwxr-xr-xexternals/grill/flext/source/flqueue.cpp57
-rw-r--r--externals/grill/flext/source/flsupport.h14
-rw-r--r--externals/grill/flext/source/flthr.cpp2
-rw-r--r--externals/grill/flext/source/flutil.cpp16
7 files changed, 209 insertions, 162 deletions
diff --git a/externals/grill/flext/changes.txt b/externals/grill/flext/changes.txt
index 51057875..78352f2f 100644
--- a/externals/grill/flext/changes.txt
+++ b/externals/grill/flext/changes.txt
@@ -40,6 +40,9 @@ Version history:
- fixed bug for symbol messages into non-left inlets
- better timers for Windows
- slimmed down object data structures and changed initialization code accordingly
+- digest one-element float/int/symbol/pointer list messages as single atoms
+- simplified message analysis
+- made flext::Forward thread safe
0.4.7:
- added flext::GetBool (just because flext::GetInt has been there for a while)
diff --git a/externals/grill/flext/source/flclass.h b/externals/grill/flext/source/flclass.h
index c2e4600b..e8b68e69 100644
--- a/externals/grill/flext/source/flclass.h
+++ b/externals/grill/flext/source/flclass.h
@@ -867,8 +867,8 @@ private:
mutable ItemCont methhead;
mutable ItemCont *bindhead;
- bool CallMeth(const MethItem &m,int argc,const t_atom *argv);
bool FindMeth(int inlet,const t_symbol *s,int argc,const t_atom *argv);
+ bool FindMethAny(int inlet,const t_symbol *s,int argc,const t_atom *argv);
bool TryMethTag(Item *lst,const t_symbol *tag,int argc,const t_atom *argv);
bool TryMethSym(Item *lst,const t_symbol *s);
bool TryMethAny(Item *lst,const t_symbol *s,int argc,const t_atom *argv);
diff --git a/externals/grill/flext/source/flmsg.cpp b/externals/grill/flext/source/flmsg.cpp
index 9a57e4f2..d8a893b1 100755
--- a/externals/grill/flext/source/flmsg.cpp
+++ b/externals/grill/flext/source/flmsg.cpp
@@ -14,63 +14,6 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#include "flext.h"
-bool flext_base::CallMeth(const MethItem &m,int argc,const t_atom *argv)
-{
- bool ret = false;
- int ix;
- t_any aargs[FLEXT_MAXMETHARGS];
- bool ok = true;
- for(ix = 0; ix < argc && ok; ++ix) {
- switch(m.args[ix]) {
- case a_float: {
- if(IsFloat(argv[ix])) aargs[ix].ft = GetFloat(argv[ix]);
- else if(IsInt(argv[ix])) aargs[ix].ft = (float)GetInt(argv[ix]);
- else ok = false;
-
- if(ok) FLEXT_LOG2("int arg %i = %f",ix,aargs[ix].ft);
- break;
- }
- case a_int: {
- if(IsFloat(argv[ix])) aargs[ix].it = (int)GetFloat(argv[ix]);
- else if(IsInt(argv[ix])) aargs[ix].it = GetInt(argv[ix]);
- else ok = false;
-
- if(ok) FLEXT_LOG2("float arg %i = %i",ix,aargs[ix].it);
- break;
- }
- case a_symbol: {
- if(IsSymbol(argv[ix])) aargs[ix].st = GetSymbol(argv[ix]);
- else ok = false;
-
- if(ok) FLEXT_LOG2("symbol arg %i = %s",ix,GetString(aargs[ix].st));
- break;
- }
-#if FLEXT_SYS == FLEXT_SYS_PD
- case a_pointer: {
- if(IsPointer(argv[ix])) aargs[ix].pt = (t_gpointer *)GetPointer(argv[ix]);
- else ok = false;
- break;
- }
-#endif
- default:
- error("Argument type illegal");
- ok = false;
- }
- }
-
- if(ok && ix == argc) {
- switch(argc) {
- case 0: ret = ((methfun_0)m.fun)(this); break;
- case 1: ret = ((methfun_1)m.fun)(this,aargs[0]); break;
- case 2: ret = ((methfun_2)m.fun)(this,aargs[0],aargs[1]); break;
- case 3: ret = ((methfun_3)m.fun)(this,aargs[0],aargs[1],aargs[2]); break;
- case 4: ret = ((methfun_4)m.fun)(this,aargs[0],aargs[1],aargs[2],aargs[3]); break;
- case 5: ret = ((methfun_5)m.fun)(this,aargs[0],aargs[1],aargs[2],aargs[3],aargs[4]); break;
- }
- }
-
- return ret;
-}
bool flext_base::TryMethTag(Item *lst,const t_symbol *tag,int argc,const t_atom *argv)
{
@@ -89,20 +32,78 @@ bool flext_base::TryMethTag(Item *lst,const t_symbol *tag,int argc,const t_atom
}
else {
if(m->argc == 1) {
- // try list
- if(m->args[0] == a_list && ((methfun_V)m->fun)(this,argc,const_cast<t_atom *>(argv))) return true;
-
- // try anything
- if(m->args[0] == a_any && ((methfun_A)m->fun)(this,tag,argc,const_cast<t_atom *>(argv))) return true;
+ if(m->args[0] == a_list) {
+ // try list
+ if(((methfun_V)m->fun)(this,argc,const_cast<t_atom *>(argv))) return true;
+ }
+ else if(m->args[0] == a_any) {
+ // try anything
+ if(((methfun_A)m->fun)(this,tag,argc,const_cast<t_atom *>(argv))) return true;
+ }
}
// try matching number of args
- if(argc == m->argc && CallMeth(*m,argc,argv)) return true;
+ if(m->argc == argc) {
+ int ix;
+ t_any aargs[FLEXT_MAXMETHARGS];
+ bool ok = true;
+ for(ix = 0; ix < argc && ok; ++ix) {
+ switch(m->args[ix]) {
+ case a_float: {
+ if(IsFloat(argv[ix])) aargs[ix].ft = GetFloat(argv[ix]);
+ else if(IsInt(argv[ix])) aargs[ix].ft = (float)GetInt(argv[ix]);
+ else ok = false;
+
+ if(ok) FLEXT_LOG2("int arg %i = %f",ix,aargs[ix].ft);
+ break;
+ }
+ case a_int: {
+ if(IsFloat(argv[ix])) aargs[ix].it = (int)GetFloat(argv[ix]);
+ else if(IsInt(argv[ix])) aargs[ix].it = GetInt(argv[ix]);
+ else ok = false;
+
+ if(ok) FLEXT_LOG2("float arg %i = %i",ix,aargs[ix].it);
+ break;
+ }
+ case a_symbol: {
+ if(IsSymbol(argv[ix])) aargs[ix].st = GetSymbol(argv[ix]);
+ else ok = false;
+
+ if(ok) FLEXT_LOG2("symbol arg %i = %s",ix,GetString(aargs[ix].st));
+ break;
+ }
+#if FLEXT_SYS == FLEXT_SYS_PD
+ case a_pointer: {
+ if(IsPointer(argv[ix])) aargs[ix].pt = (t_gpointer *)GetPointer(argv[ix]);
+ else ok = false;
+ break;
+ }
+#endif
+ default:
+ error("Argument type illegal");
+ ok = false;
+ }
+ }
+
+ if(ok && ix == argc) {
+ switch(argc) {
+ case 0: return ((methfun_0)m->fun)(this);
+ case 1: return ((methfun_1)m->fun)(this,aargs[0]);
+ case 2: return ((methfun_2)m->fun)(this,aargs[0],aargs[1]);
+ case 3: return ((methfun_3)m->fun)(this,aargs[0],aargs[1],aargs[2]);
+ case 4: return ((methfun_4)m->fun)(this,aargs[0],aargs[1],aargs[2],aargs[3]);
+ case 5: return ((methfun_5)m->fun)(this,aargs[0],aargs[1],aargs[2],aargs[3],aargs[4]);
+ default:
+ FLEXT_ASSERT(false);
+ }
+ }
+ }
}
}
return false;
}
+/*
bool flext_base::TryMethSym(Item *lst,const t_symbol *s)
{
for(; lst; lst = lst->nxt) {
@@ -117,6 +118,7 @@ bool flext_base::TryMethSym(Item *lst,const t_symbol *s)
}
return false;
}
+*/
bool flext_base::TryMethAny(Item *lst,const t_symbol *s,int argc,const t_atom *argv)
{
@@ -143,19 +145,27 @@ bool flext_base::FindMeth(int inlet,const t_symbol *s,int argc,const t_atom *arg
// search for exactly matching tag
if((lst = methhead.FindList(s,inlet)) != NULL && TryMethTag(lst,s,argc,argv)) return true;
if((lst = clmethhead->FindList(s,inlet)) != NULL && TryMethTag(lst,s,argc,argv)) return true;
-
- // if no list args, then search for pure symbol
- if(!argc) {
- if((lst = methhead.FindList(sym_symbol,inlet)) != NULL && TryMethSym(lst,s)) return true;
- if((lst = clmethhead->FindList(sym_symbol,inlet)) != NULL && TryMethSym(lst,s)) return true;
- }
-
- // otherwise search for anything
+
+ // if nothing found try any inlet
+ if((lst = methhead.FindList(s,-1)) != NULL && TryMethTag(lst,s,argc,argv)) return true;
+ if((lst = clmethhead->FindList(s,-1)) != NULL && TryMethTag(lst,s,argc,argv)) return true;
+
+ return false;
+}
+
+bool flext_base::FindMethAny(int inlet,const t_symbol *s,int argc,const t_atom *argv)
+{
+ Item *lst;
+ ItemCont *clmethhead = ClMeths(thisClassId());
+
if((lst = methhead.FindList(sym_anything,inlet)) != NULL && TryMethAny(lst,s,argc,argv)) return true;
if((lst = clmethhead->FindList(sym_anything,inlet)) != NULL && TryMethAny(lst,s,argc,argv)) return true;
// if nothing found try any inlet
- return inlet >= 0 && FindMeth(-1,s,argc,argv);
+ if((lst = methhead.FindList(sym_anything,-1)) != NULL && TryMethAny(lst,s,argc,argv)) return true;
+ if((lst = clmethhead->FindList(sym_anything,-1)) != NULL && TryMethAny(lst,s,argc,argv)) return true;
+
+ return false;
}
/*! \brief All the message processing
@@ -164,72 +174,76 @@ bool flext_base::FindMeth(int inlet,const t_symbol *s,int argc,const t_atom *arg
bool flext_base::CbMethodHandler(int inlet,const t_symbol *s,int argc,const t_atom *argv)
{
static bool trap = false;
+ bool ret;
curtag = s;
// post("methodmain inlet:%i args:%i symbol:%s",inlet,argc,s?GetString(s):"");
- bool ret = FindMeth(inlet,s,argc,argv);
- if(ret) goto end;
-
try {
-
-#if FLEXT_SYS == FLEXT_SYS_MAX
- // If float message is not explicitly handled: try int handler instead
- if(argc == 1 && s == sym_float && !trap) {
- t_atom fl;
- SetInt(fl,GetAInt(argv[0]));
- trap = true;
- ret = CbMethodHandler(inlet,sym_int,1,&fl);
- trap = false;
- }
+ ret = FindMeth(inlet,s,argc,argv);
if(ret) goto end;
-
- // If int message is not explicitly handled: try float handler instead
- if(argc == 1 && s == sym_int && !trap) {
- t_atom fl;
- SetFloat(fl,GetAFloat(argv[0]));
- trap = true;
- ret = CbMethodHandler(inlet,sym_float,1,&fl);
- trap = false;
- }
- if(ret) goto end;
-#endif
-
- // If float or int message is not explicitly handled: try list handler instead
- if(!trap && argc == 1 && (s == sym_float || s == sym_symbol
-#if FLEXT_SYS == FLEXT_SYS_MAX
- || s == sym_int
-#endif
- )) {
- t_atom list;
- if(s == sym_float)
- SetFloat(list,GetFloat(argv[0]));
-#if FLEXT_SYS == FLEXT_SYS_MAX
- else if(s == sym_int)
- SetInt(list,GetInt(argv[0]));
-#endif
- else if(s == sym_symbol)
- SetSymbol(list,GetSymbol(argv[0]));
- trap = true;
- ret = CbMethodHandler(inlet,sym_list,1,&list);
- trap = false;
+ if(argc == 1) {
+ if(s == sym_list) {
+ // for 1-element lists try the single atom (this is the format output by [route])
+ if(IsFloat(argv[0]))
+ ret = FindMeth(inlet,sym_float,1,argv);
+ else if(IsInt(argv[0]))
+ ret = FindMeth(inlet,sym_int,1,argv);
+ else if(IsSymbol(argv[0]))
+ ret = FindMeth(inlet,sym_symbol,1,argv);
+ else if(IsPointer(argv[0]))
+ ret = FindMeth(inlet,sym_pointer,1,argv);
+ if(ret) goto end;
+ }
+ else {
+ if(s == sym_float) {
+ #if FLEXT_SYS == FLEXT_SYS_MAX
+ t_atom at;
+ // If float message is not explicitly handled: try int handler instead
+ SetInt(at,(int)GetFloat(argv[0]));
+ ret = FindMeth(inlet,sym_int,1,&at);
+ if(ret) goto end;
+ #endif
+ // If not explicitly handled: try list handler instead
+ ret = FindMeth(inlet,sym_list,1,argv);
+ if(ret) goto end;
+ }
+ #if FLEXT_SYS == FLEXT_SYS_MAX
+ else if(s == sym_int) {
+ t_atom at;
+ // If int message is not explicitly handled: try float handler instead
+ SetFloat(at,(float)GetInt(argv[0]));
+ ret = FindMeth(inlet,sym_float,1,&at);
+ if(ret) goto end;
+ // If not explicitly handled: try list handler instead
+ ret = FindMeth(inlet,sym_list,1,argv);
+ if(ret) goto end;
+ }
+ #endif
+ else if(s == sym_symbol) {
+ ret = FindMeth(inlet,sym_list,1,argv);
+ if(ret) goto end;
+ }
+ #if FLEXT_SYS == FLEXT_SYS_PD
+ else if(s == sym_pointer) {
+ ret = FindMeth(inlet,sym_list,1,argv);
+ if(ret) goto end;
+ }
+ #endif
+ }
}
- if(ret) goto end;
-
- // If symbol message (pure anything without args) is not explicitly handled: try list handler instead
- if(!trap && argc == 0) {
- t_atom list;
- SetSymbol(list,s);
- trap = true;
- ret = CbMethodHandler(inlet,sym_list,1,&list);
- trap = false;
+ else if(argc == 0) {
+ // If symbol message (pure anything without args) is not explicitly handled: try list handler instead
+ t_atom at;
+ SetSymbol(at,s);
+ ret = FindMeth(inlet,sym_list,1,&at);
+ if(ret) goto end;
}
- if(ret) goto end;
// if distmsgs is switched on then distribute list elements over inlets (Max/MSP behavior)
- if(DoDist() && !trap && inlet == 0 && s == sym_list && insigs <= 1) {
+ if(DoDist() && inlet == 0 && s == sym_list && insigs <= 1 && !trap) {
int i = incnt;
if(i > argc) i = argc;
for(--i; i >= 0; --i) { // right to left distribution
@@ -237,20 +251,21 @@ bool flext_base::CbMethodHandler(int inlet,const t_symbol *s,int argc,const t_at
if(IsFloat(argv[i])) sym = sym_float;
else if(IsInt(argv[i])) sym = sym_int;
else if(IsSymbol(argv[i])) sym = sym_symbol;
-#if FLEXT_SYS == FLEXT_SYS_PD
else if(IsPointer(argv[i])) sym = sym_pointer; // can pointer atoms occur here?
-#endif
+
if(sym) {
trap = true;
- CbMethodHandler(i,sym,1,argv+i);
+ CbMethodHandler(i,sym,1,argv+i);
trap = false;
}
}
- ret = true;
+ goto end;
}
- if(!ret && !trap) ret = CbMethodResort(inlet,s,argc,argv);
+ ret = FindMethAny(inlet,s,argc,argv);
+
+ if(!ret) ret = CbMethodResort(inlet,s,argc,argv);
}
catch(std::exception &x) {
error("%s - Exception while processing method: %s",thisName(),x.what());
diff --git a/externals/grill/flext/source/flqueue.cpp b/externals/grill/flext/source/flqueue.cpp
index 1cf2aab5..a9077230 100755
--- a/externals/grill/flext/source/flqueue.cpp
+++ b/externals/grill/flext/source/flqueue.cpp
@@ -49,20 +49,35 @@ public:
return *this;
}
+ inline qmsg &Set(const t_symbol *r,const t_symbol *s,int ac,const t_atom *av)
+ {
+ th = NULL;
+ recv = r;
+ msg(s,ac,av);
+ return *this;
+ }
+
// \note PD sys lock must already be held by caller
inline void Send() const
{
- if(out < 0)
- // message to self
- th->CbMethodHandler(-1-out,msg.Header(),msg.Count(),msg.Atoms());
+ if(th) {
+ if(out < 0)
+ // message to self
+ th->CbMethodHandler(-1-out,msg.Header(),msg.Count(),msg.Atoms());
+ else
+ // message to outlet
+ th->ToSysAnything(out,msg.Header(),msg.Count(),msg.Atoms());
+ }
else
- // message to outlet
- th->ToSysAnything(out,msg.Header(),msg.Count(),msg.Atoms());
+ flext::Forward(recv,msg,true);
}
private:
flext_base *th;
- int out;
+ union {
+ int out;
+ const t_symbol *recv;
+ };
AtomAnything msg;
};
@@ -86,6 +101,15 @@ public:
Trigger();
}
+ inline void Push(const t_symbol *r,const t_symbol *s,int ac,const t_atom *av)
+ {
+ qmsg *m = QueueFifo::New();
+ FLEXT_ASSERT(m);
+ m->Set(r,s,ac,av);
+ Put(m);
+ Trigger();
+ }
+
inline void Push(flext_base *th,int o) // bang
{
Push(th,o,sym_bang,0,NULL);
@@ -336,3 +360,24 @@ void flext_base::ToQueueAnything(int o,const t_symbol *s,int argc,const t_atom *
{
queue.Push(const_cast<flext_base *>(this),o,s,argc,argv);
}
+
+
+bool flext::Forward(const t_symbol *recv,const t_symbol *s,int argc,const t_atom *argv,bool direct)
+{
+ if(direct || IsSystemThread()) {
+ void *cl = recv->s_thing;
+ if(!cl) return false;
+
+#if FLEXT_SYS == FLEXT_SYS_PD
+ pd_typedmess((t_class **)cl,(t_symbol *)s,argc,(t_atom *)argv);
+#elif FLEXT_SYS == FLEXT_SYS_MAX
+ typedmess(recv->s_thing,(t_symbol *)s,argc,(t_atom *)argv);
+#else
+#error Not implemented
+#endif
+ }
+ else
+ // send over queue
+ queue.Push(recv,s,argc,argv);
+ return true;
+}
diff --git a/externals/grill/flext/source/flsupport.h b/externals/grill/flext/source/flsupport.h
index e38697f4..31fe91ff 100644
--- a/externals/grill/flext/source/flsupport.h
+++ b/externals/grill/flext/source/flsupport.h
@@ -681,7 +681,7 @@ public:
explicit AtomListStatic(const AtomList &a): AtomListStaticBase(PRE,pre) { AtomList::operator =(a); }
//! Set list by another AtomList
- AtomListStatic &operator =(const AtomListStatic &a) { AtomList::operator =(a); return *this; }
+ AtomListStatic &operator =(const AtomList &a) { AtomList::operator =(a); return *this; }
protected:
t_atom pre[PRE];
};
@@ -742,15 +742,15 @@ public:
*/
//! Send a message to a symbol (bound to an object)
- static bool Forward(const t_symbol *sym,const t_symbol *s,int argc,const t_atom *argv);
+ static bool Forward(const t_symbol *sym,const t_symbol *s,int argc,const t_atom *argv,bool forcedirect = false);
- static bool Forward(const t_symbol *sym,AtomAnything &args) { return Forward(sym,args.Header(),args.Count(),args.Atoms()); }
- static bool Forward(const char *sym,AtomAnything &args) { return Forward(MakeSymbol(sym),args.Header(),args.Count(),args.Atoms()); }
+ static bool Forward(const t_symbol *sym,const AtomAnything &args,bool forcedirect = false) { return Forward(sym,args.Header(),args.Count(),args.Atoms(),forcedirect); }
+ static bool Forward(const char *sym,const AtomAnything &args,bool forcedirect = false) { return Forward(MakeSymbol(sym),args.Header(),args.Count(),args.Atoms(),forcedirect); }
- static bool Forward(const t_symbol *sym,int argc,const t_atom *argv) { return Forward(sym,sym_list,argc,argv); }
+ static bool Forward(const t_symbol *sym,int argc,const t_atom *argv,bool forcedirect = false) { return Forward(sym,sym_list,argc,argv,forcedirect); }
- static bool Forward(const t_symbol *sym,AtomList &args) { return Forward(sym,args.Count(),args.Atoms()); }
- static bool Forward(const char *sym,AtomList &args) { return Forward(MakeSymbol(sym),args.Count(),args.Atoms()); }
+ static bool Forward(const t_symbol *sym,const AtomList &args,bool forcedirect = false) { return Forward(sym,args.Count(),args.Atoms(),forcedirect); }
+ static bool Forward(const char *sym,const AtomList &args,bool forcedirect = false) { return Forward(MakeSymbol(sym),args.Count(),args.Atoms(),forcedirect); }
//! @} FLEXT_S_MSG
diff --git a/externals/grill/flext/source/flthr.cpp b/externals/grill/flext/source/flthr.cpp
index 56a9c9a2..f56ab096 100644
--- a/externals/grill/flext/source/flthr.cpp
+++ b/externals/grill/flext/source/flthr.cpp
@@ -625,7 +625,7 @@ bool flext::ThrCond::TimedWait(double ftm)
ftime(&tmb);
#endif
tm.tv_nsec = tmb.millitm*1000000;
- tm.tv_sec = tmb.time;
+ tm.tv_sec = (long)tmb.time;
#else // POSIX
#if 0 // find out when the following is defined
clock_gettime(CLOCK_REALTIME,tm);
diff --git a/externals/grill/flext/source/flutil.cpp b/externals/grill/flext/source/flutil.cpp
index b4aba60c..3437ee75 100644
--- a/externals/grill/flext/source/flutil.cpp
+++ b/externals/grill/flext/source/flutil.cpp
@@ -46,19 +46,3 @@ void flext::ZeroMem(void *dst,int bytes)
memset(dst,0,bytes);
#endif
}
-
-
-bool flext::Forward(const t_symbol *recv,const t_symbol *s,int argc,const t_atom *argv)
-{
- void *cl = recv->s_thing;
- if(!cl) return false;
-
-#if FLEXT_SYS == FLEXT_SYS_PD
- pd_typedmess((t_class **)cl,(t_symbol *)s,argc,(t_atom *)argv);
-#elif FLEXT_SYS == FLEXT_SYS_MAX
- typedmess(recv->s_thing,(t_symbol *)s,argc,(t_atom *)argv);
-#else
-#error Not implemented
-#endif
- return true;
-}