aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/flext/source/flout.cpp
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2002-10-22 23:07:10 +0000
committerThomas Grill <xovo@users.sourceforge.net>2002-10-22 23:07:10 +0000
commitd62e56f4df9594f72ce501f5e19c974fd18e7295 (patch)
tree635d4af7a7c2425098e60ca277086ec436b617f7 /externals/grill/flext/source/flout.cpp
parentc6f373c281ecb5cd1f4aa7a070e15cc61ab8793c (diff)
This commit was generated by cvs2svn to compensate for changes in r186,
which included commits to RCS files with non-trunk default branches. svn path=/trunk/; revision=187
Diffstat (limited to 'externals/grill/flext/source/flout.cpp')
-rw-r--r--externals/grill/flext/source/flout.cpp201
1 files changed, 201 insertions, 0 deletions
diff --git a/externals/grill/flext/source/flout.cpp b/externals/grill/flext/source/flout.cpp
new file mode 100644
index 00000000..3b7c6bd9
--- /dev/null
+++ b/externals/grill/flext/source/flout.cpp
@@ -0,0 +1,201 @@
+/*
+
+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 flout.cpp
+ \brief Implementation of the flext outlet functionality.
+*/
+
+#include "flext.h"
+#include "flinternal.h"
+
+
+#ifdef MAXMSP
+#define CRITON() short state = lockout_set(1)
+#define CRITOFF() lockout_set(state)
+#else
+#define CRITON()
+#define CRITOFF()
+#endif
+
+#ifndef FLEXT_THREADS
+void flext_base::ToOutBang(outlet *o) { CRITON(); outlet_bang((t_outlet *)o); CRITOFF(); }
+void flext_base::ToOutFloat(outlet *o,float f) { CRITON(); outlet_float((t_outlet *)o,f); CRITOFF(); }
+void flext_base::ToOutInt(outlet *o,int f) { CRITON(); outlet_flint((t_outlet *)o,f); CRITOFF(); }
+void flext_base::ToOutSymbol(outlet *o,const t_symbol *s) { CRITON(); outlet_symbol((t_outlet *)o,const_cast<t_symbol *>(s)); CRITOFF(); }
+void flext_base::ToOutList(outlet *o,int argc,const t_atom *argv) { CRITON(); outlet_list((t_outlet *)o,gensym("list"),argc,(t_atom *)argv); CRITOFF(); }
+void flext_base::ToOutAnything(outlet *o,const t_symbol *s,int argc,const t_atom *argv) { CRITON(); outlet_anything((t_outlet *)o,const_cast<t_symbol *>(s),argc,(t_atom *)argv); CRITOFF(); }
+#else
+void flext_base::ToOutBang(outlet *o) { if(IsSystemThread()) { CRITON(); outlet_bang((t_outlet *)o); CRITOFF(); } else ToQueueBang(o); }
+void flext_base::ToOutFloat(outlet *o,float f) { if(IsSystemThread()) { CRITON(); outlet_float((t_outlet *)o,f); CRITOFF(); } else ToQueueFloat(o,f); }
+void flext_base::ToOutInt(outlet *o,int f) { if(IsSystemThread()) { CRITON(); outlet_flint((t_outlet *)o,f); CRITOFF(); } else ToQueueInt(o,f); }
+void flext_base::ToOutSymbol(outlet *o,const t_symbol *s) { if(IsSystemThread()) { CRITON(); outlet_symbol((t_outlet *)o,const_cast<t_symbol *>(s)); CRITOFF(); } else ToQueueSymbol(o,s); }
+void flext_base::ToOutList(outlet *o,int argc,const t_atom *argv) { if(IsSystemThread()) { CRITON(); outlet_list((t_outlet *)o,gensym("list"),argc,(t_atom *)argv); CRITOFF(); } else ToQueueList(o,argc,(t_atom *)argv); }
+void flext_base::ToOutAnything(outlet *o,const t_symbol *s,int argc,const t_atom *argv) { if(IsSystemThread()) { CRITON(); outlet_anything((t_outlet *)o,const_cast<t_symbol *>(s),argc,(t_atom *)argv); CRITOFF(); } else ToQueueAnything(o,s,argc,(t_atom *)argv); }
+#endif
+
+
+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,const t_atom *argv) { Clear(); out = o; tp = tp_list; _list.argc = argc,_list.argv = CopyList(argc,argv); }
+ void SetAny(outlet *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); }
+
+ 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("flext - Queue tick called by wrong thread!");
+ return;
+ }
+#endif
+
+#ifdef FLEXT_THREADS
+ th->qmutex.Lock();
+#endif
+ while(th->qhead) {
+ qmsg *m = th->qhead;
+
+#ifdef MAXMSP
+ short state = lockout_set(1);
+#endif
+
+ 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: ERRINTERNAL();
+#endif
+ }
+
+#ifdef MAXMSP
+ lockout_set(state);
+#endif
+
+ th->qhead = m->nxt;
+ if(!th->qhead) th->qtail = NULL;
+ m->nxt = NULL;
+ delete m;
+ }
+#ifdef FLEXT_THREADS
+ th->qmutex.Unlock();
+#endif
+}
+
+void flext_base::Queue(qmsg *m)
+{
+#ifdef FLEXT_THREADS
+ qmutex.Lock();
+#endif
+ if(qtail) qtail->nxt = m;
+ else qhead = m;
+ qtail = m;
+#ifdef FLEXT_THREADS
+ qmutex.Unlock();
+#endif
+#ifdef PD
+ clock_delay(qclk,0);
+#elif defined(MAXMSP)
+ clock_delay(yclk,0);
+#else
+ #error "To implement!"
+#endif
+}
+
+void flext_base::ToQueueBang(outlet *o)
+{
+ qmsg *m = new qmsg();
+ m->SetBang(o);
+ Queue(m);
+}
+
+void flext_base::ToQueueFloat(outlet *o,float f)
+{
+ qmsg *m = new qmsg;
+ m->SetFloat(o,f);
+ Queue(m);
+}
+
+void flext_base::ToQueueInt(outlet *o,int f)
+{
+ qmsg *m = new qmsg;
+ m->SetInt(o,f);
+ Queue(m);
+}
+
+void flext_base::ToQueueSymbol(outlet *o,const t_symbol *s)
+{
+ qmsg *m = new qmsg;
+ m->SetSymbol(o,s);
+ Queue(m);
+}
+
+void flext_base::ToQueueList(outlet *o,int argc,const t_atom *argv)
+{
+ qmsg *m = new qmsg;
+ m->SetList(o,argc,argv);
+ Queue(m);
+}
+
+void flext_base::ToQueueAnything(outlet *o,const t_symbol *s,int argc,const t_atom *argv)
+{
+ qmsg *m = new qmsg;
+ m->SetAny(o,s,argc,argv);
+ Queue(m);
+}
+