From c2645dc4003b1391aba9b387a79a66cff1e63d3e Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Tue, 22 Oct 2002 23:16:30 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r189, which included commits to RCS files with non-trunk default branches. svn path=/trunk/; revision=190 --- externals/grill/py/source/bound.cpp | 143 ++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 externals/grill/py/source/bound.cpp (limited to 'externals/grill/py/source/bound.cpp') diff --git a/externals/grill/py/source/bound.cpp b/externals/grill/py/source/bound.cpp new file mode 100644 index 00000000..651bb52b --- /dev/null +++ b/externals/grill/py/source/bound.cpp @@ -0,0 +1,143 @@ +/* + +py/pyext - python external object for PD and MaxMSP + +Copyright (c) 2002 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. + +*/ + +#include "pyext.h" +#include "flinternal.h" + +t_class *pyext::px_class; +pyext::py_proxy *pyext::px_head,*pyext::px_tail; + +void pyext::py_proxy::px_method(py_proxy *obj,const t_symbol *s,int argc,t_atom *argv) +{ + PY_LOCK + + PyObject *args = MakePyArgs(s,AtomList(argc,argv),-1,obj->self != NULL); + PyObject *ret = PyObject_CallObject(obj->func,args); + if(!ret) { + PyErr_Print(); + } + Py_XDECREF(ret); + + PY_UNLOCK +} + + +PyObject *pyext::pyext_bind(PyObject *,PyObject *args) +{ + PyObject *self,*meth; + C *name; + if(!PyArg_ParseTuple(args, "OsO:pyext_bind", &self,&name,&meth)) + post("py/pyext - Wrong arguments!"); + else if(!PyInstance_Check(self) || !(PyMethod_Check(meth) || PyFunction_Check(meth))) { + post("py/pyext - Wrong argument types!"); + } + else { + t_symbol *recv = gensym(name); +/* + if(GetBound(recv)) + post("py/pyext - Symbol \"%s\" is already hooked",GetString(recv)); +*/ + // make a proxy object + py_proxy *px = (py_proxy *)object_new(px_class); + if(PyMethod_Check(meth)) { + PyObject *no = PyObject_GetAttrString(meth,"__name__"); + meth = PyObject_GetAttr(self,no); + Py_DECREF(no); + } + px->init(recv,self,meth); + + // add it to the list + if(px_tail) px_tail->nxt = px; + else px_head = px; + px_tail = px; + + // Do bind + pd_bind(&px->obj.ob_pd,recv); + + Py_INCREF(self); // self is borrowed reference + } + + Py_INCREF(Py_None); + return Py_None; +} + +PyObject *pyext::pyext_unbind(PyObject *,PyObject *args) +{ + PyObject *self,*meth; + C *name; + if(!PyArg_ParseTuple(args, "OsO:pyext_bind", &self,&name,&meth)) + post("py/pyext - Wrong arguments!"); + else if(!PyInstance_Check(self) || !(PyMethod_Check(meth) || PyFunction_Check(meth))) { + post("py/pyext - Wrong argument types!"); + } + else { + t_symbol *recv = gensym(name); + if(PyMethod_Check(meth)) { + PyObject *no = PyObject_GetAttrString(meth,"__name__"); + meth = PyObject_GetAttr(self,no); // meth is given a new reference! + Py_DECREF(no); + } + + // search proxy object + py_proxy *pp = NULL,*px = px_head; + while(px) { + py_proxy *pn = px->nxt; + if(recv == px->name && self == px->self && meth == px->func) { + if(pp) + pp->nxt = pn; + else + px_head = pn; + if(!pn) px_tail = pp; + break; + } + else pp = px; + px = pn; + } + + // do unbind + if(px) { + pd_unbind(&px->obj.ob_pd,recv); + object_free(px->obj); + + Py_DECREF(self); + if(PyMethod_Check(meth)) Py_DECREF(meth); + } + } + + Py_INCREF(Py_None); + return Py_None; +} + + +V pyext::ClearBinding() +{ + // search proxy object + py_proxy *pp = NULL,*px = px_head; + while(px) { + py_proxy *pn = px->nxt; + if(px->self == pyobj) { + if(pp) + pp->nxt = pn; + else + px_head = pn; + if(!pn) px_tail = pp; + + Py_DECREF(px->self); + if(PyMethod_Check(px->func)) Py_DECREF(px->func); + + pd_unbind(&px->obj.ob_pd,px->name); + object_free(px->obj); + } + else pp = px; + px = pn; + } +} + + -- cgit v1.2.1