diff options
Diffstat (limited to 'externals/grill/py/source/bound.cpp')
-rw-r--r-- | externals/grill/py/source/bound.cpp | 202 |
1 files changed, 0 insertions, 202 deletions
diff --git a/externals/grill/py/source/bound.cpp b/externals/grill/py/source/bound.cpp deleted file mode 100644 index 266bb9c5..00000000 --- a/externals/grill/py/source/bound.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/* -py/pyext - python external object for PD and MaxMSP - -Copyright (c)2002-2008 Thomas Grill (gr@grrrr.org) -For information on usage and redistribution, and for a DISCLAIMER OF ALL -WARRANTIES, see the file, "license.txt," in this distribution. - -$LastChangedRevision: 26 $ -$LastChangedDate: 2008-01-03 17:20:03 +0100 (Thu, 03 Jan 2008) $ -$LastChangedBy: thomas $ -*/ - -#include "pyext.h" -#include "flinternal.h" - -#include <set> - -class MethodCompare: - public std::less<PyObject *> -{ -public: - bool operator()(PyObject *a,PyObject *b) const - { - if(PyMethod_Check(a)) - if(PyMethod_Check(b)) { - // both are methods - PyObject *sa = PyMethod_GET_SELF(a); - PyObject *sb = PyMethod_GET_SELF(b); - if(sa) - if(sb) { - // both have self - if(sa == sb) - return PyMethod_GET_FUNCTION(a) < PyMethod_GET_FUNCTION(b); - else - return sa < sb; - } - else - return false; - else - if(sb) - return true; - else - return PyMethod_GET_FUNCTION(a) < PyMethod_GET_FUNCTION(b); - } - else - return false; - else - if(PyMethod_Check(b)) - return true; - else - // both are non-method callables - return a < b; - } -}; - -typedef std::set<PyObject *,MethodCompare> FuncSet; - -struct bounddata -{ - PyObject *self; - FuncSet funcs; -}; - -bool pyext::boundmeth(flext_base *th,t_symbol *sym,int argc,t_atom *argv,void *data) -{ - bounddata *obj = (bounddata *)data; - pyext *pyth = static_cast<pyext *>(th); - - ThrState state = pyth->PyLock(); - - PyObject *args = MakePyArgs(sym,argc,argv); - - // call all functions bound by this symbol - for(FuncSet::iterator it = obj->funcs.begin(); it != obj->funcs.end(); ++it) { - PyObject *ret = PyObject_CallObject(*it,args); - if(!ret) - PyErr_Print(); - else - Py_DECREF(ret); - } - - Py_XDECREF(args); - - pyth->PyUnlock(state); - return true; -} - -PyObject *pyext::pyext_bind(PyObject *,PyObject *args) -{ - PyObject *self,*meth,*name; - if(!PyArg_ParseTuple(args, "OOO:pyext_bind", &self,&name,&meth)) // borrowed references - post("py/pyext - Wrong arguments!"); - else if(!PyInstance_Check(self) || !PyCallable_Check(meth)) { - post("py/pyext - Wrong argument types!"); - } - else { - pyext *th = GetThis(self); - if(!th) { - PyErr_SetString(PyExc_RuntimeError,"pyext - _bind: instance not associated with pd object"); - return NULL; - } - - const t_symbol *recv = pyObject_AsSymbol(name); - - void *data = NULL; - if(recv && th->GetBoundMethod(recv,boundmeth,data)) { - // already bound to that symbol and function - bounddata *bdt = (bounddata *)data; - FLEXT_ASSERT(bdt != NULL && bdt->self == self); - - FuncSet::iterator it = bdt->funcs.find(meth); - if(it == bdt->funcs.end()) { - bdt->funcs.insert(meth); - Py_INCREF(meth); - } - } - else { - Py_INCREF(self); // self is borrowed reference - Py_INCREF(meth); - - bounddata *data = new bounddata; - data->self = self; - data->funcs.insert(meth); - - th->BindMethod(recv,boundmeth,data); - } - } - - Py_INCREF(Py_None); - return Py_None; -} - -PyObject *pyext::pyext_unbind(PyObject *,PyObject *args) -{ - PyObject *self,*meth,*name; - if(!PyArg_ParseTuple(args, "OOO:pyext_bind", &self,&name,&meth)) // borrowed references - post("py/pyext - Wrong arguments!"); - else if(!PyInstance_Check(self) || !PyCallable_Check(meth)) { - post("py/pyext - Wrong argument types!"); - } - else { - pyext *th = GetThis(self); - if(!th) { - PyErr_SetString(PyExc_RuntimeError,"pyext - _unbind: instance not associated with pd object"); - return NULL; - } - - const t_symbol *recv = pyObject_AsSymbol(name); - - void *data = NULL; - if(recv && th->GetBoundMethod(recv,boundmeth,data)) { - bounddata *bdt = (bounddata *)data; - FLEXT_ASSERT(bdt != NULL); - - // erase from map - // ATTENTION: meth is different from the element found in the map - // it just points to the same instance method - FuncSet::iterator it = bdt->funcs.find(meth); - if(it != bdt->funcs.end()) { - Py_DECREF(*it); - bdt->funcs.erase(it); - } - else - post("py/pyext - Function to unbind couldn't be found"); - - if(bdt->funcs.empty()) { - Py_DECREF(bdt->self); - delete bdt; - - th->UnbindMethod(recv,boundmeth,NULL); - } - } - } - - Py_INCREF(Py_None); - return Py_None; -} - - -void pyext::ClearBinding() -{ - // in case the object couldn't be constructed... - if(!pyobj) return; - - pyext *th = GetThis(pyobj); - if(!th) return; - - void *data = NULL; - const t_symbol *sym = NULL; - - // unbind all - while(th->UnbindMethod(sym,NULL,&data)) { - bounddata *bdt = (bounddata *)data; - if(bdt) { - for(FuncSet::iterator it = bdt->funcs.begin(); it != bdt->funcs.end(); ++it) - Py_DECREF(*it); - - Py_DECREF(bdt->self); - delete bdt; - } - } -} |