From 3ce0fb7e8ad57909fadcd4072817d69bc54e3a66 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Sun, 13 Mar 2005 04:59:47 +0000 Subject: 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 --- externals/grill/py/source/bound.cpp | 6 +- externals/grill/py/source/clmeth.cpp | 59 ++++++++++- externals/grill/py/source/main.cpp | 111 +++++++++----------- externals/grill/py/source/main.h | 47 +++------ externals/grill/py/source/modmeth.cpp | 34 +++---- externals/grill/py/source/py.cpp | 83 +++++++++++---- externals/grill/py/source/pyargs.cpp | 4 +- externals/grill/py/source/pybuffer.cpp | 22 +++- externals/grill/py/source/pydsp.cpp | 179 +++++++++++++++++++++++++++++++++ externals/grill/py/source/pyext.cpp | 104 +++++++++++++------ externals/grill/py/source/pyext.h | 63 +++++++++--- externals/grill/py/source/register.cpp | 18 ++-- 12 files changed, 535 insertions(+), 195 deletions(-) create mode 100644 externals/grill/py/source/pydsp.cpp (limited to 'externals/grill/py/source') 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(th); + pyext *pyth = static_cast(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 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(); -- cgit v1.2.1