diff options
Diffstat (limited to 'externals/grill/py/source/bound.cpp')
-rw-r--r-- | externals/grill/py/source/bound.cpp | 151 |
1 files changed, 47 insertions, 104 deletions
diff --git a/externals/grill/py/source/bound.cpp b/externals/grill/py/source/bound.cpp index e8e2599f..c0e8c35a 100644 --- a/externals/grill/py/source/bound.cpp +++ b/externals/grill/py/source/bound.cpp @@ -11,44 +11,32 @@ WARRANTIES, see the file, "license.txt," in this distribution. #include "pyext.h" #include "flinternal.h" -#ifndef USEFLEXTBINDING -t_class *pyext::px_class; -pyext::py_proxy *pyext::px_head,*pyext::px_tail; +struct bounddata +{ + PyObject *self; + std::set<PyObject *> funcs; +}; -void pyext::py_proxy::px_method(py_proxy *obj,const t_symbol *s,int argc,const 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 -} - -#else -struct bounddata { PyObject *self,*func; }; - -bool pyext::boundmeth(flext_base *,const t_symbol *sym,int argc,const t_atom *argv,void *data) +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,AtomList(argc,argv),-1,obj->self != NULL); - PyObject *ret = PyObject_CallObject(obj->func,args); - if(!ret) { - PyErr_Print(); - } - Py_XDECREF(ret); + + // call all functions bound by this symbol + for(std::set<PyObject *>::iterator it = obj->funcs.begin(); it != obj->funcs.end(); ++it) { + PyObject *ret = PyObject_CallObject(*it,args); + if(!ret) { + PyErr_Print(); + } + Py_XDECREF(ret); + } PY_UNLOCK return true; } -#endif PyObject *pyext::pyext_bind(PyObject *,PyObject *args) { @@ -72,25 +60,22 @@ PyObject *pyext::pyext_bind(PyObject *,PyObject *args) meth = PyObject_GetAttr(self,no); Py_DECREF(no); } -#ifndef USEFLEXTBINDING - py_proxy *px = (py_proxy *)object_new(px_class); - 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,(t_symbol *)recv); -#else - bounddata *data = new bounddata; - data->self = self; - data->func = meth; - GetThis(self)->BindMethod(recv,boundmeth,data); -#endif - - Py_INCREF(self); // self is borrowed reference + + void *data = NULL; + if(GetThis(self)->GetBoundMethod(recv,boundmeth,data)) { + // already bound to that symbol and function + bounddata *bdt = (bounddata *)data; + FLEXT_ASSERT(bdt != NULL && bdt->self == self); + bdt->funcs.insert(meth); + } + else { + bounddata *data = new bounddata; + data->self = self; + data->funcs.insert(meth); + GetThis(self)->BindMethod(recv,boundmeth,data); + + Py_INCREF(self); // self is borrowed reference + } } Py_INCREF(Py_None); @@ -114,42 +99,21 @@ PyObject *pyext::pyext_unbind(PyObject *,PyObject *args) Py_DECREF(no); } -#ifndef USEFLEXTBINDING - // 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,(t_symbol *)recv); - object_free(&px->obj); - - Py_DECREF(self); - if(PyMethod_Check(meth)) Py_DECREF(meth); - } -#else void *data = NULL; if(GetThis(self)->UnbindMethod(recv,boundmeth,&data)) { - bounddata *bdt = (bounddata *)data; - if(bdt) { - Py_DECREF(bdt->self); - if(PyMethod_Check(bdt->func)) Py_DECREF(bdt->func); - if(data) delete bdt; + bounddata *bdt = (bounddata *)data; + FLEXT_ASSERT(bdt != NULL); + + if(PyMethod_Check(meth)) Py_DECREF(meth); + + // erase from map + bdt->funcs.erase(meth); + + if(bdt->funcs.empty()) { + Py_DECREF(bdt->self); + delete bdt; } } -#endif } Py_INCREF(Py_None); @@ -159,28 +123,6 @@ PyObject *pyext::pyext_unbind(PyObject *,PyObject *args) V pyext::ClearBinding() { -#ifndef USEFLEXTBINDING - // 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,(t_symbol *)px->name); - object_free(&px->obj); - } - else pp = px; - px = pn; - } -#else void *data = NULL; const t_symbol *sym = NULL; @@ -188,12 +130,13 @@ V pyext::ClearBinding() while(GetThis(pyobj)->UnbindMethod(sym,NULL,&data)) { bounddata *bdt = (bounddata *)data; if(bdt) { + for(std::set<PyObject *>::iterator it = bdt->funcs.begin(); it != bdt->funcs.end(); ++it) { + PyObject *func = *it; + if(PyMethod_Check(func)) Py_DECREF(func); + } + Py_DECREF(bdt->self); - if(PyMethod_Check(bdt->func)) Py_DECREF(bdt->func); if(data) delete bdt; } } -#endif } - - |