aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/py/source
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2005-03-13 04:59:47 +0000
committerThomas Grill <xovo@users.sourceforge.net>2005-03-13 04:59:47 +0000
commit3ce0fb7e8ad57909fadcd4072817d69bc54e3a66 (patch)
treef4d4478420cc9f34bf26835f2edc5bd03f95a86b /externals/grill/py/source
parent0e0bfeecb60ffa25d997830553685482c666b7ba (diff)
pydsp: share dsp buffer objects at inplace operation
DSP support for py/pyext: new objects pyext~,pyx~,pyext.~,pyx.~ new base class for py and pyext classes preset sys.argv for module loading support for buffer objects (preliminary) py: bang in left inlet now really triggers without arguments fixes for detached operation and single-threaded version little restructuring adjust pd and py files for correct argument passing more optimizations update for new flext callback naming use lock count instead of message queuing to avoid py->py messaging deadlock pyext: fix for inlet count svn path=/trunk/; revision=2624
Diffstat (limited to 'externals/grill/py/source')
-rw-r--r--externals/grill/py/source/bound.cpp6
-rw-r--r--externals/grill/py/source/clmeth.cpp59
-rw-r--r--externals/grill/py/source/main.cpp111
-rw-r--r--externals/grill/py/source/main.h47
-rw-r--r--externals/grill/py/source/modmeth.cpp34
-rw-r--r--externals/grill/py/source/py.cpp83
-rw-r--r--externals/grill/py/source/pyargs.cpp4
-rw-r--r--externals/grill/py/source/pybuffer.cpp22
-rw-r--r--externals/grill/py/source/pydsp.cpp179
-rw-r--r--externals/grill/py/source/pyext.cpp104
-rw-r--r--externals/grill/py/source/pyext.h63
-rw-r--r--externals/grill/py/source/register.cpp18
12 files changed, 535 insertions, 195 deletions
diff --git a/externals/grill/py/source/bound.cpp b/externals/grill/py/source/bound.cpp
index 5690e0b1..1d10c2d3 100644
--- a/externals/grill/py/source/bound.cpp
+++ b/externals/grill/py/source/bound.cpp
@@ -62,7 +62,7 @@ struct bounddata
bool pyext::boundmeth(flext_base *th,t_symbol *sym,int argc,t_atom *argv,void *data)
{
bounddata *obj = (bounddata *)data;
- py *pyth = static_cast<py *>(th);
+ pyext *pyth = static_cast<pyext *>(th);
PyThreadState *state = pyth->PyLock();
@@ -92,7 +92,7 @@ PyObject *pyext::pyext_bind(PyObject *,PyObject *args)
post("py/pyext - Wrong argument types!");
}
else {
- py *th = GetThis(self);
+ pyext *th = GetThis(self);
FLEXT_ASSERT(th);
const t_symbol *recv = pyObject_AsSymbol(name);
@@ -134,7 +134,7 @@ PyObject *pyext::pyext_unbind(PyObject *,PyObject *args)
post("py/pyext - Wrong argument types!");
}
else {
- py *th = GetThis(self);
+ pyext *th = GetThis(self);
FLEXT_ASSERT(th);
const t_symbol *recv = pyObject_AsSymbol(name);
diff --git a/externals/grill/py/source/clmeth.cpp b/externals/grill/py/source/clmeth.cpp
index 6062eda9..cfd8604a 100644
--- a/externals/grill/py/source/clmeth.cpp
+++ b/externals/grill/py/source/clmeth.cpp
@@ -29,6 +29,9 @@ PyMethodDef pyext::meth_tbl[] =
{ "_stop", pyext::pyext_stop, METH_VARARGS,"Stop running threads" },
#endif
{ "_isthreaded", pyext::pyext_isthreaded, METH_O,"Query whether threading is enabled" },
+
+ { "_invec", pyext::pyext_invec, METH_VARARGS,"Get input vector" },
+ { "_outvec", pyext::pyext_outvec, METH_VARARGS,"Get output vector" },
{NULL, NULL, 0, NULL} /* Sentinel */
};
@@ -36,7 +39,7 @@ PyMethodDef pyext::attr_tbl[] =
{
{ "__setattr__", pyext::pyext_setattr, METH_VARARGS,"Set class attribute" },
{ "__getattr__", pyext::pyext_getattr, METH_VARARGS,"Get class attribute" },
- { NULL, NULL,0,NULL },
+ { NULL, NULL,0,NULL },
};
@@ -174,6 +177,9 @@ PyObject *pyext::pyext_outlet(PyObject *,PyObject *args)
if(lst) {
int o = PyInt_AsLong(outl);
if(o >= 1 && o <= ext->Outlets()) {
+ // offset outlet by signal outlets
+ o += ext->sigoutlets;
+
// by using the queue there is no immediate call of the next object
// deadlock would occur if this was another py/pyext object!
if(lst->Count() && IsSymbol((*lst)[0]))
@@ -195,7 +201,10 @@ PyObject *pyext::pyext_outlet(PyObject *,PyObject *args)
if(!tp) Py_DECREF(val);
}
- if(!ok) post("pyext - Syntax: _outlet(self,outlet,args...)");
+ if(!ok) {
+ PyErr_SetString(PyExc_SyntaxError,"pyext - Syntax: _outlet(self,outlet,args...)");
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
@@ -211,7 +220,8 @@ PyObject *pyext::pyext_detach(PyObject *,PyObject *args)
int val;
if(!PyArg_ParseTuple(args, "Oi:pyext_detach",&self,&val)) {
// handle error
- post("pyext - Syntax: _detach(self,[0/1])");
+ PyErr_SetString(PyExc_SyntaxError,"pyext - Syntax: _detach(self,[0/1])");
+ return NULL;
}
else {
pyext *ext = GetThis(self);
@@ -229,7 +239,8 @@ PyObject *pyext::pyext_stop(PyObject *,PyObject *args)
int val = -1;
if(!PyArg_ParseTuple(args, "O|i:pyext_stop",&self,&val)) {
// handle error
- post("pyext - Syntax: _stop(self,{wait time}");
+ PyErr_SetString(PyExc_SyntaxError,"pyext - Syntax: _stop(self,{wait time})");
+ return NULL;
}
else {
pyext *ext = GetThis(self);
@@ -305,12 +316,50 @@ PyObject *pyext::pyext_tocanvas(PyObject *,PyObject *args)
if(!tp) Py_DECREF(val);
}
- if(!ok) post("pyext - Syntax: _tocanvas(self,args...)");
+ if(!ok) {
+ PyErr_SetString(PyExc_SyntaxError,"pyext - Syntax: _tocanvas(self,args...)");
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
}
#endif
+PyObject *pyext::pyext_invec(PyObject *,PyObject *args)
+{
+ PyObject *self;
+ int val = -1;
+ if(!PyArg_ParseTuple(args, "O|i:pyext_invec",&self,&val)) {
+ // handle error
+ PyErr_SetString(PyExc_SyntaxError,"pyext - Syntax: _invec(self,inlet)");
+ return NULL;
+ }
+ else {
+ pyext *ext = GetThis(self);
+ PyObject *b = ext->GetSig(val,true);
+ if(b) return b;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+PyObject *pyext::pyext_outvec(PyObject *,PyObject *args)
+{
+ PyObject *self;
+ int val = -1;
+ if(!PyArg_ParseTuple(args, "O|i:pyext_outvec",&self,&val)) {
+ // handle error
+ PyErr_SetString(PyExc_SyntaxError,"pyext - Syntax: _outvec(self,inlet)");
+ return NULL;
+ }
+ else {
+ pyext *ext = GetThis(self);
+ PyObject *b = ext->GetSig(val,false);
+ if(b) return b;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
diff --git a/externals/grill/py/source/main.cpp b/externals/grill/py/source/main.cpp
index e32b9ba8..aa234cc4 100644
--- a/externals/grill/py/source/main.cpp
+++ b/externals/grill/py/source/main.cpp
@@ -13,7 +13,7 @@ WARRANTIES, see the file, "license.txt," in this distribution.
static PyMethodDef StdOut_Methods[] =
{
- { "write", py::StdOut_Write, 1 },
+ { "write", pybase::StdOut_Write, 1 },
{ NULL, NULL, }
};
@@ -27,9 +27,9 @@ static PyInterpreterState *pymain = NULL;
static PyThreadState *pythrmain = NULL;
static PyThrMap pythrmap;
-int py::lockcount = 0;
+int pybase::lockcount = 0;
-PyThreadState *py::FindThreadState()
+PyThreadState *pybase::FindThreadState()
{
flext::thrid_t id = flext::GetThreadId();
PyThrMap::iterator it = pythrmap.find(id);
@@ -43,7 +43,7 @@ PyThreadState *py::FindThreadState()
return it->second;
}
-void py::FreeThreadState()
+void pybase::FreeThreadState()
{
flext::thrid_t id = flext::GetThreadId();
PyThrMap::iterator it = pythrmap.find(id);
@@ -59,10 +59,16 @@ void py::FreeThreadState()
#endif
+PyObject *pybase::module_obj = NULL;
+PyObject *pybase::module_dict = NULL;
+
+PyObject *pybase::emptytuple = NULL;
+
+
void initsymbol();
void initsamplebuffer();
-void py::lib_setup()
+void pybase::lib_setup()
{
post("");
post("------------------------------------------------");
@@ -137,10 +143,13 @@ void py::lib_setup()
initsamplebuffer();
PyModule_AddObject(module_obj,"Buffer",(PyObject *)&pySamplebuffer_Type);
+ emptytuple = PyTuple_New(0);
+
// -------------------------------------------------------------
FLEXT_SETUP(pyobj);
FLEXT_SETUP(pyext);
+ FLEXT_DSP_SETUP(pydsp);
#ifdef FLEXT_THREADS
// release global lock
@@ -151,24 +160,10 @@ void py::lib_setup()
post("");
}
-FLEXT_LIB_SETUP(py,py::lib_setup)
+FLEXT_LIB_SETUP(py,pybase::lib_setup)
-PyObject *py::module_obj = NULL;
-PyObject *py::module_dict = NULL;
-
-
-void py::Setup(t_classid c)
-{
- FLEXT_CADDMETHOD_(c,0,"doc",m_doc);
- FLEXT_CADDMETHOD_(c,0,"dir",m_dir);
-#ifdef FLEXT_THREADS
- FLEXT_CADDATTR_VAR1(c,"detach",detach);
- FLEXT_CADDMETHOD_(c,0,"stop",m_stop);
-#endif
-}
-
-py::py()
+pybase::pybase()
: module(NULL),detach(0)
#ifdef FLEXT_THREADS
, shouldexit(false),thrcount(0),stoptick(0)
@@ -177,23 +172,16 @@ py::py()
PyThreadState *state = PyLock();
Py_INCREF(module_obj);
PyUnlock(state);
-
-#ifdef FLEXT_THREADS
- FLEXT_ADDTIMER(stoptmr,tick);
-
- // launch thread worker
- FLEXT_CALLMETHOD(threadworker);
-#endif
}
-py::~py()
+pybase::~pybase()
{
PyThreadState *state = PyLock();
Py_XDECREF(module_obj);
PyUnlock(state);
}
-void py::Exit()
+void pybase::Exit()
{
#ifdef FLEXT_THREADS
shouldexit = true;
@@ -204,16 +192,15 @@ void py::Exit()
Sleep(PY_STOP_TICK*0.001f);
if(thrcount) {
// Wait forever
- post("%s - Waiting for thread termination!",thisName());
+ post("py/pyext - Waiting for thread termination!");
while(thrcount) Sleep(PY_STOP_TICK*0.001f);
- post("%s - Okay, all threads have terminated",thisName());
+ post("py/pyext - Okay, all threads have terminated");
}
}
#endif
- flext_base::Exit();
}
-void py::GetDir(PyObject *obj,AtomList &lst)
+void pybase::GetDir(PyObject *obj,AtomList &lst)
{
if(obj) {
PyThreadState *state = PyLock();
@@ -227,7 +214,7 @@ void py::GetDir(PyObject *obj,AtomList &lst)
lst = *l; delete l;
}
else
- post("%s - %s: List could not be created",thisName(),GetString(thisTag()));
+ post("py/pyext - Argument list could not be created");
Py_DECREF(pvar);
}
@@ -235,15 +222,15 @@ void py::GetDir(PyObject *obj,AtomList &lst)
}
}
-void py::m__dir(PyObject *obj)
+void pybase::m__dir(PyObject *obj)
{
AtomList lst;
GetDir(obj,lst);
// dump dir to attribute outlet
- ToOutAnything(GetOutAttr(),thisTag(),lst.Count(),lst.Atoms());
+ DumpOut(NULL,lst.Count(),lst.Atoms());
}
-void py::m__doc(PyObject *obj)
+void pybase::m__doc(PyObject *obj)
{
if(obj) {
PyThreadState *state = PyLock();
@@ -279,19 +266,19 @@ void py::m__doc(PyObject *obj)
}
}
-void py::m_click()
+void pybase::OpenEditor()
{
// this should once open the editor....
}
-void py::SetArgs(int argc,const t_atom *argv)
+void pybase::SetArgs(int argc,const t_atom *argv)
{
// script arguments
char **sargv = new char *[argc+1];
for(int i = 0; i <= argc; ++i) {
sargv[i] = new char[256];
if(!i)
- strcpy(sargv[i],thisName());
+ strcpy(sargv[i],"py/pyext");
else
GetAString(argv[i-1],sargv[i],255);
}
@@ -303,7 +290,7 @@ void py::SetArgs(int argc,const t_atom *argv)
delete[] sargv;
}
-void py::ImportModule(const char *name)
+void pybase::ImportModule(const char *name)
{
if(!name) return;
@@ -316,7 +303,7 @@ void py::ImportModule(const char *name)
dict = PyModule_GetDict(module);
}
-void py::UnimportModule()
+void pybase::UnimportModule()
{
if(!module) return;
@@ -332,7 +319,7 @@ void py::UnimportModule()
dict = NULL;
}
-void py::ReloadModule()
+void pybase::ReloadModule()
{
if(module) {
PyObject *newmod = PyImport_ReloadModule(module);
@@ -348,10 +335,10 @@ void py::ReloadModule()
}
}
else
- post("%s - No module to reload",thisName());
+ post("py/pyext - No module to reload");
}
-void py::GetModulePath(const char *mod,char *dir,int len)
+void pybase::GetModulePath(const char *mod,char *dir,int len)
{
#if FLEXT_SYS == FLEXT_SYS_PD
// uarghh... pd doesn't show its path for extra modules
@@ -394,7 +381,7 @@ void py::GetModulePath(const char *mod,char *dir,int len)
#endif
}
-void py::AddToPath(const char *dir)
+void pybase::AddToPath(const char *dir)
{
if(dir && *dir) {
PyObject *pobj = PySys_GetObject("path");
@@ -410,12 +397,12 @@ void py::AddToPath(const char *dir)
static const t_symbol *sym_response = flext::MakeSymbol("response");
-void py::Respond(bool b)
+void pybase::Respond(bool b)
{
if(respond) {
t_atom a;
SetBool(a,b);
- ToOutAnything(GetOutAttr(),sym_response,1,&a);
+ DumpOut(sym_response,1,&a);
}
}
@@ -424,7 +411,7 @@ void py::Respond(bool b)
static PyObject *output = NULL;
// post to the console
-PyObject* py::StdOut_Write(PyObject* self, PyObject* args)
+PyObject* pybase::StdOut_Write(PyObject* self, PyObject* args)
{
// should always be a tuple
FLEXT_ASSERT(PyTuple_Check(args));
@@ -475,7 +462,7 @@ public:
PyObject *fun,*args;
};
-bool py::gencall(PyObject *pmeth,PyObject *pargs)
+bool pybase::gencall(PyObject *pmeth,PyObject *pargs)
{
bool ret = false;
@@ -494,18 +481,18 @@ bool py::gencall(PyObject *pmeth,PyObject *pargs)
case 2:
// each call a new thread
if(!shouldexit) {
- ret = FLEXT_CALLMETHOD_X(work_wrapper,new work_data(pmeth,pargs));
- if(!ret) post("%s - Failed to launch thread!",thisName());
+ ret = thrcall(new work_data(pmeth,pargs));
+ if(!ret) post("py/pyext - Failed to launch thread!");
}
break;
#endif
default:
- post("%s - Unknown detach mode",thisName());
+ post("py/pyext - Unknown detach mode");
}
return ret;
}
-void py::work_wrapper(void *data)
+void pybase::work_wrapper(void *data)
{
FLEXT_ASSERT(data);
@@ -528,7 +515,7 @@ void py::work_wrapper(void *data)
}
#ifdef FLEXT_THREADS
-bool py::qucall(PyObject *fun,PyObject *args)
+bool pybase::qucall(PyObject *fun,PyObject *args)
{
FifoEl *el = qufifo.New();
el->Set(fun,args);
@@ -537,7 +524,7 @@ bool py::qucall(PyObject *fun,PyObject *args)
return true;
}
-void py::threadworker()
+void pybase::threadworker()
{
FifoEl *el;
PyThreadState *state;
@@ -573,7 +560,7 @@ void py::threadworker()
#endif
#if FLEXT_SYS == FLEXT_SYS_MAX
-short py::patcher_myvol(t_patcher *x)
+short pybase::patcher_myvol(t_patcher *x)
{
t_box *w;
if (x->p_vol)
@@ -585,12 +572,12 @@ short py::patcher_myvol(t_patcher *x)
}
#endif
-bool py::collect()
+bool pybase::collect()
{
if(gcollect) {
- PyObject *args = PyTuple_New(0);
- PyObject *ret = PyObject_Call(gcollect,args,NULL);
- Py_DECREF(args);
+ Py_INCREF(emptytuple);
+ PyObject *ret = PyObject_Call(gcollect,emptytuple,NULL);
+ Py_DECREF(emptytuple);
if(ret) {
#ifdef FLEXT_DEBUG
int refs = PyInt_AsLong(ret);
diff --git a/externals/grill/py/source/main.h b/externals/grill/py/source/main.h
index 7079dc2f..c76d43fa 100644
--- a/externals/grill/py/source/main.h
+++ b/externals/grill/py/source/main.h
@@ -41,23 +41,25 @@ public:
typedef PooledFifo<FifoEl> PyFifo;
-class py:
- public flext_base
-{
- FLEXT_HEADER_S(py,flext_base,Setup)
+class pybase
+ : public flext
+{
public:
- py();
- ~py();
- static void lib_setup();
+ pybase();
+ virtual ~pybase();
- virtual void Exit();
+ void Exit();
static PyObject *MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,int inlet = -1,bool withself = false);
static AtomList *GetPyArgs(PyObject *pValue,PyObject **self = NULL);
+ static void lib_setup();
+
protected:
+ virtual void DumpOut(const t_symbol *sym,int argc,const t_atom *argv) = 0;
+
void m__dir(PyObject *obj);
void m__doc(PyObject *obj);
@@ -83,12 +85,15 @@ protected:
void Reregister(const char *reg);
virtual void Reload() = 0;
+ void OpenEditor();
void Respond(bool b);
static bool IsAnything(const t_symbol *s) { return s && s != sym_float && s != sym_int && s != sym_symbol && s != sym_list && s != sym_pointer; }
enum retval { nothing,atom,sequ };
+ static PyObject *emptytuple;
+
// --- module stuff -----
static PyObject *module_obj,*module_dict;
@@ -131,6 +136,7 @@ protected:
int detach;
bool gencall(PyObject *fun,PyObject *args);
+ virtual bool thrcall(void *data) = 0;
virtual bool callpy(PyObject *fun,PyObject *args) = 0;
#if FLEXT_SYS == FLEXT_SYS_MAX
@@ -139,7 +145,7 @@ protected:
static bool collect();
-private:
+protected:
void work_wrapper(void *data);
@@ -151,10 +157,6 @@ private:
static PyThreadState *FindThreadState();
static void FreeThreadState();
-
- FLEXT_THREAD_X(work_wrapper)
-#else
- FLEXT_CALLBACK_X(work_wrapper)
#endif
public:
@@ -189,25 +191,6 @@ public:
#endif
static PyObject* StdOut_Write(PyObject* Self, PyObject* Args);
-
-protected:
-
- virtual void m_click();
-
- static void Setup(t_classid c);
-
- // callbacks
- FLEXT_ATTRVAR_I(detach)
- FLEXT_ATTRVAR_B(respond)
- FLEXT_CALLBACK_V(m_stop)
- FLEXT_CALLBACK(m_dir)
- FLEXT_CALLGET_V(mg_dir)
- FLEXT_CALLBACK(m_doc)
-
-#ifdef FLEXT_THREADS
- FLEXT_CALLBACK_T(tick)
- FLEXT_THREAD(threadworker)
-#endif
};
#endif
diff --git a/externals/grill/py/source/modmeth.cpp b/externals/grill/py/source/modmeth.cpp
index 4054d3ce..bbbe64b1 100644
--- a/externals/grill/py/source/modmeth.cpp
+++ b/externals/grill/py/source/modmeth.cpp
@@ -12,24 +12,24 @@ WARRANTIES, see the file, "license.txt," in this distribution.
// function table for module
-PyMethodDef py::func_tbl[] =
+PyMethodDef pybase::func_tbl[] =
{
- { "_send", py::py_send, METH_VARARGS,"Send message to a named object" },
+ { "_send", pybase::py_send, METH_VARARGS,"Send message to a named object" },
#ifdef FLEXT_THREADS
- { "_priority", py::py_priority, METH_VARARGS,"Set priority of current thread" },
+ { "_priority", pybase::py_priority, METH_VARARGS,"Set priority of current thread" },
#endif
- { "_samplerate", py::py_samplerate, METH_NOARGS,"Get system sample rate" },
- { "_blocksize", py::py_blocksize, METH_NOARGS,"Get system block size" },
+ { "_samplerate", pybase::py_samplerate, METH_NOARGS,"Get system sample rate" },
+ { "_blocksize", pybase::py_blocksize, METH_NOARGS,"Get system block size" },
#if FLEXT_SYS == FLEXT_SYS_PD
- { "_getvalue", py::py_getvalue, METH_VARARGS,"Get value of a 'value' object" },
- { "_setvalue", py::py_setvalue, METH_VARARGS,"Set value of a 'value' object" },
+ { "_getvalue", pybase::py_getvalue, METH_VARARGS,"Get value of a 'value' object" },
+ { "_setvalue", pybase::py_setvalue, METH_VARARGS,"Set value of a 'value' object" },
#endif
{NULL, NULL, 0, NULL} // sentinel
};
-const char *py::py_doc =
+const char *pybase::py_doc =
"py/pyext - python external object for PD and Max/MSP, (C)2002-2005 Thomas Grill\n"
"\n"
"This is the pyext module. Available function:\n"
@@ -45,7 +45,7 @@ const char *py::py_doc =
#ifdef FLEXT_THREADS
-void py::tick(void *)
+void pybase::tick(void *)
{
Lock();
@@ -57,7 +57,7 @@ void py::tick(void *)
else {
// still active threads
if(!--stoptick) {
- post("%s - Threads couldn't be stopped entirely - %i remaining",thisName(),thrcount);
+ post("py/pyext - Threads couldn't be stopped entirely - %i remaining",thrcount);
shouldexit = false;
}
else
@@ -69,7 +69,7 @@ void py::tick(void *)
}
#endif
-void py::m_stop(int argc,const t_atom *argv)
+void pybase::m_stop(int argc,const t_atom *argv)
{
#ifdef FLEXT_THREADS
if(thrcount) {
@@ -93,17 +93,17 @@ void py::m_stop(int argc,const t_atom *argv)
#endif
}
-PyObject *py::py_samplerate(PyObject *self,PyObject *args)
+PyObject *pybase::py_samplerate(PyObject *self,PyObject *args)
{
return PyFloat_FromDouble(sys_getsr());
}
-PyObject *py::py_blocksize(PyObject *self,PyObject *args)
+PyObject *pybase::py_blocksize(PyObject *self,PyObject *args)
{
return PyLong_FromLong(sys_getblksize());
}
-PyObject *py::py_send(PyObject *,PyObject *args)
+PyObject *pybase::py_send(PyObject *,PyObject *args)
{
// should always be a tuple
FLEXT_ASSERT(PyTuple_Check(args));
@@ -153,7 +153,7 @@ PyObject *py::py_send(PyObject *,PyObject *args)
}
#ifdef FLEXT_THREADS
-PyObject *py::py_priority(PyObject *self,PyObject *args)
+PyObject *pybase::py_priority(PyObject *self,PyObject *args)
{
int val;
if(!PyArg_ParseTuple(args, "i:py_priority", &val)) {
@@ -168,7 +168,7 @@ PyObject *py::py_priority(PyObject *self,PyObject *args)
#endif
#if FLEXT_SYS == FLEXT_SYS_PD
-PyObject *py::py_getvalue(PyObject *self,PyObject *args)
+PyObject *pybase::py_getvalue(PyObject *self,PyObject *args)
{
FLEXT_ASSERT(PyTuple_Check(args));
@@ -195,7 +195,7 @@ PyObject *py::py_getvalue(PyObject *self,PyObject *args)
return ret;
}
-PyObject *py::py_setvalue(PyObject *self,PyObject *args)
+PyObject *pybase::py_setvalue(PyObject *self,PyObject *args)
{
FLEXT_ASSERT(PyTuple_Check(args));
diff --git a/externals/grill/py/source/py.cpp b/externals/grill/py/source/py.cpp
index 3856739e..bf3ff8fb 100644
--- a/externals/grill/py/source/py.cpp
+++ b/externals/grill/py/source/py.cpp
@@ -11,19 +11,23 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#include "main.h"
-class pyobj:
- public py
+class pyobj
+ : public pybase
+ , public flext_base
{
- FLEXT_HEADER_S(pyobj,py,Setup)
+ FLEXT_HEADER_S(pyobj,flext_base,Setup)
public:
pyobj(int argc,const t_atom *argv);
~pyobj();
protected:
- bool m_method_(int n,const t_symbol *s,int argc,const t_atom *argv);
+ virtual void Exit();
- bool work(const t_symbol *s,int argc,const t_atom *argv);
+ virtual bool CbMethodResort(int n,const t_symbol *s,int argc,const t_atom *argv);
+ virtual void CbClick();
+
+ void m_help();
void m_reload();
void m_reload_(int argc,const t_atom *argv);
@@ -31,16 +35,14 @@ protected:
void m_dir_() { m__dir(function); }
void m_doc_() { m__doc(function); }
- virtual void m_help();
-
// methods for python arguments
void callwork(const t_symbol *s,int argc,const t_atom *argv);
- void m_bang() { callwork(sym_bang,0,NULL); }
- void m_py_list(int argc,const t_atom *argv) { callwork(sym_list,argc,argv); }
- void m_py_float(int argc,const t_atom *argv) { callwork(sym_float,argc,argv); }
- void m_py_int(int argc,const t_atom *argv) { callwork(sym_int,argc,argv); }
- void m_py_any(const t_symbol *s,int argc,const t_atom *argv) { callwork(s,argc,argv); }
+ inline void m_bang() { callwork(NULL,0,NULL); }
+ inline void m_py_list(int argc,const t_atom *argv) { callwork(sym_list,argc,argv); }
+ inline void m_py_float(int argc,const t_atom *argv) { callwork(sym_float,argc,argv); }
+ inline void m_py_int(int argc,const t_atom *argv) { callwork(sym_int,argc,argv); }
+ inline void m_py_any(const t_symbol *s,int argc,const t_atom *argv) { callwork(s,argc,argv); }
const t_symbol *funname;
PyObject *function;
@@ -51,12 +53,16 @@ protected:
void SetFunction(const char *func);
void ResetFunction();
+ virtual bool thrcall(void *data);
+ virtual void DumpOut(const t_symbol *sym,int argc,const t_atom *argv);
+
private:
virtual bool callpy(PyObject *fun,PyObject *args);
static void Setup(t_classid c);
+ FLEXT_CALLBACK(m_help)
FLEXT_CALLBACK(m_bang)
FLEXT_CALLBACK(m_reload)
FLEXT_CALLBACK_V(m_reload_)
@@ -69,10 +75,20 @@ private:
FLEXT_CALLBACK_V(m_py_int)
FLEXT_CALLBACK_A(m_py_any)
+ // callbacks
+ FLEXT_ATTRVAR_I(detach)
+ FLEXT_ATTRVAR_B(respond)
+ FLEXT_CALLBACK_V(m_stop)
+ FLEXT_CALLBACK(m_dir)
+ FLEXT_CALLGET_V(mg_dir)
+ FLEXT_CALLBACK(m_doc)
+
#ifdef FLEXT_THREADS
- FLEXT_THREAD_A(work)
+ FLEXT_CALLBACK_T(tick)
+ FLEXT_THREAD(threadworker)
+ FLEXT_THREAD_X(work_wrapper)
#else
- FLEXT_CALLBACK_A(work)
+ FLEXT_CALLBACK_X(work_wrapper)
#endif
};
@@ -81,6 +97,14 @@ FLEXT_LIB_V("py",pyobj)
void pyobj::Setup(t_classid c)
{
+ FLEXT_CADDMETHOD_(c,0,"doc",m_doc);
+ FLEXT_CADDMETHOD_(c,0,"dir",m_dir);
+#ifdef FLEXT_THREADS
+ FLEXT_CADDATTR_VAR1(c,"detach",detach);
+ FLEXT_CADDMETHOD_(c,0,"stop",m_stop);
+#endif
+
+ FLEXT_CADDMETHOD_(c,0,"help",m_help);
FLEXT_CADDMETHOD_(c,0,"reload",m_reload_);
FLEXT_CADDMETHOD_(c,0,"reload.",m_reload);
FLEXT_CADDMETHOD_(c,0,"doc+",m_doc_);
@@ -100,11 +124,17 @@ void pyobj::Setup(t_classid c)
pyobj::pyobj(int argc,const t_atom *argv):
function(NULL),funname(NULL),withfunction(false)
{
- PyThreadState *state = PyLock();
-
AddInAnything(2);
AddOutAnything();
+#ifdef FLEXT_THREADS
+ FLEXT_ADDTIMER(stoptmr,tick);
+ // launch thread worker
+ FLEXT_CALLMETHOD(threadworker);
+#endif
+
+ PyThreadState *state = PyLock();
+
if(argc > 2)
SetArgs(argc-2,argv+2);
else
@@ -163,10 +193,13 @@ pyobj::~pyobj()
PyUnlock(state);
}
+void pyobj::Exit()
+{
+ pybase::Exit();
+ flext_base::Exit();
+}
-
-
-bool pyobj::m_method_(int n,const t_symbol *s,int argc,const t_atom *argv)
+bool pyobj::CbMethodResort(int n,const t_symbol *s,int argc,const t_atom *argv)
{
if(n == 1)
post("%s - no method for type %s",thisName(),GetString(s));
@@ -346,3 +379,15 @@ void pyobj::callwork(const t_symbol *s,int argc,const t_atom *argv)
Respond(ret);
}
+
+void pyobj::CbClick() { pybase::OpenEditor(); }
+
+void pyobj::DumpOut(const t_symbol *sym,int argc,const t_atom *argv)
+{
+ ToOutAnything(GetOutAttr(),sym?sym:thisTag(),argc,argv);
+}
+
+bool pyobj::thrcall(void *data)
+{
+ return FLEXT_CALLMETHOD_X(work_wrapper,data);
+}
diff --git a/externals/grill/py/source/pyargs.cpp b/externals/grill/py/source/pyargs.cpp
index a040feac..56b0123a 100644
--- a/externals/grill/py/source/pyargs.cpp
+++ b/externals/grill/py/source/pyargs.cpp
@@ -29,7 +29,7 @@ static PyObject *MakePyAtom(const t_atom &at)
return NULL;
}
-PyObject *py::MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,int inlet,bool withself)
+PyObject *pybase::MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,int inlet,bool withself)
{
PyObject *pArgs;
@@ -84,7 +84,7 @@ PyObject *py::MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,int inlet
return pArgs;
}
-flext::AtomList *py::GetPyArgs(PyObject *pValue,PyObject **self)
+flext::AtomList *pybase::GetPyArgs(PyObject *pValue,PyObject **self)
{
if(pValue == NULL) return NULL;
AtomList *ret = NULL;
diff --git a/externals/grill/py/source/pybuffer.cpp b/externals/grill/py/source/pybuffer.cpp
index 96f2efae..6e7e571b 100644
--- a/externals/grill/py/source/pybuffer.cpp
+++ b/externals/grill/py/source/pybuffer.cpp
@@ -178,6 +178,21 @@ static PyObject *buffer_item(pySamplebuffer *self, int i)
return ret;
}
+PyObject *NAFromBuffer(PyObject *buf,int c,int n)
+{
+#ifdef PY_NUMARRAY
+ if(nasupport) {
+ maybelong shape[2];
+ shape[0] = n;
+ shape[1] = c;
+ PyArrayObject *na = NA_NewAllFromBuffer(c == 1?1:2,shape,numtype,buf,0,0,NA_ByteOrder(),1,1);
+ return (PyObject *)na;
+ }
+ else
+#endif
+ return NULL;
+}
+
static PyObject *buffer_slice(pySamplebuffer *self,int ilow = 0,int ihigh = 1<<(sizeof(int)*8-2))
{
PyObject *ret;
@@ -191,10 +206,7 @@ static PyObject *buffer_slice(pySamplebuffer *self,int ilow = 0,int ihigh = 1<<(
if(ihigh < 0) ihigh += n;
if(ihigh > n) ihigh = n;
- maybelong shape[2];
- shape[0] = n;
- shape[1] = c;
- PyObject *nobj = (PyObject *)NA_NewAllFromBuffer(c == 1?1:2,shape,numtype,(PyObject *)self,0,0,NA_ByteOrder(),1,1);
+ PyObject *nobj = NAFromBuffer((PyObject *)self,c,n);
if(ilow != 0 || ihigh != n) {
ret = PySequence_GetSlice(nobj,ilow,ihigh);
Py_DECREF(nobj);
@@ -657,7 +669,7 @@ void initsamplebuffer()
import_libnumarray();
if(PyErr_Occurred())
// catch import error
- PyErr_Print();
+ PyErr_Clear();
else {
// numarray support ok
nasupport = true;
diff --git a/externals/grill/py/source/pydsp.cpp b/externals/grill/py/source/pydsp.cpp
new file mode 100644
index 00000000..b1f50c0d
--- /dev/null
+++ b/externals/grill/py/source/pydsp.cpp
@@ -0,0 +1,179 @@
+/*
+
+py/pyext - python script object for PD and Max/MSP
+
+Copyright (c)2002-2005 Thomas Grill (gr@grrrr.org)
+For information on usage and redistribution, and for a DISCLAIMER OF ALL
+WARRANTIES, see the file, "license.txt," in this distribution.
+
+*/
+
+#include "pyext.h"
+
+class pydsp
+ : public pyext
+{
+ FLEXT_HEADER(pydsp,pyext)
+public:
+ pydsp(int argc,const t_atom *argv);
+
+protected:
+ virtual bool CbDsp();
+ virtual void CbSignal();
+
+ virtual bool DoInit();
+ virtual void DoExit();
+
+ virtual PyObject *GetSig(int ix,bool in);
+
+ void NewBuffers(bool update = false);
+ void FreeBuffers();
+
+ PyObject *dspfun,*sigfun;
+ PyObject **buffers;
+};
+
+FLEXT_LIB_DSP_V("pyext~ pyext.~ pyx~ pyx.~",pydsp)
+
+pydsp::pydsp(int argc,const t_atom *argv)
+ : pyext(argc,argv,true)
+ , dspfun(NULL),sigfun(NULL)
+{}
+
+bool pydsp::DoInit()
+{
+ if(!pyext::DoInit()) return false;
+
+ if(pyobj)
+ {
+ NewBuffers();
+
+ dspfun = PyObject_GetAttrString(pyobj,"_dsp"); // get ref
+ if(dspfun && !PyMethod_Check(dspfun)) {
+ Py_DECREF(dspfun);
+ dspfun = NULL;
+ }
+ sigfun = PyObject_GetAttrString(pyobj,"_signal"); // get ref
+ if(sigfun && !PyMethod_Check(sigfun)) {
+ Py_DECREF(sigfun);
+ sigfun = NULL;
+ }
+ }
+ return true;
+}
+
+void pydsp::DoExit()
+{
+ if(dspfun) { Py_DECREF(dspfun); dspfun = NULL; }
+ if(sigfun) { Py_DECREF(sigfun); sigfun = NULL; }
+
+ FreeBuffers();
+}
+
+PyObject *NAFromBuffer(PyObject *buf,int c,int n);
+
+void pydsp::NewBuffers(bool update)
+{
+ int i,n = Blocksize();
+ const int ins = CntInSig(),outs = CntOutSig();
+ t_sample *const *insigs = InSig();
+ t_sample *const *outsigs = OutSig();
+
+ if(!buffers) {
+ int cnt = ins+outs;
+ if(cnt) {
+ buffers = new PyObject *[cnt];
+ memset(buffers,0,cnt*sizeof(*buffers));
+ }
+ }
+
+ for(i = 0; i < ins; ++i) {
+ if(update) Py_XDECREF(buffers[i]);
+ PyObject *b = PyBuffer_FromReadWriteMemory(insigs[i],n*sizeof(t_sample));
+ buffers[i] = NAFromBuffer(b,1,n);
+ Py_DECREF(b);
+ }
+ for(i = 0; i < outs; ++i) {
+ if(update) Py_XDECREF(buffers[ins+i]);
+ if(i < ins && outsigs[i] == insigs[i]) {
+ // same vectors - share the objects!
+ buffers[ins+i] = buffers[i];
+ Py_XINCREF(buffers[i]);
+ }
+ else {
+ PyObject *b = PyBuffer_FromReadWriteMemory(outsigs[i],n*sizeof(t_sample));
+ buffers[ins+i] = NAFromBuffer(b,1,n);
+ Py_DECREF(b);
+ }
+ }
+}
+
+void pydsp::FreeBuffers()
+{
+ if(buffers) {
+ int cnt = CntInSig()+CntOutSig();
+ for(int i = 0; i < cnt; ++i) Py_XDECREF(buffers[i]);
+ delete[] buffers;
+ buffers = NULL;
+ }
+}
+
+bool pydsp::CbDsp()
+{
+ if(CntInSig() || CntOutSig())
+ {
+ NewBuffers(true);
+
+ if(dspfun) {
+ PyThreadState *state = PyLock();
+// Py_INCREF(emptytuple);
+ PyObject *ret = PyObject_Call(dspfun,emptytuple,NULL);
+// Py_DECREF(emptytuple);
+ if(ret)
+ Py_DECREF(ret);
+ else {
+#ifdef FLEXT_DEBUG
+ PyErr_Print();
+#else
+ PyErr_Clear();
+#endif
+ }
+ PyUnlock(state);
+ }
+ return true;
+ }
+ else
+ // switch on dsp only if there are signal inlets or outlets
+ return false;
+}
+
+void pydsp::CbSignal()
+{
+ if(sigfun) {
+ PyThreadState *state = PyLock();
+// Py_INCREF(emptytuple);
+ PyObject *ret = PyObject_Call(sigfun,emptytuple,NULL);
+// Py_DECREF(emptytuple);
+
+ if(ret)
+ Py_DECREF(ret);
+ else {
+#ifdef FLEXT_DEBUG
+ PyErr_Print();
+#else
+ PyErr_Clear();
+#endif
+ }
+ PyUnlock(state);
+ }
+ else
+ flext_dsp::CbSignal();
+}
+
+PyObject *pydsp::GetSig(int ix,bool in)
+{
+ PyObject *r = buffers[in?ix:CntInSig()+ix];
+ Py_XINCREF(r);
+ return r;
+}
+
diff --git a/externals/grill/py/source/pyext.cpp b/externals/grill/py/source/pyext.cpp
index 72ae41fd..0ebeab68 100644
--- a/externals/grill/py/source/pyext.cpp
+++ b/externals/grill/py/source/pyext.cpp
@@ -20,6 +20,15 @@ void pyext::Setup(t_classid c)
{
sym_get = flext::MakeSymbol("get");
+ FLEXT_CADDMETHOD_(c,0,"doc",m_doc);
+ FLEXT_CADDMETHOD_(c,0,"dir",m_dir);
+#ifdef FLEXT_THREADS
+ FLEXT_CADDATTR_VAR1(c,"detach",detach);
+ FLEXT_CADDMETHOD_(c,0,"stop",m_stop);
+#endif
+
+ FLEXT_CADDMETHOD_(c,0,"help",m_help);
+
FLEXT_CADDMETHOD_(c,0,"reload",m_reload_);
FLEXT_CADDMETHOD_(c,0,"reload.",m_reload);
FLEXT_CADDMETHOD_(c,0,"doc+",m_doc_);
@@ -95,19 +104,31 @@ void pyext::SetThis()
PyObject *pyext::class_obj = NULL;
PyObject *pyext::class_dict = NULL;
-pyext::pyext(int argc,const t_atom *argv):
+pyext::pyext(int argc,const t_atom *argv,bool sig):
pyobj(NULL),pythr(NULL),
inlets(-1),outlets(-1),
+ siginlets(0),sigoutlets(0),
methname(NULL)
{
- int apre = 0;
+#ifdef FLEXT_THREADS
+ FLEXT_ADDTIMER(stoptmr,tick);
+ // launch thread worker
+ FLEXT_CALLMETHOD(threadworker);
+#endif
+ int apre = 0;
if(argc >= apre+2 && CanbeInt(argv[apre]) && CanbeInt(argv[apre+1])) {
inlets = GetAInt(argv[apre]);
outlets = GetAInt(argv[apre+1]);
apre += 2;
}
+ if(sig && argc >= apre+2 && CanbeInt(argv[apre]) && CanbeInt(argv[apre+1])) {
+ siginlets = GetAInt(argv[apre]);
+ sigoutlets = GetAInt(argv[apre+1]);
+ apre += 2;
+ }
+
const t_atom *clname = NULL;
PyThreadState *state = PyLock();
@@ -162,38 +183,46 @@ pyext::pyext(int argc,const t_atom *argv):
if(argc > apre) args(argc-apre,argv+apre);
+ PyUnlock(state);
+}
+
+bool pyext::Init()
+{
+ PyThreadState *state = PyLock();
+
if(methname) {
MakeInstance();
-
- if(pyobj)
- InitInOut(inlets,outlets);
+ if(pyobj) InitInOut(inlets,outlets);
}
- else
+ else
inlets = outlets = 0;
- PyUnlock(state);
-
if(inlets < 0 || outlets < 0)
InitProblem();
else {
- AddInAnything(1+inlets);
+ AddInSignal(siginlets);
+ AddInAnything((siginlets?0:1)+inlets);
+ AddOutSignal(sigoutlets);
AddOutAnything(outlets);
}
- if(!pyobj)
- InitProblem();
+ PyUnlock(state);
+
+ return pyobj && flext_dsp::Init();
}
-pyext::~pyext()
-{
- PyThreadState *state = PyLock();
+void pyext::Exit()
+{
+ pybase::Exit(); // exit threads
+ PyThreadState *state = PyLock();
DoExit();
-
Unregister("_pyext");
UnimportModule();
PyUnlock(state);
+
+ flext_dsp::Exit();
}
bool pyext::DoInit()
@@ -230,13 +259,15 @@ void pyext::DoExit()
// try to run del to clean up the class instance
PyObject *objdel = PyObject_GetAttrString(pyobj,"_del");
if(objdel) {
- PyObject *args = PyTuple_New(0);
- PyObject *ret = PyObject_Call(objdel,args,NULL);
- if(!ret)
- post("%s - Could not call _del method",thisName());
- else
+ Py_INCREF(emptytuple);
+ PyObject *ret = PyObject_Call(objdel,emptytuple,NULL);
+ if(ret)
Py_DECREF(ret);
- Py_DECREF(args);
+#ifdef FLEXT_DEBUG
+ else
+ post("%s - Could not call _del method",thisName());
+#endif
+ Py_DECREF(emptytuple);
Py_DECREF(objdel);
}
else
@@ -269,7 +300,7 @@ void pyext::InitInOut(int &inl,int &outl)
if(inl < 0) {
// get number of inlets
- inl = 1;
+ inl = inlets;
PyObject *res = PyObject_GetAttrString(pyobj,"_inlets"); // get ref
if(res) {
if(PyCallable_Check(res)) {
@@ -286,7 +317,7 @@ void pyext::InitInOut(int &inl,int &outl)
}
if(outl < 0) {
// get number of outlets
- outl = 1;
+ outl = outlets;
PyObject *res = PyObject_GetAttrString(pyobj,"_outlets"); // get ref
if(res) {
if(PyCallable_Check(res)) {
@@ -436,14 +467,12 @@ void pyext::m_set(int argc,const t_atom *argv)
}
-bool pyext::m_method_(int n,const t_symbol *s,int argc,const t_atom *argv)
+bool pyext::CbMethodResort(int n,const t_symbol *s,int argc,const t_atom *argv)
{
- bool ret = false;
if(pyobj && n >= 1)
- ret = work(n,s,argc,argv);
+ return work(n,s,argc,argv);
else
- post("%s - no method for type '%s' into inlet %i",thisName(),GetString(s),n);
- return ret;
+ return flext_dsp::CbMethodResort(n,s,argc,argv);
}
@@ -522,6 +551,10 @@ bool pyext::work(int n,const t_symbol *s,int argc,const t_atom *argv)
bool isfloat = s == sym_float && argc == 1;
+ // offset inlet index by signal inlets
+ // \note first one is shared with messages!
+ if(siginlets) n += siginlets-1;
+
// if float equals an integer, try int_* method
if(isfloat && GetAFloat(argv[0]) == GetAInt(argv[0])) {
sprintf(str,"int_%i",n);
@@ -585,3 +618,18 @@ bool pyext::work(int n,const t_symbol *s,int argc,const t_atom *argv)
Respond(ret);
return ret;
}
+
+PyObject *pyext::GetSig(int ix,bool in) { return NULL; }
+
+void pyext::CbClick() { pybase::OpenEditor(); }
+bool pyext::CbDsp() { return false; }
+
+void pyext::DumpOut(const t_symbol *sym,int argc,const t_atom *argv)
+{
+ ToOutAnything(GetOutAttr(),sym?sym:thisTag(),argc,argv);
+}
+
+bool pyext::thrcall(void *data)
+{
+ return FLEXT_CALLMETHOD_X(work_wrapper,data);
+}
diff --git a/externals/grill/py/source/pyext.h b/externals/grill/py/source/pyext.h
index f94b2f19..3c6a86b5 100644
--- a/externals/grill/py/source/pyext.h
+++ b/externals/grill/py/source/pyext.h
@@ -13,14 +13,14 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#include "main.h"
-class pyext:
- public py
+class pyext
+ : public pybase
+ , public flext_dsp
{
- FLEXT_HEADER_S(pyext,py,Setup)
+ FLEXT_HEADER_S(pyext,flext_dsp,Setup)
public:
- pyext(int argc,const t_atom *argv);
- ~pyext();
+ pyext(int argc,const t_atom *argv,bool sig = false);
static PyObject *pyext__doc__(PyObject *,PyObject *args);
static PyObject *pyext__init__(PyObject *,PyObject *args);
@@ -38,21 +38,35 @@ public:
static PyObject *pyext_stop(PyObject *,PyObject *args);
static PyObject *pyext_isthreaded(PyObject *,PyObject *);
+ static PyObject *pyext_inbuf(PyObject *,PyObject *args);
+ static PyObject *pyext_invec(PyObject *,PyObject *args);
+ static PyObject *pyext_outbuf(PyObject *,PyObject *args);
+ static PyObject *pyext_outvec(PyObject *,PyObject *args);
+
int Inlets() const { return inlets; }
int Outlets() const { return outlets; }
protected:
- virtual bool m_method_(int n,const t_symbol *s,int argc,const t_atom *argv);
+
+ virtual bool Init();
+ virtual void Exit();
+
+ virtual bool CbMethodResort(int n,const t_symbol *s,int argc,const t_atom *argv);
+ virtual void CbClick();
+ virtual bool CbDsp();
+
+ virtual void DumpOut(const t_symbol *sym,int argc,const t_atom *argv);
bool work(int n,const t_symbol *s,int argc,const t_atom *argv);
+ void m_help();
+
void m_reload();
void m_reload_(int argc,const t_atom *argv);
void ms_args(const AtomList &a) { m_reload_(a.Count(),a.Atoms()); }
void m_dir_() { m__dir(pyobj); }
void mg_dir_(AtomList &lst) { GetDir(pyobj,lst); }
void m_doc_() { m__doc(((PyInstanceObject *)pyobj)->in_class->cl_dict); }
- virtual void m_help();
void m_get(const t_symbol *s);
void m_set(int argc,const t_atom *argv);
@@ -60,23 +74,27 @@ protected:
const t_symbol *methname;
PyObject *pyobj;
int inlets,outlets;
+ int siginlets,sigoutlets;
+
+ virtual void Reload();
+ virtual bool DoInit();
+ virtual void DoExit();
+
+ virtual PyObject *GetSig(int ix,bool in);
+
+ static pyext *GetThis(PyObject *self);
private:
static void Setup(t_classid);
- static pyext *GetThis(PyObject *self);
void SetThis();
void ClearBinding();
bool MakeInstance();
- bool DoInit();
- void DoExit();
void InitInOut(int &inlets,int &outlets);
AtomList args;
- virtual void Reload();
-
static PyObject *class_obj,*class_dict;
static PyMethodDef attr_tbl[],meth_tbl[];
static const char *pyext_doc;
@@ -89,6 +107,7 @@ private:
bool call(const char *meth,int inlet,const t_symbol *s,int argc,const t_atom *argv);
+ virtual bool thrcall(void *data);
virtual bool callpy(PyObject *fun,PyObject *args);
static bool stcallpy(PyObject *fun,PyObject *args);
@@ -96,7 +115,9 @@ private:
private:
static bool boundmeth(flext_base *,t_symbol *sym,int argc,t_atom *argv,void *data);
-
+
+ FLEXT_CALLBACK(m_help)
+
FLEXT_CALLBACK(m_reload)
FLEXT_CALLBACK_V(m_reload_)
FLEXT_CALLBACK(m_dir_)
@@ -108,6 +129,22 @@ private:
FLEXT_CALLBACK_S(m_get)
FLEXT_CALLBACK_V(m_set)
+
+ // callbacks
+ FLEXT_ATTRVAR_I(detach)
+ FLEXT_ATTRVAR_B(respond)
+ FLEXT_CALLBACK_V(m_stop)
+ FLEXT_CALLBACK(m_dir)
+ FLEXT_CALLGET_V(mg_dir)
+ FLEXT_CALLBACK(m_doc)
+
+#ifdef FLEXT_THREADS
+ FLEXT_CALLBACK_T(tick)
+ FLEXT_THREAD(threadworker)
+ FLEXT_THREAD_X(work_wrapper)
+#else
+ FLEXT_CALLBACK_X(work_wrapper)
+#endif
};
#endif
diff --git a/externals/grill/py/source/register.cpp b/externals/grill/py/source/register.cpp
index ae273955..bc2563ae 100644
--- a/externals/grill/py/source/register.cpp
+++ b/externals/grill/py/source/register.cpp
@@ -11,7 +11,7 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#include "main.h"
-void py::Register(const char *regnm)
+void pybase::Register(const char *regnm)
{
if(module) {
// add this to module registry
@@ -20,7 +20,7 @@ void py::Register(const char *regnm)
PyObject *add = Py_BuildValue("[i]",(long)this);
if(!reg || !PyList_Check(reg)) {
if(PyDict_SetItemString(dict,(char *)regnm,add)) {
- post("%s - Could not set registry",thisName());
+ post("py/pyext - Could not set registry");
}
}
else {
@@ -29,7 +29,7 @@ void py::Register(const char *regnm)
}
}
-void py::Unregister(const char *regnm)
+void pybase::Unregister(const char *regnm)
{
if(module) {
// remove this from module registry
@@ -37,11 +37,11 @@ void py::Unregister(const char *regnm)
PyObject *reg = PyDict_GetItemString(dict,(char *)regnm); // borrowed!!!
PyObject *add = Py_BuildValue("i",(int)this);
if(!reg || !PySequence_Check(reg))
- post("%s - Internal error: Registry not found!?",thisName());
+ post("py/pyext - Internal error: Registry not found!?");
else {
int ix = PySequence_Index(reg,add);
if(ix < 0) {
- post("%s - Internal error: object not found in registry?!",thisName());
+ post("py/pyext - Internal error: object not found in registry?!");
}
else {
PySequence_DelItem(reg,ix);
@@ -51,7 +51,7 @@ void py::Unregister(const char *regnm)
}
}
-void py::Reregister(const char *regnm)
+void pybase::Reregister(const char *regnm)
{
if(module) {
// remove this from module registry
@@ -59,16 +59,16 @@ void py::Reregister(const char *regnm)
PyObject *reg = PyDict_GetItemString(dict,(char *)regnm); // borrowed!!!
if(!reg || !PySequence_Check(reg))
- post("%s - Internal error: Registry not found!?",thisName());
+ post("py/pyext - Internal error: Registry not found!?");
else {
int cnt = PySequence_Size(reg);
for(int i = 0; i < cnt; ++i) {
PyObject *it = PySequence_GetItem(reg,i); // new reference
if(!it || !PyInt_Check(it)) {
- post("%s - Internal error: Corrupt registry?!",thisName());
+ post("py/pyext - Internal error: Corrupt registry?!");
}
else {
- py *th = (py *)PyInt_AsLong(it);
+ pybase *th = (pybase *)PyInt_AsLong(it);
th->module = module;
th->dict = dict;
th->Reload();