[PD-cvs] externals/grill/py/source bound.cpp,1.12,1.13 clmeth.cpp,1.11,1.12 main.cpp,1.18,1.19 main.h,1.25,1.26 modmeth.cpp,1.12,1.13 py.cpp,1.15,1.16 pyargs.cpp,1.9,1.10 pyext.cpp,1.22,1.23 pyext.h,1.17,1.18 register.cpp,1.4,1.5
Thomas Grill
xovo at users.sourceforge.net
Sun Jan 9 05:59:32 CET 2005
- Previous message: [PD-cvs] externals/grill/py license.txt,1.2,1.3 package.txt,1.4,1.5 py.vcproj,1.14,1.15 readme.txt,1.24,1.25
- Next message: [PD-cvs] pd/src s_inter.c,1.5.4.5,1.5.4.6
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/pure-data/externals/grill/py/source
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7214/source
Modified Files:
bound.cpp clmeth.cpp main.cpp main.h modmeth.cpp py.cpp
pyargs.cpp pyext.cpp pyext.h register.cpp
Log Message:
support for Python threads, at last
small fixes
merged in 20041229-newdetach branch.
renamed locking functions
Index: clmeth.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/clmeth.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** clmeth.cpp 17 Dec 2004 05:04:29 -0000 1.11
--- clmeth.cpp 9 Jan 2005 04:59:30 -0000 1.12
***************
*** 3,7 ****
py/pyext - python external object for PD and Max/MSP
! Copyright (c) 2002-2004 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
--- 3,7 ----
py/pyext - python external object for PD and Max/MSP
! Copyright (c)2002-2005 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
***************
*** 40,45 ****
! const C *pyext::pyext_doc =
! "py/pyext - python external object for PD and Max/MSP, (C)2002-2004 Thomas Grill\n"
"\n"
"This is the pyext base class. Available methods:\n"
--- 40,45 ----
! const char *pyext::pyext_doc =
! "py/pyext - python external object for PD and Max/MSP, (C)2002-2005 Thomas Grill\n"
"\n"
"This is the pyext base class. Available methods:\n"
***************
*** 82,86 ****
}
! BL handled = false;
if(PyString_Check(name)) {
char* sname = PyString_AsString(name);
--- 82,86 ----
}
! bool handled = false;
if(PyString_Check(name)) {
char* sname = PyString_AsString(name);
***************
*** 137,141 ****
PyObject *pyext::pyext_outlet(PyObject *,PyObject *args)
{
! BL ok = false;
// should always be a tuple!
--- 137,141 ----
PyObject *pyext::pyext_outlet(PyObject *,PyObject *args)
{
! bool ok = false;
// should always be a tuple!
***************
*** 151,158 ****
pyext *ext = GetThis(self);
! I sz = PyTuple_Size(args);
PyObject *val;
! BL tp =
sz == 3 &&
PySequence_Check(
--- 151,158 ----
pyext *ext = GetThis(self);
! int sz = PyTuple_Size(args);
PyObject *val;
! bool tp =
sz == 3 &&
PySequence_Check(
***************
*** 165,169 ****
AtomList *lst = GetPyArgs(val);
if(lst) {
! I o = PyInt_AsLong(outl);
if(o >= 1 && o <= ext->Outlets()) {
// by using the queue there is no immediate call of the next object
--- 165,169 ----
AtomList *lst = GetPyArgs(val);
if(lst) {
! int o = PyInt_AsLong(outl);
if(o >= 1 && o <= ext->Outlets()) {
// by using the queue there is no immediate call of the next object
***************
*** 226,230 ****
else {
pyext *ext = GetThis(self);
! I cnt = 0;
t_atom at;
if(val >= 0) flext::SetInt(at,val);
--- 226,230 ----
else {
pyext *ext = GetThis(self);
! int cnt = 0;
t_atom at;
if(val >= 0) flext::SetInt(at,val);
***************
*** 256,268 ****
FLEXT_ASSERT(PyTuple_Check(args));
! BL ok = false;
PyObject *self = PyTuple_GetItem(args,0); // borrowed ref
if(self && PyInstance_Check(self)) {
pyext *ext = GetThis(self);
! I sz = PySequence_Size(args);
PyObject *val;
! BL tp =
sz == 2 &&
PySequence_Check(
--- 256,268 ----
FLEXT_ASSERT(PyTuple_Check(args));
! bool ok = false;
PyObject *self = PyTuple_GetItem(args,0); // borrowed ref
if(self && PyInstance_Check(self)) {
pyext *ext = GetThis(self);
! int sz = PySequence_Size(args);
PyObject *val;
! bool tp =
sz == 2 &&
PySequence_Check(
Index: pyargs.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pyargs.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -d -r1.9 -r1.10
*** pyargs.cpp 10 Nov 2004 03:31:34 -0000 1.9
--- pyargs.cpp 9 Jan 2005 04:59:30 -0000 1.10
***************
*** 3,7 ****
py/pyext - python external object for PD and MaxMSP
! Copyright (c)2002-2004 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
--- 3,7 ----
py/pyext - python external object for PD and MaxMSP
! Copyright (c)2002-2005 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
***************
*** 22,26 ****
}
// these following should never happen
! else if(flext::IsFloat(at)) return PyFloat_FromDouble((D)flext::GetFloat(at));
else if(flext::IsInt(at)) return PyInt_FromLong(flext::GetInt(at));
--- 22,26 ----
}
// these following should never happen
! else if(flext::IsFloat(at)) return PyFloat_FromDouble((double)flext::GetFloat(at));
else if(flext::IsInt(at)) return PyInt_FromLong(flext::GetInt(at));
***************
*** 28,32 ****
}
! PyObject *py::MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,I inlet,BL withself)
{
PyObject *pArgs;
--- 28,32 ----
}
! PyObject *py::MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,int inlet,bool withself)
{
PyObject *pArgs;
***************
*** 41,48 ****
*/
{
! BL any = IsAnything(s);
pArgs = PyTuple_New(argc+(any?1:0)+(inlet >= 0?1:0));
! I pix = 0;
if(inlet >= 0) {
--- 41,48 ----
*/
{
! bool any = IsAnything(s);
pArgs = PyTuple_New(argc+(any?1:0)+(inlet >= 0?1:0));
! int pix = 0;
if(inlet >= 0) {
***************
*** 53,57 ****
}
! I ix;
PyObject *tmp;
if(!withself || argc < (any?1:2)) tmp = pArgs,ix = pix;
--- 53,57 ----
}
! int ix;
PyObject *tmp;
if(!withself || argc < (any?1:2)) tmp = pArgs,ix = pix;
***************
*** 65,69 ****
}
! for(I i = 0; i < argc; ++i) {
PyObject *pValue = MakePyAtom(argv[i]);
if(!pValue) {
--- 65,69 ----
}
! for(int i = 0; i < argc; ++i) {
PyObject *pValue = MakePyAtom(argv[i]);
if(!pValue) {
***************
*** 96,101 ****
// analyze return value or tuple
! I rargc = 0;
! BL ok = true;
retval tp = nothing;
--- 96,101 ----
// analyze return value or tuple
! int rargc = 0;
! bool ok = true;
retval tp = nothing;
***************
*** 117,121 ****
ret = new AtomList(rargc);
! for(I ix = 0; ix < rargc; ++ix) {
PyObject *arg;
if(tp == sequ)
--- 117,121 ----
ret = new AtomList(rargc);
! for(int ix = 0; ix < rargc; ++ix) {
PyObject *arg;
if(tp == sequ)
***************
*** 126,130 ****
if(PyInt_Check(arg)) SetInt((*ret)[ix],PyInt_AsLong(arg));
else if(PyLong_Check(arg)) SetInt((*ret)[ix],PyLong_AsLong(arg));
! else if(PyFloat_Check(arg)) SetFloat((*ret)[ix],(F)PyFloat_AsDouble(arg));
else if(PyString_Check(arg)) SetString((*ret)[ix],PyString_AsString(arg));
else if(ix == 0 && self && PyInstance_Check(arg)) {
--- 126,130 ----
if(PyInt_Check(arg)) SetInt((*ret)[ix],PyInt_AsLong(arg));
else if(PyLong_Check(arg)) SetInt((*ret)[ix],PyLong_AsLong(arg));
! else if(PyFloat_Check(arg)) SetFloat((*ret)[ix],(float)PyFloat_AsDouble(arg));
else if(PyString_Check(arg)) SetString((*ret)[ix],PyString_AsString(arg));
else if(ix == 0 && self && PyInstance_Check(arg)) {
***************
*** 136,140 ****
PyObject *tp = PyObject_Type(arg);
PyObject *stp = tp?PyObject_Str(tp):NULL;
! C *tmp = "";
if(stp) tmp = PyString_AsString(stp);
post("py/pyext: Could not convert argument %s",tmp);
--- 136,140 ----
PyObject *tp = PyObject_Type(arg);
PyObject *stp = tp?PyObject_Str(tp):NULL;
! char *tmp = "";
if(stp) tmp = PyString_AsString(stp);
post("py/pyext: Could not convert argument %s",tmp);
Index: main.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/main.cpp,v
retrieving revision 1.18
retrieving revision 1.19
diff -C2 -d -r1.18 -r1.19
*** main.cpp 10 Nov 2004 03:31:34 -0000 1.18
--- main.cpp 9 Jan 2005 04:59:30 -0000 1.19
***************
*** 3,7 ****
py/pyext - python external object for PD and MaxMSP
! Copyright (c)2002-2004 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
--- 3,7 ----
py/pyext - python external object for PD and MaxMSP
! Copyright (c)2002-2005 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
***************
*** 56,66 ****
! V py::lib_setup()
{
post("");
! post("py/pyext %s - python script objects, (C)2002-2004 Thomas Grill",PY__VERSION);
#ifdef FLEXT_DEBUG
post("DEBUG version compiled on %s %s",__DATE__,__TIME__);
#endif
post("");
--- 56,71 ----
! void py::lib_setup()
{
post("");
! post("--------------------------------------");
! post("py/pyext %s - python script objects",PY__VERSION);
! post(" (C)2002-2005 Thomas Grill");
! post(" http://grrrr.org/ext");
#ifdef FLEXT_DEBUG
+ post("");
post("DEBUG version compiled on %s %s",__DATE__,__TIME__);
#endif
+ post("--------------------------------------");
post("");
***************
*** 91,99 ****
module_dict = PyModule_GetDict(module_obj); // borrowed reference
! PyModule_AddStringConstant(module_obj,"__doc__",(C *)py_doc);
// redirect stdout
! PyObject* py_out = Py_InitModule("stdout", StdOut_Methods);
PySys_SetObject("stdout", py_out);
#ifdef FLEXT_THREADS
--- 96,107 ----
module_dict = PyModule_GetDict(module_obj); // borrowed reference
! PyModule_AddStringConstant(module_obj,"__doc__",(char *)py_doc);
// redirect stdout
! PyObject* py_out;
! py_out = Py_InitModule("stdout", StdOut_Methods);
PySys_SetObject("stdout", py_out);
+ py_out = Py_InitModule("stderr", StdOut_Methods);
+ PySys_SetObject("stderr", py_out);
#ifdef FLEXT_THREADS
***************
*** 117,137 ****
py::py():
module(NULL),
! detach(false),shouldexit(false),thrcount(0),
stoptick(0)
{
! PY_LOCK
Py_INCREF(module_obj);
! PY_UNLOCK
FLEXT_ADDTIMER(stoptmr,tick);
}
py::~py()
{
! if(thrcount) {
! shouldexit = true;
!
// Wait for a certain time
! for(int i = 0; i < (PY_STOP_WAIT/PY_STOP_TICK) && thrcount; ++i) Sleep((F)(PY_STOP_TICK/1000.));
// Wait forever
--- 125,151 ----
py::py():
module(NULL),
! detach(0),shouldexit(false),thrcount(0),
stoptick(0)
{
! // interpreter = PyInterpreterState_New();
!
! PyThreadState *state = PyLock();
Py_INCREF(module_obj);
! PyUnlock(state);
FLEXT_ADDTIMER(stoptmr,tick);
+
+ // launch thread worker
+ FLEXT_CALLMETHOD(threadworker);
}
py::~py()
{
! shouldexit = true;
! qucond.Signal();
!
! if(thrcount) {
// Wait for a certain time
! for(int i = 0; i < (PY_STOP_WAIT/PY_STOP_TICK) && thrcount; ++i) Sleep((float)(PY_STOP_TICK/1000.));
// Wait forever
***************
*** 142,145 ****
--- 156,165 ----
Py_XDECREF(module_obj);
+ /*
+ PyEval_AcquireLock();
+ PyInterpreterState_Clear(interpreter);
+ PyInterpreterState_Delete(interpreter);
+ PyEval_ReleaseLock();
+ */
}
***************
*** 148,152 ****
{
if(obj) {
! PY_LOCK
PyObject *pvar = PyObject_Dir(obj);
--- 168,172 ----
{
if(obj) {
! PyThreadState *state = PyLock();
PyObject *pvar = PyObject_Dir(obj);
***************
*** 163,167 ****
}
! PY_UNLOCK
}
}
--- 183,187 ----
}
! PyUnlock(state);
}
}
***************
*** 175,182 ****
}
! V py::m__doc(PyObject *obj)
{
if(obj) {
! PY_LOCK
PyObject *docf = PyDict_GetItemString(obj,"__doc__"); // borrowed!!!
--- 195,202 ----
}
! void py::m__doc(PyObject *obj)
{
if(obj) {
! PyThreadState *state = PyLock();
PyObject *docf = PyDict_GetItemString(obj,"__doc__"); // borrowed!!!
***************
*** 207,221 ****
}
! PY_UNLOCK
}
}
! V py::SetArgs(I argc,const t_atom *argv)
{
// script arguments
! C **sargv = new C *[argc+1];
for(int i = 0; i <= argc; ++i) {
! sargv[i] = new C[256];
if(!i)
strcpy(sargv[i],thisName());
--- 227,241 ----
}
! PyUnlock(state);
}
}
! void py::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());
***************
*** 231,239 ****
}
! V py::ImportModule(const C *name)
{
if(!name) return;
! module = PyImport_ImportModule((C *)name); // increases module_obj ref count by one
if (!module) {
--- 251,259 ----
}
! void py::ImportModule(const char *name)
{
if(!name) return;
! module = PyImport_ImportModule((char *)name); // increases module_obj ref count by one
if (!module) {
***************
*** 245,249 ****
}
! V py::UnimportModule()
{
if(!module) return;
--- 265,269 ----
}
! void py::UnimportModule()
{
if(!module) return;
***************
*** 261,265 ****
}
! V py::ReloadModule()
{
if(module) {
--- 281,285 ----
}
! void py::ReloadModule()
{
if(module) {
***************
*** 280,290 ****
}
! V py::GetModulePath(const C *mod,C *dir,I len)
{
#if FLEXT_SYS == FLEXT_SYS_PD
// uarghh... pd doesn't show its path for extra modules
! C *name;
! I fd = open_via_path("",mod,".py",dir,&name,len,0);
if(fd > 0) close(fd);
else name = NULL;
--- 300,310 ----
}
! void py::GetModulePath(const char *mod,char *dir,int len)
{
#if FLEXT_SYS == FLEXT_SYS_PD
// uarghh... pd doesn't show its path for extra modules
! char *name;
! int fd = open_via_path("",mod,".py",dir,&name,len,0);
if(fd > 0) close(fd);
else name = NULL;
***************
*** 296,303 ****
short path;
long type;
! char smod[256];
strcat(strcpy(smod,mod),".py");
! if(!locatefile_extended(smod,&path,&type,&type,-1))
path_topathname(path,NULL,dir);
else
// not found
--- 316,338 ----
short path;
long type;
! char smod[1024];
strcat(strcpy(smod,mod),".py");
! if(!locatefile_extended(smod,&path,&type,&type,-1)) {
! #if FLEXT_OS == FLEXT_OS_WIN
path_topathname(path,NULL,dir);
+ #else
+ // convert pathname to unix style
+ path_topathname(path,NULL,smod);
+ char *colon = strchr(smod,':');
+ if(colon) {
+ *colon = 0;
+ strcpy(dir,"/Volumes/");
+ strcat(dir,smod);
+ strcat(dir,colon+1);
+ }
+ else
+ strcpy(dir,smod);
+ #endif
+ }
else
// not found
***************
*** 308,312 ****
}
! V py::AddToPath(const C *dir)
{
if(dir && *dir) {
--- 343,347 ----
}
! void py::AddToPath(const char *dir)
{
if(dir && *dir) {
***************
*** 327,330 ****
--- 362,378 ----
}
+ static const t_symbol *sym_response = flext::MakeSymbol("response");
+
+ void py::Respond(bool b)
+ {
+ if(respond) {
+ t_atom a;
+ SetBool(a,b);
+ ToOutAnything(GetOutAttr(),sym_response,1,&a);
+ }
+ }
+
+
+
static PyObject *output = NULL;
***************
*** 369,370 ****
--- 417,542 ----
return Py_None;
}
+
+
+ class work_data
+ {
+ public:
+ work_data(PyObject *f,PyObject *a): fun(f),args(a) {}
+ ~work_data() { Py_DECREF(fun); Py_DECREF(args); }
+
+ PyObject *fun,*args;
+ };
+
+ bool py::gencall(PyObject *pmeth,PyObject *pargs)
+ {
+ bool ret = false;
+
+ // Now call method
+ switch(detach) {
+ case 0:
+ ret = callpy(pmeth,pargs);
+ Py_DECREF(pargs);
+ Py_DECREF(pmeth);
+ break;
+ case 1:
+ // put call into queue
+ ret = qucall(pmeth,pargs);
+ break;
+ 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());
+ }
+ break;
+ default:
+ FLEXT_ASSERT(false);
+ }
+ return ret;
+ }
+
+ void py::work_wrapper(void *data)
+ {
+ FLEXT_ASSERT(data);
+
+ ++thrcount;
+
+ PyThreadState *state = PyLock();
+
+ // call worker
+ work_data *w = (work_data *)data;
+ callpy(w->fun,w->args);
+ delete w;
+
+ PyUnlock(state);
+
+ --thrcount;
+ }
+
+ bool py::qucall(PyObject *fun,PyObject *args)
+ {
+ if(qufifo.Push(fun,args)) {
+ qucond.Signal();
+ return true;
+ }
+ else
+ return false;
+ }
+
+ void py::threadworker()
+ {
+ PyObject *fun,*args;
+ PyThreadState *state;
+
+ while(!shouldexit) {
+ state = PyLock();
+ while(qufifo.Pop(fun,args)) {
+ callpy(fun,args);
+ Py_XDECREF(fun);
+ Py_XDECREF(args);
+ }
+ PyUnlock(state);
+ qucond.Wait();
+ }
+
+ state = PyLock();
+ // unref remaining Python objects
+ while(qufifo.Pop(fun,args)) {
+ Py_XDECREF(fun);
+ Py_XDECREF(args);
+ }
+ PyUnlock(state);
+ }
+
+ Fifo::~Fifo()
+ {
+ FifoEl *el = head;
+ while(el) {
+ FifoEl *n = el->nxt;
+ delete el;
+ el = n;
+ }
+ }
+
+ bool Fifo::Push(PyObject *f,PyObject *a)
+ {
+ FifoEl *el = new FifoEl;
+ el->fun = f;
+ el->args = a;
+ if(tail) tail->nxt = el;
+ else head = el;
+ tail = el;
+ return true;
+ }
+
+ bool Fifo::Pop(PyObject *&f,PyObject *&a)
+ {
+ if(!head) return false;
+ FifoEl *el = head;
+ head = el->nxt;
+ f = el->fun;
+ a = el->args;
+ if(tail == el) tail = NULL;
+ delete el;
+ return true;
+ }
Index: pyext.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pyext.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -C2 -d -r1.17 -r1.18
*** pyext.h 10 Nov 2004 03:31:34 -0000 1.17
--- pyext.h 9 Jan 2005 04:59:30 -0000 1.18
***************
*** 3,7 ****
py/pyext - python external object for PD and MaxMSP
! Copyright (c)2002-2004 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
--- 3,7 ----
py/pyext - python external object for PD and MaxMSP
! Copyright (c)2002-2005 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
***************
*** 20,24 ****
public:
! pyext(I argc,const t_atom *argv);
~pyext();
--- 20,24 ----
public:
! pyext(int argc,const t_atom *argv);
~pyext();
***************
*** 39,82 ****
static PyObject *pyext_isthreaded(PyObject *,PyObject *);
! I Inlets() const { return inlets; }
! I Outlets() const { return outlets; }
protected:
! virtual BL m_method_(I n,const t_symbol *s,I argc,const t_atom *argv);
! BL work(I n,const t_symbol *s,I argc,const t_atom *argv);
! V m_reload();
! V m_reload_(I argc,const t_atom *argv);
! V ms_args(const AtomList &a) { m_reload_(a.Count(),a.Atoms()); }
! V m_dir_() { m__dir(pyobj); }
! V mg_dir_(AtomList &lst) { GetDir(pyobj,lst); }
! V m_doc_() { m__doc(((PyInstanceObject *)pyobj)->in_class->cl_dict); }
! virtual V m_help();
! V m_get(const t_symbol *s);
! V m_set(I argc,const t_atom *argv);
const t_symbol *methname;
PyObject *pyobj;
! I inlets,outlets;
private:
! static V Setup(t_classid);
static pyext *GetThis(PyObject *self);
void SetThis();
! V ClearBinding();
! BL MakeInstance();
! BL DoInit();
AtomList args;
! virtual V Reload();
static PyObject *class_obj,*class_dict;
static PyMethodDef attr_tbl[],meth_tbl[];
! static const C *pyext_doc;
// -------- bind stuff ------------------
--- 39,82 ----
static PyObject *pyext_isthreaded(PyObject *,PyObject *);
! 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);
! bool work(int n,const t_symbol *s,int argc,const t_atom *argv);
! 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);
const t_symbol *methname;
PyObject *pyobj;
! int inlets,outlets;
private:
! static void Setup(t_classid);
static pyext *GetThis(PyObject *self);
void SetThis();
! void ClearBinding();
! bool MakeInstance();
! bool DoInit();
AtomList args;
! virtual void Reload();
static PyObject *class_obj,*class_dict;
static PyMethodDef attr_tbl[],meth_tbl[];
! static const char *pyext_doc;
// -------- bind stuff ------------------
***************
*** 86,107 ****
// ---------------------------
! PyObject *call(const C *meth,I inlet,const t_symbol *s,I argc,const t_atom *argv);
!
! V work_wrapper(void *data);
! BL callwork(I n,const t_symbol *s,I argc,const t_atom *argv);
!
! class work_data:
! public flext::AtomAnything
! {
! public:
! work_data(I _n,const t_symbol *_s,I _argc,const t_atom *_argv): n(_n),AtomAnything(_s,_argc,_argv) {}
! I n;
! };
! #ifdef FLEXT_THREADS
! FLEXT_THREAD_X(work_wrapper)
! #else
! FLEXT_CALLBACK_X(work_wrapper)
! #endif
PyThreadState *pythr;
--- 86,93 ----
// ---------------------------
! bool call(const char *meth,int inlet,const t_symbol *s,int argc,const t_atom *argv);
! virtual bool callpy(PyObject *fun,PyObject *args);
! static bool stcallpy(PyObject *fun,PyObject *args);
PyThreadState *pythr;
Index: modmeth.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/modmeth.cpp,v
retrieving revision 1.12
retrieving revision 1.13
diff -C2 -d -r1.12 -r1.13
*** modmeth.cpp 10 Nov 2004 03:31:34 -0000 1.12
--- modmeth.cpp 9 Jan 2005 04:59:30 -0000 1.13
***************
*** 3,7 ****
py/pyext - python external object for PD and Max/MSP
! Copyright (c) 2002-2004 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
--- 3,7 ----
py/pyext - python external object for PD and Max/MSP
! Copyright (c)2002-2005 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
***************
*** 22,27 ****
{ "_samplerate", py::py_samplerate, METH_NOARGS,"Get system sample rate" },
{ "_blocksize", py::py_blocksize, METH_NOARGS,"Get system block size" },
- { "_inchannels", py::py_inchannels, METH_NOARGS,"Get number of audio in channels" },
- { "_outchannels", py::py_outchannels, METH_NOARGS,"Get number of audio out channels" },
#if FLEXT_SYS == FLEXT_SYS_PD
--- 22,25 ----
***************
*** 33,38 ****
};
! const C *py::py_doc =
! "py/pyext - python external object for PD and Max/MSP, (C)2002-2004 Thomas Grill\n"
"\n"
"This is the pyext module. Available function:\n"
--- 31,36 ----
};
! const char *py::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"
***************
*** 43,48 ****
"_samplerate(): Get system sample rate\n"
"_blocksize(): Get current blocksize\n"
- "_inchannels(): Get number of audio in channels\n"
- "_outchannels(): Get number of audio out channels\n"
"_getvalue(name): Get value of a 'value' object\n"
"_setvalue(name,float): Set value of a 'value' object\n"
--- 41,44 ----
***************
*** 51,55 ****
! V py::tick(V *)
{
Lock();
--- 47,51 ----
! void py::tick(void *)
{
Lock();
***************
*** 74,86 ****
}
! V py::m_stop(int argc,const t_atom *argv)
{
if(thrcount) {
Lock();
! I wait = PY_STOP_WAIT;
if(argc >= 1 && CanbeInt(argv[0])) wait = GetAInt(argv[0]);
! I ticks = wait/PY_STOP_TICK;
if(stoptick) {
// already stopping
--- 70,82 ----
}
! void py::m_stop(int argc,const t_atom *argv)
{
if(thrcount) {
Lock();
! int wait = PY_STOP_WAIT;
if(argc >= 1 && CanbeInt(argv[0])) wait = GetAInt(argv[0]);
! int ticks = wait/PY_STOP_TICK;
if(stoptick) {
// already stopping
***************
*** 107,136 ****
}
- PyObject *py::py_inchannels(PyObject *self,PyObject *args)
- {
- #if FLEXT_SYS == FLEXT_SYS_PD
- I ch = sys_get_inchannels();
- #elif FLEXT_SYS == FLEXT_SYS_MAX
- I ch = sys_getch(); // not working
- #else
- #pragma message("Not implemented!")
- ch = 0;
- #endif
- return PyLong_FromLong(ch);
- }
-
- PyObject *py::py_outchannels(PyObject *self,PyObject *args)
- {
- #if FLEXT_SYS == FLEXT_SYS_PD
- I ch = sys_get_outchannels();
- #elif FLEXT_SYS == FLEXT_SYS_MAX
- I ch = sys_getch(); // not working
- #else
- #pragma message("Not implemented!")
- ch = 0;
- #endif
- return PyLong_FromLong(ch);
- }
-
PyObject *py::py_send(PyObject *,PyObject *args)
{
--- 103,106 ----
Index: bound.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/bound.cpp,v
retrieving revision 1.12
retrieving revision 1.13
diff -C2 -d -r1.12 -r1.13
*** bound.cpp 10 Nov 2004 03:31:34 -0000 1.12
--- bound.cpp 9 Jan 2005 04:59:30 -0000 1.13
***************
*** 3,7 ****
py/pyext - python external object for PD and MaxMSP
! Copyright (c) 2002-2004 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
--- 3,7 ----
py/pyext - python external object for PD and MaxMSP
! Copyright (c)2002-2005 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
***************
*** 22,30 ****
};
! bool pyext::boundmeth(flext_base *,t_symbol *sym,int argc,t_atom *argv,void *data)
{
bounddata *obj = (bounddata *)data;
! PY_LOCK
PyObject *args = MakePyArgs(sym,argc,argv,-1,obj->self != NULL);
--- 22,31 ----
};
! 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);
! PyThreadState *state = pyth->PyLock();
PyObject *args = MakePyArgs(sym,argc,argv,-1,obj->self != NULL);
***************
*** 41,45 ****
Py_XDECREF(args);
! PY_UNLOCK
return true;
}
--- 42,46 ----
Py_XDECREF(args);
! pyth->PyUnlock(state);
return true;
}
***************
*** 48,52 ****
{
PyObject *self,*meth;
! C *name;
if(!PyArg_ParseTuple(args, "OsO:pyext_bind", &self,&name,&meth))
post("py/pyext - Wrong arguments!");
--- 49,53 ----
{
PyObject *self,*meth;
! char *name;
if(!PyArg_ParseTuple(args, "OsO:pyext_bind", &self,&name,&meth))
post("py/pyext - Wrong arguments!");
***************
*** 92,96 ****
{
PyObject *self,*meth;
! C *name;
if(!PyArg_ParseTuple(args, "OsO:pyext_bind", &self,&name,&meth))
post("py/pyext - Wrong arguments!");
--- 93,97 ----
{
PyObject *self,*meth;
! char *name;
if(!PyArg_ParseTuple(args, "OsO:pyext_bind", &self,&name,&meth))
post("py/pyext - Wrong arguments!");
***************
*** 128,132 ****
! V pyext::ClearBinding()
{
// in case the object couldn't be constructed...
--- 129,133 ----
! void pyext::ClearBinding()
{
// in case the object couldn't be constructed...
Index: register.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/register.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** register.cpp 10 Nov 2004 03:31:34 -0000 1.4
--- register.cpp 9 Jan 2005 04:59:30 -0000 1.5
***************
*** 3,7 ****
py/pyext - python external object for PD and MaxMSP
! Copyright (c) 2002-2004 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
--- 3,7 ----
py/pyext - python external object for PD and MaxMSP
! Copyright (c)2002-2005 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
***************
*** 12,27 ****
! V py::Register(const C *regnm)
{
if(module) {
// add this to module registry
! PyObject *reg = PyDict_GetItemString(dict,(C *)regnm); // borrowed!!!
PyObject *add = Py_BuildValue("[i]",(long)this);
if(!reg || !PyList_Check(reg)) {
! if(PyDict_SetItemString(dict,(C *)regnm,add)) {
post("%s - Could not set registry",thisName());
}
- // Py_XDECREF(reg);
}
else {
--- 12,26 ----
! void py::Register(const char *regnm)
{
if(module) {
// add this to module registry
! PyObject *reg = PyDict_GetItemString(dict,(char *)regnm); // borrowed!!!
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());
}
}
else {
***************
*** 29,48 ****
}
}
-
}
! V py::Unregister(const C *regnm)
{
if(module) {
// remove this from module registry
! PyObject *reg = PyDict_GetItemString(dict,(C *)regnm); // borrowed!!!
PyObject *add = Py_BuildValue("i",(int)this);
if(!reg || !PySequence_Check(reg))
! post("%s - Registry not found!?",thisName());
else {
! I ix = PySequence_Index(reg,add);
if(ix < 0) {
! post("%s - This object not found in registry?!",thisName());
}
else {
--- 28,46 ----
}
}
}
! void py::Unregister(const char *regnm)
{
if(module) {
// remove this from module registry
! 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());
else {
! int ix = PySequence_Index(reg,add);
if(ix < 0) {
! post("%s - Internal error: object not found in registry?!",thisName());
}
else {
***************
*** 52,73 ****
Py_DECREF(add);
}
-
}
! V py::Reregister(const C *regnm)
{
if(module) {
// remove this from module registry
! PyObject *reg = PyDict_GetItemString(dict,(C *)regnm); // borrowed!!!
if(!reg || !PySequence_Check(reg))
! post("%s - Registry not found!?",thisName());
else {
! I cnt = PySequence_Size(reg);
! for(I i = 0; i < cnt; ++i) {
PyObject *it = PySequence_GetItem(reg,i); // new reference
if(!it || !PyInt_Check(it)) {
! post("%s - Corrupt registry?!",thisName());
}
else {
--- 50,70 ----
Py_DECREF(add);
}
}
! void py::Reregister(const char *regnm)
{
if(module) {
// remove this from module registry
! PyObject *reg = PyDict_GetItemString(dict,(char *)regnm); // borrowed!!!
if(!reg || !PySequence_Check(reg))
! post("%s - Internal error: Registry not found!?",thisName());
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());
}
else {
***************
*** 82,88 ****
}
}
-
}
-
-
-
--- 79,81 ----
Index: main.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/main.h,v
retrieving revision 1.25
retrieving revision 1.26
diff -C2 -d -r1.25 -r1.26
*** main.h 17 Dec 2004 05:04:29 -0000 1.25
--- main.h 9 Jan 2005 04:59:30 -0000 1.26
***************
*** 3,7 ****
py/pyext - python script object for PD and MaxMSP
! Copyright (c)2002-2004 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
--- 3,7 ----
py/pyext - python script object for PD and MaxMSP
! Copyright (c)2002-2005 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
***************
*** 25,30 ****
#endif
! #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 408)
! #error You need at least flext version 0.4.8
#endif
--- 25,30 ----
#endif
! #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 500)
! #error You need at least flext version 0.5.0
#endif
***************
*** 39,52 ****
! #define I int
! #define C char
! #define V void
! #define BL bool
! #define F float
! #define D double
! #include "main.h"
class py:
--- 39,64 ----
+ class Fifo
+ {
+ protected:
+ struct FifoEl {
+ PyObject *fun;
+ PyObject *args;
+ FifoEl *nxt;
+ };
+ public:
+ Fifo(): head(NULL),tail(NULL) {}
+ ~Fifo();
! bool Push(PyObject *f,PyObject *a);
! bool Pop(PyObject *&f,PyObject *&a);
!
! protected:
! FifoEl *head,*tail;
! };
! PyThreadState *FindThreadState();
! void FreeThreadState();
class py:
***************
*** 58,98 ****
py();
~py();
! static V lib_setup();
! static PyObject *MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,I inlet = -1,BL withself = false);
static AtomList *GetPyArgs(PyObject *pValue,PyObject **self = NULL);
protected:
! V m__dir(PyObject *obj);
! V m__doc(PyObject *obj);
! V m_dir() { m__dir(module); }
! V mg_dir(AtomList &lst) { m__dir(module); }
! V m_doc() { m__doc(dict); }
PyObject *module,*dict; // inherited user class module and associated dictionary
! static const C *py_doc;
! V GetDir(PyObject *obj,AtomList &lst);
! V GetModulePath(const C *mod,C *dir,I len);
! V AddToPath(const C *dir);
! V SetArgs(I argc,const t_atom *argv);
! V ImportModule(const C *name);
! V UnimportModule();
! V ReloadModule();
! V Register(const C *reg);
! V Unregister(const C *reg);
! V Reregister(const C *reg);
! virtual V Reload() = 0;
! V Respond(BL b) { if(respond) { t_atom a[1]; SetBool(a[0],b); ToOutAnything(GetOutAttr(),MakeSymbol("response"),1,a); } }
! static BL IsAnything(const t_symbol *s) { return s && s != sym_bang && s != sym_float && s != sym_int && s != sym_symbol && s != sym_list && s != sym_pointer; }
! enum retval { nothing,atom,sequ /*,tuple,list*/ };
// --- module stuff -----
--- 70,110 ----
py();
~py();
! static void lib_setup();
! 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);
protected:
! void m__dir(PyObject *obj);
! void m__doc(PyObject *obj);
! void m_dir() { m__dir(module); }
! void mg_dir(AtomList &lst) { m__dir(module); }
! void m_doc() { m__doc(dict); }
PyObject *module,*dict; // inherited user class module and associated dictionary
! static const char *py_doc;
! void GetDir(PyObject *obj,AtomList &lst);
! void GetModulePath(const char *mod,char *dir,int len);
! void AddToPath(const char *dir);
! void SetArgs(int argc,const t_atom *argv);
! void ImportModule(const char *name);
! void UnimportModule();
! void ReloadModule();
! void Register(const char *reg);
! void Unregister(const char *reg);
! void Reregister(const char *reg);
! virtual void Reload() = 0;
! void Respond(bool b);
! static bool IsAnything(const t_symbol *s) { return s && s != sym_bang && s != sym_float && s != sym_int && s != sym_symbol && s != sym_list && s != sym_pointer; }
! enum retval { nothing,atom,sequ };
// --- module stuff -----
***************
*** 109,114 ****
static PyObject *py_samplerate(PyObject *,PyObject *args);
static PyObject *py_blocksize(PyObject *,PyObject *args);
! static PyObject *py_inchannels(PyObject *,PyObject *args);
! static PyObject *py_outchannels(PyObject *,PyObject *args);
#if FLEXT_SYS == FLEXT_SYS_PD
static PyObject *py_getvalue(PyObject *,PyObject *args);
--- 121,125 ----
static PyObject *py_samplerate(PyObject *,PyObject *args);
static PyObject *py_blocksize(PyObject *,PyObject *args);
!
#if FLEXT_SYS == FLEXT_SYS_PD
static PyObject *py_getvalue(PyObject *,PyObject *args);
***************
*** 118,129 ****
// ----thread stuff ------------
! virtual V m_stop(int argc,const t_atom *argv);
! BL detach,shouldexit,respond;
! I thrcount;
! I stoptick;
Timer stoptmr;
! V tick(V *);
public:
--- 129,160 ----
// ----thread stuff ------------
! virtual void m_stop(int argc,const t_atom *argv);
! bool shouldexit,respond;
! int thrcount;
! int stoptick;
Timer stoptmr;
+ int detach;
! void tick(void *);
!
! bool gencall(PyObject *fun,PyObject *args);
! virtual bool callpy(PyObject *fun,PyObject *args) = 0;
!
! private:
! // PyInterpreterState *interpreter;
!
! bool qucall(PyObject *fun,PyObject *args);
! void threadworker();
! Fifo qufifo;
! ThrCond qucond;
!
! void work_wrapper(void *data);
!
! #ifdef FLEXT_THREADS
! FLEXT_THREAD_X(work_wrapper)
! #else
! FLEXT_CALLBACK_X(work_wrapper)
! #endif
public:
***************
*** 131,139 ****
#ifdef FLEXT_THREADS
ThrMutex mutex;
! inline V Lock() { mutex.Unlock(); }
! inline V Unlock() { mutex.Unlock(); }
#else
! inline V Lock() {}
! inline V Unlock() {}
#endif
--- 162,185 ----
#ifdef FLEXT_THREADS
ThrMutex mutex;
! inline void Lock() { mutex.Unlock(); }
! inline void Unlock() { mutex.Unlock(); }
!
! inline PyThreadState *PyLock()
! {
! PyEval_AcquireLock();
! return PyThreadState_Swap(FindThreadState());
! }
!
! inline void PyUnlock(PyThreadState *st)
! {
! PyThreadState_Swap(st);
! PyEval_ReleaseLock();
! }
#else
! inline void Lock() {}
! inline void Unlock() {}
!
! inline PyThreadState *PyLock() { return NULL; }
! inline void PyUnlock(PyThreadState *st) {}
#endif
***************
*** 143,147 ****
// callbacks
! FLEXT_ATTRVAR_B(detach)
FLEXT_ATTRVAR_B(respond)
FLEXT_CALLBACK_V(m_stop)
--- 189,193 ----
// callbacks
! FLEXT_ATTRVAR_I(detach)
FLEXT_ATTRVAR_B(respond)
FLEXT_CALLBACK_V(m_stop)
***************
*** 150,175 ****
FLEXT_CALLBACK(m_doc)
FLEXT_CALLBACK_T(tick)
- };
! #ifdef FLEXT_THREADS
!
! PyThreadState *FindThreadState();
! void FreeThreadState();
!
! #define PY_LOCK \
! { \
! PyEval_AcquireLock(); \
! PyThreadState *__st = FindThreadState(); \
! PyThreadState *__oldst = PyThreadState_Swap(__st);
!
! #define PY_UNLOCK \
! PyThreadState_Swap(__oldst); \
! PyEval_ReleaseLock(); \
! }
!
! #else
! #define PY_LOCK
! #define PY_UNLOCK
! #endif
#endif
--- 196,202 ----
FLEXT_CALLBACK(m_doc)
FLEXT_CALLBACK_T(tick)
! FLEXT_THREAD(threadworker)
! };
#endif
Index: pyext.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pyext.cpp,v
retrieving revision 1.22
retrieving revision 1.23
diff -C2 -d -r1.22 -r1.23
*** pyext.cpp 10 Nov 2004 03:31:34 -0000 1.22
--- pyext.cpp 9 Jan 2005 04:59:30 -0000 1.23
***************
*** 3,7 ****
py/pyext - python script object for PD and Max/MSP
! Copyright (c)2002-2004 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
--- 3,7 ----
py/pyext - python script object for PD and Max/MSP
! Copyright (c)2002-2005 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
***************
*** 14,20 ****
FLEXT_LIB_V("pyext pyext. pyx pyx.",pyext)
! V pyext::Setup(t_classid c)
{
! FLEXT_CADDMETHOD_(c,0,"reload.",m_reload);
FLEXT_CADDMETHOD_(c,0,"reload",m_reload_);
FLEXT_CADDMETHOD_(c,0,"dir",m_dir);
--- 14,25 ----
FLEXT_LIB_V("pyext pyext. pyx pyx.",pyext)
!
! static const t_symbol *sym_get;
!
! void pyext::Setup(t_classid c)
{
! sym_get = flext::MakeSymbol("get");
!
! FLEXT_CADDMETHOD_(c,0,"reload.",m_reload);
FLEXT_CADDMETHOD_(c,0,"reload",m_reload_);
FLEXT_CADDMETHOD_(c,0,"dir",m_dir);
***************
*** 36,40 ****
FLEXT_CADDATTR_VAR1(c,"respond",respond);
-
// ----------------------------------------------------
--- 41,44 ----
***************
*** 113,117 ****
PyObject *pyext::class_dict = NULL;
! pyext::pyext(I argc,const t_atom *argv):
pyobj(NULL),pythr(NULL),
inlets(-1),outlets(-1),
--- 117,121 ----
PyObject *pyext::class_dict = NULL;
! pyext::pyext(int argc,const t_atom *argv):
pyobj(NULL),pythr(NULL),
inlets(-1),outlets(-1),
***************
*** 128,132 ****
const t_atom *clname = NULL;
! PY_LOCK
// init script module
--- 132,136 ----
const t_atom *clname = NULL;
! PyThreadState *state = PyLock();
// init script module
***************
*** 239,243 ****
inlets = outlets = 0;
! PY_UNLOCK
if(inlets < 0 || outlets < 0)
--- 243,247 ----
inlets = outlets = 0;
! PyUnlock(state);
if(inlets < 0 || outlets < 0)
***************
*** 254,258 ****
pyext::~pyext()
{
! PY_LOCK
ClearBinding();
--- 258,262 ----
pyext::~pyext()
{
! PyThreadState *state = PyLock();
ClearBinding();
***************
*** 266,273 ****
UnimportModule();
! PY_UNLOCK
}
! BL pyext::DoInit()
{
SetThis();
--- 270,277 ----
UnimportModule();
! PyUnlock(state);
}
! bool pyext::DoInit()
{
SetThis();
***************
*** 294,303 ****
}
! BL pyext::MakeInstance()
{
// pyobj should already have been decref'd / cleared before getting here!!
if(module && methname) {
! PyObject *pref = PyObject_GetAttrString(module,const_cast<C *>(GetString(methname)));
if(!pref)
PyErr_Print();
--- 298,307 ----
}
! bool pyext::MakeInstance()
{
// pyobj should already have been decref'd / cleared before getting here!!
if(module && methname) {
! PyObject *pref = PyObject_GetAttrString(module,const_cast<char *>(GetString(methname)));
if(!pref)
PyErr_Print();
***************
*** 320,324 ****
}
! V pyext::Reload()
{
ClearBinding();
--- 324,328 ----
}
! void pyext::Reload()
{
ClearBinding();
***************
*** 334,340 ****
! V pyext::m_reload()
{
! PY_LOCK
Unregister("_pyext"); // self
--- 338,344 ----
! void pyext::m_reload()
{
! PyThreadState *state = PyLock();
Unregister("_pyext"); // self
***************
*** 347,354 ****
SetThis();
! PY_UNLOCK
}
! V pyext::m_reload_(I argc,const t_atom *argv)
{
args(argc,argv);
--- 351,358 ----
SetThis();
! PyUnlock(state);
}
! void pyext::m_reload_(int argc,const t_atom *argv)
{
args(argc,argv);
***************
*** 358,362 ****
void pyext::m_get(const t_symbol *s)
{
! PY_LOCK
PyObject *pvar = PyObject_GetAttrString(pyobj,const_cast<char *>(GetString(s))); /* fetch bound method */
--- 362,366 ----
void pyext::m_get(const t_symbol *s)
{
! PyThreadState *state = PyLock();
PyObject *pvar = PyObject_GetAttrString(pyobj,const_cast<char *>(GetString(s))); /* fetch bound method */
***************
*** 369,373 ****
if(lst) {
// dump value to attribute outlet
! AtomAnything out("get",lst->Count()+1);
SetSymbol(out[0],s);
out.Set(lst->Count(),lst->Atoms(),1);
--- 373,377 ----
if(lst) {
// dump value to attribute outlet
! AtomAnything out(sym_get,lst->Count()+1);
SetSymbol(out[0],s);
out.Set(lst->Count(),lst->Atoms(),1);
***************
*** 381,390 ****
}
! PY_UNLOCK
}
void pyext::m_set(int argc,const t_atom *argv)
{
! PY_LOCK
if(argc < 2 || !IsString(argv[0]))
--- 385,394 ----
}
! PyUnlock(state);
}
void pyext::m_set(int argc,const t_atom *argv)
{
! PyThreadState *state = PyLock();
if(argc < 2 || !IsString(argv[0]))
***************
*** 418,430 ****
}
! PY_UNLOCK
}
! BL pyext::m_method_(I n,const t_symbol *s,I argc,const t_atom *argv)
{
! BL ret = false;
if(pyobj && n >= 1)
! ret = callwork(n,s,argc,argv);
else
post("%s - no method for type '%s' into inlet %i",thisName(),GetString(s),n);
--- 422,434 ----
}
! PyUnlock(state);
}
! bool pyext::m_method_(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);
else
post("%s - no method for type '%s' into inlet %i",thisName(),GetString(s),n);
***************
*** 433,440 ****
! V pyext::m_help()
{
post("");
! post("%s %s - python class object, (C)2002-2004 Thomas Grill",thisName(),PY__VERSION);
#ifdef FLEXT_DEBUG
post("DEBUG VERSION, compiled on " __DATE__ " " __TIME__);
--- 437,444 ----
! void pyext::m_help()
{
post("");
! post("%s %s - python class object, (C)2002-2005 Thomas Grill",thisName(),PY__VERSION);
#ifdef FLEXT_DEBUG
post("DEBUG VERSION, compiled on " __DATE__ " " __TIME__);
***************
*** 461,469 ****
}
! PyObject *pyext::call(const C *meth,I inlet,const t_symbol *s,I argc,const t_atom *argv)
{
! PyObject *ret = NULL;
! PyObject *pmeth = PyObject_GetAttrString(pyobj,const_cast<char *>(meth)); /* fetch bound method */
if(pmeth == NULL) {
PyErr_Clear(); // no method found
--- 465,489 ----
}
! bool pyext::callpy(PyObject *fun,PyObject *args)
{
! PyObject *ret = PyObject_Call(fun,args,NULL);
! if(ret == NULL) {
! // function not found resp. arguments not matching
! PyErr_Print();
! return false;
! }
! else {
! if(!PyObject_Not(ret)) post("pyext - returned value is ignored");
! Py_DECREF(ret);
! return true;
! }
! }
!
! bool pyext::call(const char *meth,int inlet,const t_symbol *s,int argc,const t_atom *argv)
! {
! bool ret = false;
!
! PyObject *pmeth = PyObject_GetAttrString(pyobj,const_cast<char *>(meth)); /* fetch bound method */
if(pmeth == NULL) {
PyErr_Clear(); // no method found
***************
*** 471,555 ****
else {
PyObject *pargs = MakePyArgs(s,argc,argv,inlet?inlet:-1,true);
! if(!pargs)
PyErr_Print();
! else {
! ret = PyEval_CallObject(pmeth, pargs);
! if (ret == NULL) // function not found resp. arguments not matching
! PyErr_Print();
!
! Py_DECREF(pargs);
! }
! Py_DECREF(pmeth);
! }
!
! return ret;
! }
!
! V pyext::work_wrapper(V *data)
! {
! ++thrcount;
! #ifdef FLEXT_DEBUG
! if(!data)
! post("%s - no data!",thisName());
! else
! #endif
! {
! #ifdef FLEXT_THREADS
! // --- make new Python thread ---
! // get the global lock
! PyEval_AcquireLock();
! // create a thread state object for this thread
! PyThreadState *newthr = FindThreadState();
! // free the lock
! PyEval_ReleaseLock();
! #endif
! {
! // call worker
! work_data *w = (work_data *)data;
! work(w->n,w->Header(),w->Count(),w->Atoms());
! delete w;
}
!
! #ifdef FLEXT_THREADS
! // --- delete Python thread ---
! // grab the lock
! PyEval_AcquireLock();
! // swap my thread state out of the interpreter
! PyThreadState_Swap(NULL);
! // delete mapped thread state
! FreeThreadState();
! // release the lock
! PyEval_ReleaseLock();
! // -----------------------------
! #endif
! }
! --thrcount;
! }
!
! BL pyext::callwork(I n,const t_symbol *s,I argc,const t_atom *argv)
! {
! BL ret = true,ok = false;
! if(detach) {
! if(shouldexit)
! post("%s - Stopping.... new threads can't be launched now!",thisName());
! else {
! ret = FLEXT_CALLMETHOD_X(work_wrapper,new work_data(n,s,argc,argv));
! if(!ret) post("%s - Failed to launch thread!",thisName());
! }
}
! else
! ret = ok = work(n,s,argc,argv);
! Respond(ok);
! return ret;
}
! BL pyext::work(I n,const t_symbol *s,I argc,const t_atom *argv)
{
! BL retv = false;
! PY_LOCK
! PyObject *ret = NULL;
! char *str = new char[strlen(GetString(s))+10];
{
--- 491,512 ----
else {
PyObject *pargs = MakePyArgs(s,argc,argv,inlet?inlet:-1,true);
! if(!pargs) {
PyErr_Print();
! Py_DECREF(pmeth);
}
! else
! ret = gencall(pmeth,pargs);
}
! return ret;
}
! bool pyext::work(int n,const t_symbol *s,int argc,const t_atom *argv)
{
! bool ret = false;
! PyThreadState *state = PyLock();
! // should be enough...
! char str[256];
{
***************
*** 564,568 ****
if(s == sym_bang && !argc) {
t_atom argv;
! SetString(argv,"");
ret = call(str,0,s,1,&argv);
}
--- 521,525 ----
if(s == sym_bang && !argc) {
t_atom argv;
! SetSymbol(argv,sym__);
ret = call(str,0,s,1,&argv);
}
***************
*** 577,588 ****
if(!ret) {
// try anything at any inlet
! strcpy(str,"_anything_");
if(s == sym_bang && !argc) {
t_atom argv;
! SetString(argv,"");
! ret = call(str,n,s,1,&argv);
}
else
! ret = call(str,n,s,argc,argv);
}
--- 534,545 ----
if(!ret) {
// try anything at any inlet
! const char *str1 = "_anything_";
if(s == sym_bang && !argc) {
t_atom argv;
! SetSymbol(argv,sym__);
! ret = call(str1,n,s,1,&argv);
}
else
! ret = call(str1,n,s,argc,argv);
}
***************
*** 591,604 ****
post("%s - no matching method found for '%s' into inlet %i",thisName(),GetString(s),n);
! if(str) delete[] str;
!
! if(ret) {
! if(!PyObject_Not(ret)) post("%s - returned value is ignored",thisName());
! Py_DECREF(ret);
! retv = true;
! }
!
! PY_UNLOCK
! return retv;
}
--- 548,554 ----
post("%s - no matching method found for '%s' into inlet %i",thisName(),GetString(s),n);
! PyUnlock(state);
! Respond(ret);
! return ret;
}
Index: py.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/py.cpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -C2 -d -r1.15 -r1.16
*** py.cpp 10 Nov 2004 03:31:34 -0000 1.15
--- py.cpp 9 Jan 2005 04:59:30 -0000 1.16
***************
*** 3,7 ****
py/pyext - python script object for PD and Max/MSP
! Copyright (c)2002-2004 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
--- 3,7 ----
py/pyext - python script object for PD and Max/MSP
! Copyright (c)2002-2005 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
***************
*** 18,55 ****
public:
! pyobj(I argc,const t_atom *argv);
~pyobj();
protected:
! BL m_method_(I n,const t_symbol *s,I argc,const t_atom *argv);
! BL work(const t_symbol *s,I argc,const t_atom *argv);
! V m_bang() { callwork(sym_bang,0,NULL); }
! V m_reload();
! V m_reload_(I argc,const t_atom *argv);
! V m_set(I argc,const t_atom *argv);
! V m_dir_() { m__dir(function); }
! V m_doc_() { m__doc(function); }
! virtual V m_help();
// methods for python arguments
! V callwork(const t_symbol *s,I argc,const t_atom *argv);
! V m_py_list(I argc,const t_atom *argv) { callwork(sym_list,argc,argv); }
! V m_py_float(I argc,const t_atom *argv) { callwork(sym_float,argc,argv); }
! V m_py_int(I argc,const t_atom *argv) { callwork(sym_int,argc,argv); }
! V m_py_any(const t_symbol *s,I argc,const t_atom *argv) { callwork(s,argc,argv); }
const t_symbol *funname;
PyObject *function;
! virtual V Reload();
! V SetFunction(const C *func);
! V ResetFunction();
private:
static void Setup(t_classid c);
--- 18,58 ----
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);
! bool work(const t_symbol *s,int argc,const t_atom *argv);
! void m_bang() { callwork(sym_bang,0,NULL); }
! void m_reload();
! void m_reload_(int argc,const t_atom *argv);
! void m_set(int argc,const t_atom *argv);
! 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_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); }
const t_symbol *funname;
PyObject *function;
! virtual void Reload();
! void SetFunction(const char *func);
! void ResetFunction();
private:
+
+ virtual bool callpy(PyObject *fun,PyObject *args);
+
static void Setup(t_classid c);
***************
*** 99,106 ****
}
! pyobj::pyobj(I argc,const t_atom *argv):
function(NULL),funname(NULL)
{
! PY_LOCK
AddInAnything(2);
--- 102,109 ----
}
! pyobj::pyobj(int argc,const t_atom *argv):
function(NULL),funname(NULL)
{
! PyThreadState *state = PyLock();
AddInAnything(2);
***************
*** 117,121 ****
post("%s - script name argument is invalid",thisName());
else {
! C dir[1024];
GetModulePath(GetString(argv[0]),dir,sizeof(dir));
// set script path
--- 120,124 ----
post("%s - script name argument is invalid",thisName());
else {
! char dir[1024];
GetModulePath(GetString(argv[0]),dir,sizeof(dir));
// set script path
***************
*** 128,137 ****
AddToPath(GetString(canvas_getcurrentdir()));
#elif FLEXT_SYS == FLEXT_SYS_MAX
! #if FLEXT_OS == FLEXT_OS_WIN
! #else
short path = patcher_myvol(thisCanvas());
path_topathname(path,NULL,dir);
AddToPath(dir);
! #endif
#else
#pragma message("Adding current dir to path is not implemented")
--- 131,139 ----
AddToPath(GetString(canvas_getcurrentdir()));
#elif FLEXT_SYS == FLEXT_SYS_MAX
! /*
short path = patcher_myvol(thisCanvas());
path_topathname(path,NULL,dir);
AddToPath(dir);
! */
#else
#pragma message("Adding current dir to path is not implemented")
***************
*** 154,165 ****
}
! PY_UNLOCK
}
pyobj::~pyobj()
{
! PY_LOCK
Unregister("_py");
! PY_UNLOCK
}
--- 156,167 ----
}
! PyUnlock(state);
}
pyobj::~pyobj()
{
! PyThreadState *state = PyLock();
Unregister("_py");
! PyUnlock(state);
}
***************
*** 167,171 ****
! BL pyobj::m_method_(I n,const t_symbol *s,I argc,const t_atom *argv)
{
if(n == 1)
--- 169,173 ----
! bool pyobj::m_method_(int n,const t_symbol *s,int argc,const t_atom *argv)
{
if(n == 1)
***************
*** 174,180 ****
}
! V pyobj::m_reload()
{
! PY_LOCK
Unregister("_py");
--- 176,182 ----
}
! void pyobj::m_reload()
{
! PyThreadState *state = PyLock();
Unregister("_py");
***************
*** 185,205 ****
SetFunction(funname?GetString(funname):NULL);
! PY_UNLOCK
}
! V pyobj::m_reload_(I argc,const t_atom *argv)
{
! PY_LOCK
SetArgs(argc,argv);
! PY_UNLOCK
m_reload();
}
! V pyobj::m_set(I argc,const t_atom *argv)
{
! PY_LOCK
! I ix = 0;
if(argc >= 2) {
if(!IsString(argv[ix])) {
--- 187,207 ----
SetFunction(funname?GetString(funname):NULL);
! PyUnlock(state);
}
! void pyobj::m_reload_(int argc,const t_atom *argv)
{
! PyThreadState *state = PyLock();
SetArgs(argc,argv);
! PyUnlock(state);
m_reload();
}
! void pyobj::m_set(int argc,const t_atom *argv)
{
! PyThreadState *state = PyLock();
! int ix = 0;
if(argc >= 2) {
if(!IsString(argv[ix])) {
***************
*** 207,211 ****
return;
}
! const C *sn = GetString(argv[ix]);
if(!module || !strcmp(sn,PyModule_GetName(module))) {
--- 209,213 ----
return;
}
! const char *sn = GetString(argv[ix]);
if(!module || !strcmp(sn,PyModule_GetName(module))) {
***************
*** 222,232 ****
SetFunction(GetString(argv[ix]));
! PY_UNLOCK
}
! V pyobj::m_help()
{
post("");
! post("%s %s - python script object, (C)2002-2004 Thomas Grill",thisName(),PY__VERSION);
#ifdef FLEXT_DEBUG
post("DEBUG VERSION, compiled on " __DATE__ " " __TIME__);
--- 224,234 ----
SetFunction(GetString(argv[ix]));
! PyUnlock(state);
}
! void pyobj::m_help()
{
post("");
! post("%s %s - python script object, (C)2002-2005 Thomas Grill",thisName(),PY__VERSION);
#ifdef FLEXT_DEBUG
post("DEBUG VERSION, compiled on " __DATE__ " " __TIME__);
***************
*** 249,253 ****
post("\tdir+: dump function dictionary");
#ifdef FLEXT_THREADS
! post("\tdetach 0/1: detach threads");
post("\tstop {wait time (ms)}: stop threads");
#endif
--- 251,255 ----
post("\tdir+: dump function dictionary");
#ifdef FLEXT_THREADS
! post("\tdetach 0/1/2: detach threads");
post("\tstop {wait time (ms)}: stop threads");
#endif
***************
*** 255,259 ****
}
! V pyobj::ResetFunction()
{
if(!module || !dict)
--- 257,261 ----
}
! void pyobj::ResetFunction()
{
if(!module || !dict)
***************
*** 264,268 ****
}
! function = funname?PyDict_GetItemString(dict,(C *)GetString(funname)):NULL; // borrowed!!!
if(!function) {
PyErr_Clear();
--- 266,270 ----
}
! function = funname?PyDict_GetItemString(dict,(char *)GetString(funname)):NULL; // borrowed!!!
if(!function) {
PyErr_Clear();
***************
*** 275,279 ****
}
! V pyobj::SetFunction(const C *func)
{
if(func) {
--- 277,281 ----
}
! void pyobj::SetFunction(const char *func)
{
if(func) {
***************
*** 286,314 ****
! V pyobj::Reload()
{
ResetFunction();
}
!
! BL pyobj::work(const t_symbol *s,I argc,const t_atom *argv)
{
! AtomList *rargs = NULL;
! BL ret;
!
! ++thrcount;
! PY_LOCK
if(function) {
! PyObject *pArgs = MakePyArgs(s,argc,argv);
! PyObject *pValue = PyObject_CallObject(function, pArgs);
!
! rargs = GetPyArgs(pValue);
! if(!rargs) PyErr_Print();
! Py_XDECREF(pArgs);
! Py_XDECREF(pValue);
! ret = true;
! }
else {
post("%s: no function defined",thisName());
--- 288,332 ----
! void pyobj::Reload()
{
ResetFunction();
}
! bool pyobj::callpy(PyObject *fun,PyObject *args)
{
! PyObject *ret = PyObject_Call(fun,args,NULL);
! if(ret == NULL) {
! // function not found resp. arguments not matching
! PyErr_Print();
! return false;
! }
! else {
! AtomList *rargs = GetPyArgs(ret);
! if(!rargs)
! PyErr_Print();
! else {
! // call to outlet _outside_ the Mutex lock!
! // otherwise (if not detached) deadlock will occur
! if(rargs->Count()) ToOutList(0,*rargs);
! delete rargs;
! }
! Py_DECREF(ret);
! return true;
! }
! }
+ void pyobj::callwork(const t_symbol *s,int argc,const t_atom *argv)
+ {
+ bool ret = false;
+
if(function) {
! PyThreadState *state = PyLock();
!
! PyObject *pargs = MakePyArgs(s,argc,argv);
! Py_INCREF(function);
! ret = gencall(function,pargs);
! PyUnlock(state);
! }
else {
post("%s: no function defined",thisName());
***************
*** 316,347 ****
}
- PY_UNLOCK
- --thrcount;
-
- if(rargs) {
- // call to outlet _outside_ the Mutex lock!
- // otherwise (if not detached) deadlock will occur
- if(rargs->Count()) ToOutList(0,*rargs);
- delete rargs;
- }
-
- return ret;
- }
-
- V pyobj::callwork(const t_symbol *s,I argc,const t_atom *argv)
- {
- BL ret = false;
- if(detach) {
- if(shouldexit)
- post("%s - New threads can't be launched now!",thisName());
- else {
- ret = FLEXT_CALLMETHOD_A(work,s,argc,argv);
- if(!ret) post("%s - Failed to launch thread!",thisName());
- }
- }
- else
- ret = work(s,argc,argv);
Respond(ret);
}
-
-
--- 334,337 ----
- Previous message: [PD-cvs] externals/grill/py license.txt,1.2,1.3 package.txt,1.4,1.5 py.vcproj,1.14,1.15 readme.txt,1.24,1.25
- Next message: [PD-cvs] pd/src s_inter.c,1.5.4.5,1.5.4.6
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Pd-cvs
mailing list