Update of /cvsroot/pure-data/externals/grill/py/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30504/source
Modified Files: bound.cpp clmeth.cpp main.cpp main.h py.cpp pydsp.cpp pyext.cpp pyext.h register.cpp Log Message: check for PD version better reload handling, but still far fom perfect fixed minor other issues fixed buglet fixing strange gcc behavior updates for DSP processing better argument checking
Index: clmeth.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/clmeth.cpp,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** clmeth.cpp 10 Apr 2005 22:24:13 -0000 1.19 --- clmeth.cpp 18 Apr 2005 15:11:43 -0000 1.20 *************** *** 125,128 **** --- 125,132 ---- if(ext) ret = PyLong_FromLong(ext->shouldexit?1:0); + else { + Py_INCREF(Py_True); + ret = Py_True; + } } // post("pyext::getattr %s",sname); *************** *** 189,209 **** else ext->ToOutAtom(o-1,*lst.Atoms()); } else ! post("pyext: outlet index out of range"); ! ! ok = true; } else ! post("py/pyext - No data to send");
if(!tp) Py_DECREF(val); } ! ! if(!ok) { PyErr_SetString(PyExc_SyntaxError,"pyext - Syntax: _outlet(self,outlet,args...)"); - return NULL; - }
Py_INCREF(Py_None); return Py_None; --- 193,210 ---- else ext->ToOutAtom(o-1,*lst.Atoms()); + ok = true; } else ! PyErr_SetString(PyExc_ValueError,"pyext - _outlet: index out of range"); } else ! PyErr_SetString(PyExc_ValueError,"pyext - _outlet: invalid arguments");
if(!tp) Py_DECREF(val); } ! else PyErr_SetString(PyExc_SyntaxError,"pyext - Syntax: _outlet(self,outlet,args...)");
+ if(!ok) return NULL; Py_INCREF(Py_None); return Py_None; *************** *** 220,229 **** if(!PyArg_ParseTuple(args, "Oi:pyext_detach",&self,&val)) { // handle error ! PyErr_SetString(PyExc_SyntaxError,"pyext - Syntax: _detach(self,[0/1])"); return NULL; } else { pyext *ext = GetThis(self); ! ext->detach = val != 0; }
--- 221,234 ---- if(!PyArg_ParseTuple(args, "Oi:pyext_detach",&self,&val)) { // handle error ! PyErr_SetString(PyExc_SyntaxError,"pyext - Syntax: _detach(self,[0/1/2])"); ! return NULL; ! } ! else if(val < 0 || val > 2) { ! PyErr_SetString(PyExc_ValueError,"pyext - _detach must be in the range 0..2"); return NULL; } else { pyext *ext = GetThis(self); ! ext->detach = val; }
*************** *** 242,245 **** --- 247,254 ---- return NULL; } + else if(val < 0) { + PyErr_SetString(PyExc_ValueError,"pyext - _stop time must be >= 0"); + return NULL; + } else { pyext *ext = GetThis(self); *************** *** 333,336 **** --- 342,349 ---- return NULL; } + else if(val < 0) { + PyErr_SetString(PyExc_ValueError,"pyext - _invec: index out of range"); + return NULL; + } else { pyext *ext = GetThis(self); *************** *** 352,355 **** --- 365,372 ---- return NULL; } + else if(val < 0) { + PyErr_SetString(PyExc_ValueError,"pyext - _outvec: index out of range"); + return NULL; + } else { pyext *ext = GetThis(self);
Index: bound.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/bound.cpp,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** bound.cpp 13 Mar 2005 04:59:47 -0000 1.15 --- bound.cpp 18 Apr 2005 15:11:43 -0000 1.16 *************** *** 175,179 **** if(!pyobj) return;
! FLEXT_ASSERT(GetThis(pyobj));
void *data = NULL; --- 175,180 ---- if(!pyobj) return;
! pyext *th = GetThis(pyobj); ! FLEXT_ASSERT(th);
void *data = NULL; *************** *** 181,185 ****
// unbind all ! while(GetThis(pyobj)->UnbindMethod(sym,NULL,&data)) { bounddata *bdt = (bounddata *)data; if(bdt) { --- 182,186 ----
// unbind all ! while(th->UnbindMethod(sym,NULL,&data)) { bounddata *bdt = (bounddata *)data; if(bdt) {
Index: pydsp.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/pydsp.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** pydsp.cpp 10 Apr 2005 22:24:13 -0000 1.4 --- pydsp.cpp 18 Apr 2005 15:11:43 -0000 1.5 *************** *** 125,129 **** PyObject *ret = PyObject_CallObject(dspfun,NULL); if(ret) { ! dodsp = PyObject_IsTrue(ret); Py_DECREF(ret); } --- 125,129 ---- PyObject *ret = PyObject_CallObject(dspfun,NULL); if(ret) { ! dodsp = PyObject_IsTrue(ret) != 0; Py_DECREF(ret); }
Index: main.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/main.cpp,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** main.cpp 10 Apr 2005 22:24:13 -0000 1.34 --- main.cpp 18 Apr 2005 15:11:43 -0000 1.35 *************** *** 289,298 **** { if(!name) return false; ! ! SetArgs(); ! module = PyImport_ImportModule((char *)name); // increases module_obj ref count by one ! dict = module?PyModule_GetDict(module):NULL; ! ! return module != NULL; }
--- 289,295 ---- { if(!name) return false; ! if(modname == name) return true; ! modname = name; ! return ReloadModule(); }
*************** *** 316,335 **** { bool ok = false; ! if(module) { ! SetArgs(); ! PyObject *newmod = PyImport_ReloadModule(module); ! if(!newmod) { ! // old module still exists?! ! // dict = NULL; ! } ! else { ! Py_XDECREF(module); ! module = newmod; ! dict = PyModule_GetDict(module); // borrowed ! ok = true; ! } } - else - post("py/pyext - No module to reload"); return ok; } --- 313,332 ---- { bool ok = false; ! ! SetArgs(); ! PyObject *newmod = module ! ?PyImport_ReloadModule(module) ! :PyImport_ImportModule((char *)modname.c_str()); ! ! if(!newmod) { ! // unload faulty module ! if(module) UnimportModule(); ! } ! else { ! Py_XDECREF(module); ! module = newmod; ! dict = PyModule_GetDict(module); // borrowed ! ok = true; } return ok; } *************** *** 403,406 **** --- 400,445 ---- }
+ void pybase::Reload() + { + PyThreadState *state = PyLockSys(); + + PyObject *reg = GetRegistry(REGNAME); + + if(reg) { + PyObject *key; + int pos = 0; + while(PyDict_Next(reg,&pos,&key,NULL)) { + pybase *th = (pybase *)PyLong_AsLong(key); + FLEXT_ASSERT(th); + th->Unload(); + } + + UnloadModule(); + } + + bool ok = ReloadModule(); + + if(ok) { + LoadModule(); + + if(reg) { + SetRegistry(REGNAME,reg); + + PyObject *key; + int pos = 0; + while(PyDict_Next(reg,&pos,&key,NULL)) { + pybase *th = (pybase *)PyLong_AsLong(key); + FLEXT_ASSERT(th); + th->Load(); + } + } + else + Load(); + } + + Report(); + PyUnlock(state); + } +
Index: main.h =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/main.h,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** main.h 10 Apr 2005 22:24:13 -0000 1.39 --- main.h 18 Apr 2005 15:11:43 -0000 1.40 *************** *** 16,19 **** --- 16,20 ---- #include "pybuffer.h" #include <flcontainers.h> + #include <string>
#if FLEXT_OS == FLEXT_LINUX || FLEXT_OS == FLEXT_IRIX *************** *** 21,24 **** --- 22,29 ---- #endif
+ #if FLEXT_SYS == FLEXT_SYS_PD && (!defined (PD_MINOR_VERSION) || PD_MINOR_VERSION < 37) + #error PD version >= 0.37 required, please upgrade! + #endif + #define PY__VERSION "0.2.0pre"
*************** *** 27,30 **** --- 32,37 ---- #define PYEXT_CLASS "_class" // name for base class
+ #define REGNAME "_registry" + #define PY_STOP_WAIT 100 // ms #define PY_STOP_TICK 1 // ms *************** *** 68,72 **** void m_doc() { m__doc(dict); }
! PyObject *module,*dict; // inherited user class module and associated dictionary
static const char *py_doc; --- 75,80 ---- void m_doc() { m__doc(dict); }
! std::string modname; // module name ! PyObject *module,*dict; // object module and associated dictionary
static const char *py_doc; *************** *** 79,90 **** void AddToPath(const char *dir); void SetArgs(); bool ImportModule(const char *name); void UnimportModule(); bool ReloadModule();
! void Register(const char *reg); ! void Unregister(const char *reg); ! void Reregister(const char *reg); ! virtual bool Reload() = 0;
void OpenEditor(); --- 87,113 ---- void AddToPath(const char *dir); void SetArgs(); + + // reload module and all connected objects + void Reload(); + bool ImportModule(const char *name); void UnimportModule(); bool ReloadModule();
! // Get module registry ! PyObject *GetRegistry(const char *regname); ! // Set module registry ! void SetRegistry(const char *regname,PyObject *reg); ! ! // Register object ! void Register(PyObject *reg); ! // Unregister object ! void Unregister(PyObject *reg); ! ! virtual void LoadModule() = 0; ! virtual void UnloadModule() = 0; ! ! virtual void Load() = 0; ! virtual void Unload() = 0;
void OpenEditor(); *************** *** 200,204 **** inline void Unlock() {}
! inline PyThreadState *PyLock(PyThreadState *) { return NULL; } inline PyThreadState *PyLockSys() { return NULL; } inline void PyUnlock(PyThreadState *st) {} --- 223,227 ---- inline void Unlock() {}
! inline PyThreadState *PyLock(PyThreadState * = NULL) { return NULL; } inline PyThreadState *PyLockSys() { return NULL; } inline void PyUnlock(PyThreadState *st) {}
Index: register.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/register.cpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** register.cpp 13 Mar 2005 04:59:47 -0000 1.6 --- register.cpp 18 Apr 2005 15:11:43 -0000 1.7 *************** *** 11,14 **** --- 11,82 ---- #include "main.h"
+ #if 1 + + PyObject *pybase::GetRegistry(const char *regnm) + { + if(module) { + FLEXT_ASSERT(dict); // module must have a valid dict + + // add this to module registry + PyObject *reg = PyDict_GetItemString(dict,(char *)regnm); // borrowed!!! + if(reg) + FLEXT_ASSERT(PyDict_Check(reg)); + else { + // make a new empty registry + reg = PyDict_New(); + PyDict_SetItemString(dict,(char *)regnm,reg); + } + return reg; + } + else + return NULL; + } + + void pybase::SetRegistry(const char *regnm,PyObject *reg) + { + if(module) { + FLEXT_ASSERT(dict); // module must have a valid dict + FLEXT_ASSERT(reg && PyDict_Check(reg)); + PyDict_SetItemString(dict,(char *)regnm,reg); + } + } + + void pybase::Register(PyObject *reg) + { + if(!module) return; + FLEXT_ASSERT(reg && PyDict_Check(reg)); + + // add this to module registry + Py_INCREF(Py_None); + PyObject *key = PyLong_FromUnsignedLong((size_t)this); + PyDict_SetItem(reg,key,Py_None); + } + + void pybase::Unregister(PyObject *reg) + { + if(!module) return; + FLEXT_ASSERT(reg && PyDict_Check(reg)); + + // remove this from module registry + PyObject *key = PyLong_FromUnsignedLong((size_t)this); + PyObject *item = PyDict_GetItem(reg,key); + if(!item) + post("py/pyext - Internal error: object not found in registry"); + else + PyDict_DelItem(reg,key); + } + + /* + void pybase::RegLoad(PyObject *reg) + { + + } + + void pybase::RegUnload(PyObject *reg) + { + } + */ + + #else
void pybase::Register(const char *regnm) *************** *** 80,81 **** --- 148,151 ---- } } + + #endif
Index: pyext.h =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/pyext.h,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** pyext.h 7 Apr 2005 15:03:53 -0000 1.22 --- pyext.h 18 Apr 2005 15:11:43 -0000 1.23 *************** *** 62,67 **** void m_help();
! void m_reload(); ! void m_reload_(int argc,const t_atom *argv) { initargs(argc,argv); m_reload(); } void ms_initargs(const AtomList &a) { m_reload_(a.Count(),a.Atoms()); } void m_dir_() { m__dir(pyobj); } --- 62,67 ---- void m_help();
! void m_reload() { Reload(); } ! void m_reload_(int argc,const t_atom *argv) { initargs(argc,argv); Reload(); } void ms_initargs(const AtomList &a) { m_reload_(a.Count(),a.Atoms()); } void m_dir_() { m__dir(pyobj); } *************** *** 79,83 **** flext::AtomListStatic<16> initargs;
! virtual bool Reload(); virtual bool DoInit(); virtual void DoExit(); --- 79,88 ---- flext::AtomListStatic<16> initargs;
! virtual void LoadModule(); ! virtual void UnloadModule(); ! ! virtual void Load(); ! virtual void Unload(); ! virtual bool DoInit(); virtual void DoExit(); *************** *** 91,94 **** --- 96,100 ----
void SetThis(); + void ClearThis();
void ClearBinding();
Index: pyext.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/pyext.cpp,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** pyext.cpp 10 Apr 2005 22:24:13 -0000 1.33 --- pyext.cpp 18 Apr 2005 15:11:43 -0000 1.34 *************** *** 12,15 **** --- 12,16 ---- #include <flinternal.h>
+ FLEXT_LIB_V("pyext pyext. pyx pyx.",pyext)
*************** *** 101,104 **** --- 102,110 ---- }
+ void pyext::ClearThis() + { + int ret = PyObject_DelAttrString(pyobj,"_this"); + FLEXT_ASSERT(ret != -1); + }
PyObject *pyext::class_obj = NULL; *************** *** 170,174 **** }
! Register("_pyext");
if(argc > apre || clname) { --- 176,180 ---- }
! Register(GetRegistry(REGNAME));
if(argc > apre || clname) { *************** *** 209,212 **** --- 215,219 ---- }
+ Report(); PyUnlock(state);
*************** *** 220,226 **** PyThreadState *state = PyLockSys(); DoExit(); ! Unregister("_pyext"); UnimportModule();
PyUnlock(state);
--- 227,235 ---- PyThreadState *state = PyLockSys(); DoExit(); ! ! Unregister(GetRegistry(REGNAME)); UnimportModule();
+ Report(); PyUnlock(state);
*************** *** 230,235 **** bool pyext::DoInit() { - SetThis(); - // call init now, after _this has been set, which is // important for eventual callbacks from __init__ to c --- 239,242 ---- *************** *** 238,246 **** bool ok = true;
PyObject *init = PyObject_GetAttrString(pyobj,"__init__"); // get ref if(init) { if(PyMethod_Check(init)) { PyObject *res = PyObject_CallObject(init,pargs); ! if(!res) ok = false; else --- 245,256 ---- bool ok = true;
+ SetThis(); + PyObject *init = PyObject_GetAttrString(pyobj,"__init__"); // get ref if(init) { if(PyMethod_Check(init)) { PyObject *res = PyObject_CallObject(init,pargs); ! if(!res) ! // exception is set ok = false; else *************** *** 279,282 **** --- 289,294 ---- PyErr_Clear();
+ ClearThis(); + gcrun = pyobj->ob_refcnt > 1; Py_DECREF(pyobj); // opposite of SetClssMeth *************** *** 369,382 **** }
! bool pyext::Reload() { ! DoExit();
! // by here, the Python class destructor should have been called!
! // SetArgs(0,NULL); ! bool ok = ReloadModule(); ! ! if(ok) ok = MakeInstance();
if(ok) { --- 381,397 ---- }
! void pyext::LoadModule() { ! }
! void pyext::UnloadModule() ! { ! }
! void pyext::Load() ! { ! FLEXT_ASSERT(!pyobj); ! ! bool ok = MakeInstance();
if(ok) { *************** *** 388,411 **** }
! return ok; }
! ! void pyext::m_reload() ! { ! PyThreadState *state = PyLockSys(); ! ! Unregister("_pyext"); // self ! ! Reload(); ! ! Reregister("_pyext"); // the others ! Register("_pyext"); // self ! ! SetThis(); ! ! Report(); ! ! PyUnlock(state); }
--- 403,413 ---- }
! // return ok; }
! void pyext::Unload() ! { ! DoExit(); ! pyobj = NULL; }
Index: py.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/py.cpp,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** py.cpp 10 Apr 2005 22:24:13 -0000 1.24 --- py.cpp 18 Apr 2005 15:11:43 -0000 1.25 *************** *** 30,35 **** void m_help();
! void m_reload(); ! void m_reload_(int argc,const t_atom *argv) { args(argc,argv); m_reload(); } void m_set(int argc,const t_atom *argv); void m_dir_() { m__dir(function); } --- 30,35 ---- void m_help();
! void m_reload() { Reload(); } ! void m_reload_(int argc,const t_atom *argv) { args(argc,argv); Reload(); } void m_set(int argc,const t_atom *argv); void m_dir_() { m__dir(function); } *************** *** 49,53 **** bool withfunction;
! virtual bool Reload();
bool SetFunction(const char *func); --- 49,57 ---- bool withfunction;
! virtual void LoadModule(); ! virtual void UnloadModule(); ! ! virtual void Load(); ! virtual void Unload();
bool SetFunction(const char *func); *************** *** 166,170 **** }
! Register("_py");
if(argc >= 2) { --- 170,174 ---- }
! Register(GetRegistry(REGNAME));
if(argc >= 2) { *************** *** 184,188 **** { PyThreadState *state = PyLockSys(); ! Unregister("_py"); Report(); PyUnlock(state); --- 188,192 ---- { PyThreadState *state = PyLockSys(); ! Unregister(GetRegistry(REGNAME)); Report(); PyUnlock(state); *************** *** 202,220 **** }
- void pyobj::m_reload() - { - PyThreadState *state = PyLockSys(); - - Unregister("_py"); - - ReloadModule(); - Reregister("_py"); - Register("_py"); - SetFunction(funname?GetString(funname):NULL); - - Report(); - PyUnlock(state); - } - void pyobj::m_set(int argc,const t_atom *argv) { --- 206,209 ---- *************** *** 229,233 **** if(!module || !strcmp(sn,PyModule_GetName(module))) { ImportModule(sn); ! Register("_py"); } } --- 218,222 ---- if(!module || !strcmp(sn,PyModule_GetName(module))) { ImportModule(sn); ! Register(GetRegistry(REGNAME)); } } *************** *** 317,324 ****
! bool pyobj::Reload() { ResetFunction(); ! return true; }
--- 306,326 ----
! void pyobj::LoadModule() ! { ! SetFunction(funname?GetString(funname):NULL); ! } ! ! void pyobj::UnloadModule() ! { ! } ! ! void pyobj::Load() { ResetFunction(); ! } ! ! void pyobj::Unload() ! { ! SetFunction(NULL); }