aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/py
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2004-01-22 03:38:37 +0000
committerThomas Grill <xovo@users.sourceforge.net>2004-01-22 03:38:37 +0000
commitc970a0b61182435de534f39b32e8f29f5ef7b42f (patch)
tree96a819d9661a7cda1b55ecad0ca479002661336d /externals/grill/py
parentf9b7710c9bf2b7d6574fb4c358b1c7ff8837719d (diff)
""
svn path=/trunk/; revision=1285
Diffstat (limited to 'externals/grill/py')
-rw-r--r--externals/grill/py/source/clmeth.cpp14
-rw-r--r--externals/grill/py/source/main.h5
-rw-r--r--externals/grill/py/source/modmeth.cpp6
-rw-r--r--externals/grill/py/source/py.cpp32
-rw-r--r--externals/grill/py/source/pyext.cpp105
5 files changed, 95 insertions, 67 deletions
diff --git a/externals/grill/py/source/clmeth.cpp b/externals/grill/py/source/clmeth.cpp
index 0c28563a..0f4ad23e 100644
--- a/externals/grill/py/source/clmeth.cpp
+++ b/externals/grill/py/source/clmeth.cpp
@@ -1,8 +1,8 @@
/*
-py/pyext - python external object for PD and MaxMSP
+py/pyext - python external object for PD and Max/MSP
-Copyright (c) 2002-2003 Thomas Grill (xovo@gmx.net)
+Copyright (c) 2002-2004 Thomas Grill (xovo@gmx.net)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
@@ -40,16 +40,20 @@ PyMethodDef pyext::attr_tbl[] =
const C *pyext::pyext_doc =
- "py/pyext - python external object for PD and MaxMSP, (C)2002 Thomas Grill\n"
+ "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"
"_outlet(self,ix,args...): Send a message to an indexed outlet\n"
+#if FLEXT_SYS == FLEXT_SYS_PD
"_tocanvas(self,args...): Send a message to the parent canvas\n"
-#ifdef FLEXT_THREADS
- "_detach(self,int): Define whether a called Python method has its own thread\n"
#endif
"_bind(self,name,func): Bind a python function to a symbol\n"
"_unbind(self,name,func): Unbind a python function from a symbol\n"
+#ifdef FLEXT_THREADS
+ "_detach(self,int): Define whether a called Python method has its own thread\n"
+ "_stop(self): Stop running threads\n"
+#endif
+ "_isthreaded(self): Query whether threading is enabled\n"
;
PyObject* pyext::pyext__init__(PyObject *,PyObject *args)
diff --git a/externals/grill/py/source/main.h b/externals/grill/py/source/main.h
index b1894571..612c1c45 100644
--- a/externals/grill/py/source/main.h
+++ b/externals/grill/py/source/main.h
@@ -90,6 +90,8 @@ protected:
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*/ };
@@ -114,7 +116,7 @@ protected:
virtual V m_stop(int argc,const t_atom *argv);
- BL detach,shouldexit;
+ BL detach,shouldexit,respond;
I thrcount;
I stoptick;
Timer stoptmr;
@@ -138,6 +140,7 @@ protected:
// callbacks
FLEXT_ATTRVAR_B(detach)
+ FLEXT_ATTRVAR_B(respond)
FLEXT_CALLBACK_V(m_stop)
FLEXT_CALLBACK(m_dir)
FLEXT_CALLGET_V(mg_dir)
diff --git a/externals/grill/py/source/modmeth.cpp b/externals/grill/py/source/modmeth.cpp
index b376a4fb..f7dae309 100644
--- a/externals/grill/py/source/modmeth.cpp
+++ b/externals/grill/py/source/modmeth.cpp
@@ -1,8 +1,8 @@
/*
-py/pyext - python external object for PD and MaxMSP
+py/pyext - python external object for PD and Max/MSP
-Copyright (c) 2002-2003 Thomas Grill (xovo@gmx.net)
+Copyright (c) 2002-2004 Thomas Grill (xovo@gmx.net)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
@@ -28,7 +28,7 @@ PyMethodDef py::func_tbl[] =
};
const C *py::py_doc =
- "py/pyext - python external object for PD and MaxMSP, (C)2002 Thomas Grill\n"
+ "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"
"_send(args...): Send a message to a send symbol\n"
diff --git a/externals/grill/py/source/py.cpp b/externals/grill/py/source/py.cpp
index bfc32678..e9e7040d 100644
--- a/externals/grill/py/source/py.cpp
+++ b/externals/grill/py/source/py.cpp
@@ -1,8 +1,8 @@
/*
-py/pyext - python script object for PD and MaxMSP
+py/pyext - python script object for PD and Max/MSP
-Copyright (c) 2002-2003 Thomas Grill (xovo@gmx.net)
+Copyright (c) 2002-2004 Thomas Grill (xovo@gmx.net)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
@@ -23,9 +23,9 @@ public:
protected:
BL m_method_(I n,const t_symbol *s,I argc,const t_atom *argv);
- V work(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() { work(sym_bang,0,NULL); }
+ 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);
@@ -94,6 +94,8 @@ void pyobj::Setup(t_classid c)
FLEXT_CADDMETHOD_(c,1,"int",m_py_int);
FLEXT_CADDMETHOD(c,1,m_py_list);
FLEXT_CADDMETHOD(c,1,m_py_any);
+
+ FLEXT_CADDATTR_VAR1(c,"respond",respond);
}
pyobj::pyobj(I argc,const t_atom *argv):
@@ -227,6 +229,8 @@ V pyobj::m_help()
post("\treload. : reload with former arguments");
post("\tdoc: display module doc string");
post("\tdoc+: display function doc string");
+ post("\tdir: dump module dictionary");
+ post("\tdir+: dump function dictionary");
#ifdef FLEXT_THREADS
post("\tdetach 0/1: detach threads");
post("\tstop {wait time (ms)}: stop threads");
@@ -271,9 +275,10 @@ V pyobj::Reload()
}
-V pyobj::work(const t_symbol *s,I argc,const t_atom *argv)
+BL pyobj::work(const t_symbol *s,I argc,const t_atom *argv)
{
AtomList *rargs = NULL;
+ BL ret;
++thrcount;
PY_LOCK
@@ -287,9 +292,11 @@ V pyobj::work(const t_symbol *s,I argc,const t_atom *argv)
Py_XDECREF(pArgs);
Py_XDECREF(pValue);
+ ret = true;
}
else {
post("%s: no function defined",thisName());
+ ret = false;
}
PY_UNLOCK
@@ -301,19 +308,24 @@ V pyobj::work(const t_symbol *s,I argc,const t_atom *argv)
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
- if(!FLEXT_CALLMETHOD_A(work,s,argc,argv))
- post("%s - Failed to launch thread!",thisName());
+ else {
+ ret = FLEXT_CALLMETHOD_A(work,s,argc,argv);
+ if(!ret) post("%s - Failed to launch thread!",thisName());
+ }
}
- else
- work(s,argc,argv);
+ else
+ ret = work(s,argc,argv);
+ Respond(ret);
}
diff --git a/externals/grill/py/source/pyext.cpp b/externals/grill/py/source/pyext.cpp
index 924a6fec..7dd4d805 100644
--- a/externals/grill/py/source/pyext.cpp
+++ b/externals/grill/py/source/pyext.cpp
@@ -1,6 +1,6 @@
/*
-py/pyext - python script object for PD and MaxMSP
+py/pyext - python script object for PD and Max/MSP
Copyright (c)2002-2004 Thomas Grill (xovo@gmx.net)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
@@ -32,6 +32,8 @@ V pyext::Setup(t_classid c)
FLEXT_CADDMETHOD_(c,0,"get",m_get);
FLEXT_CADDMETHOD_(c,0,"set",m_set);
+
+ FLEXT_CADDATTR_VAR1(c,"respond",respond);
}
pyext *pyext::GetThis(PyObject *self)
@@ -224,7 +226,6 @@ pyext::~pyext()
Unregister("_pyext");
Py_XDECREF(pyobj);
-
Py_XDECREF(class_obj);
Py_XDECREF(class_dict);
@@ -244,39 +245,45 @@ BL pyext::SetClssMeth() //I argc,t_atom *argv)
PyObject *pref = PyObject_GetAttrString(module,const_cast<C *>(GetString(methname)));
if(!pref)
PyErr_Print();
- else if(PyClass_Check(pref)) {
- // make instance, but don't call __init__
- pyobj = PyInstance_NewRaw(pref,NULL);
+ else {
+ if(PyClass_Check(pref)) {
+ // make instance, but don't call __init__
+ pyobj = PyInstance_NewRaw(pref,NULL);
+
+ Py_DECREF(pref);
+ if(pyobj == NULL)
+ PyErr_Print();
+ else {
+ // remember the this pointer
+ PyObject *th = PyLong_FromVoidPtr(this);
+ int ret = PyObject_SetAttrString(pyobj,"_this",th); // ref is taken
+
+ // call init now, after _this has been set, which is
+ // important for eventual callbacks from __init__ to c
+ PyObject *pargs = MakePyArgs(NULL,args,-1,true);
+ if (pargs == NULL) PyErr_Print();
+
+ PyObject *init;
+ init = PyObject_GetAttrString(pyobj,"__init__"); // get ref
+ if(init) {
+ if(PyCallable_Check(init)) {
+ PyObject *res = PyEval_CallObject(init,pargs);
+ if(!res)
+ PyErr_Print();
+ else
+ Py_DECREF(res);
+ }
+ Py_DECREF(init);
+ }
+
+ Py_XDECREF(pargs);
+ }
+ }
+ else
+ post("%s - Type of \"%s\" is unhandled!",thisName(),GetString(methname));
- Py_DECREF(pref);
- if(pyobj == NULL)
- PyErr_Print();
- else {
- // remember the this pointer
- PyObject *th = PyLong_FromVoidPtr(this);
- int ret = PyObject_SetAttrString(pyobj,"_this",th); // ref is taken
-
- // call init now, after _this has been set, which is
- // important for eventual callbacks from __init__ to c
- PyObject *pargs = MakePyArgs(NULL,args,-1,true);
- if (pargs == NULL) PyErr_Print();
-
- PyObject *init;
- init = PyObject_GetAttrString(pyobj,"__init__"); // get ref
- if(init && PyCallable_Check(init)) {
- PyObject *res = PyEval_CallObject(init,pargs);
- if(!res)
- PyErr_Print();
- else
- Py_DECREF(res);
- Py_DECREF(init);
- }
-
- Py_XDECREF(pargs);
- }
+ Py_DECREF(pref);
}
- else
- post("%s - Type of \"%s\" is unhandled!",thisName(),GetString(methname));
return true;
}
else
@@ -287,6 +294,7 @@ V pyext::Reload()
{
ClearBinding();
Py_XDECREF(pyobj);
+
// by here, the Python class destructor should have been called!
SetArgs(0,NULL);
@@ -321,7 +329,7 @@ void pyext::m_get(const t_symbol *s)
PY_LOCK
PyObject *pvar = PyObject_GetAttrString(pyobj,const_cast<char *>(GetString(s))); /* fetch bound method */
- if(pvar == NULL) {
+ if(!pvar) {
PyErr_Clear(); // no method found
post("%s - get: Python variable %s not found",thisName(),GetString(s));
}
@@ -384,13 +392,12 @@ void pyext::m_set(int argc,const t_atom *argv)
BL pyext::m_method_(I n,const t_symbol *s,I argc,const t_atom *argv)
{
- if(pyobj && n >= 1) {
- return callwork(n,s,argc,argv);
- }
- else {
+ 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);
- return false;
- }
+ return ret;
}
@@ -413,6 +420,8 @@ V pyext::m_help()
post("\treload. : reload with former arguments");
post("\tdoc: display module doc string");
post("\tdoc+: display class doc string");
+ post("\tdir: dump module dictionary");
+ post("\tdir+: dump class dictionary");
#ifdef FLEXT_THREADS
post("\tdetach 0/1: detach threads");
post("\tstop {wait time (ms)}: stop threads");
@@ -502,19 +511,19 @@ V pyext::work_wrapper(V *data)
BL pyext::callwork(I n,const t_symbol *s,I argc,const t_atom *argv)
{
- if(detach) {
- if(shouldexit) {
+ BL ret = true,ok = false;
+ if(detach) {
+ if(shouldexit)
post("%s - Stopping.... new threads can't be launched now!",thisName());
- return true;
- }
else {
- BL ret = FLEXT_CALLMETHOD_X(work_wrapper,new work_data(n,s,argc,argv));
+ ret = FLEXT_CALLMETHOD_X(work_wrapper,new work_data(n,s,argc,argv));
if(!ret) post("%s - Failed to launch thread!",thisName());
- return true;
}
}
- else
- return work(n,s,argc,argv);
+ 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)