diff options
Diffstat (limited to 'externals/grill/py/source/pyargs.cpp')
-rw-r--r-- | externals/grill/py/source/pyargs.cpp | 146 |
1 files changed, 101 insertions, 45 deletions
diff --git a/externals/grill/py/source/pyargs.cpp b/externals/grill/py/source/pyargs.cpp index 5e328975..f08369a7 100644 --- a/externals/grill/py/source/pyargs.cpp +++ b/externals/grill/py/source/pyargs.cpp @@ -8,83 +8,124 @@ WARRANTIES, see the file, "license.txt," in this distribution. */ -#include "main.h" +#include "pybase.h" +#include "pyatom.h" + +static const t_symbol *symatom = flext::MakeSymbol(" py "); static PyObject *MakePyAtom(const t_atom &at) { if(flext::IsSymbol(at)) return pySymbol_FromSymbol(flext::GetSymbol(at)); +/* else if(flext::CanbeInt(at) || flext::CanbeFloat(at)) { - // if a number can be an integer... let at be an integer! + // if a number can be an integer... let it be an integer! int ival = flext::GetAInt(at); double fval = flext::GetAFloat(at); return (double)ival == fval?PyInt_FromLong(ival):PyFloat_FromDouble(fval); } -// else if(flext::IsPointer(at)) return NULL; // not handled -/* - // 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)); -*/ +*/ + else if(flext::IsFloat(at)) + return PyFloat_FromDouble(flext::GetFloat(at)); + else if(flext::IsInt(at)) + return PyInt_FromLong(flext::GetInt(at)); + return NULL; } -PyObject *pybase::MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,int inlet,bool withself) +static PyObject *MakePyAtom(int argc,const t_atom *argv) { - PyObject *pArgs; + if(argc != sizeof(size_t)/2) return NULL; + + size_t atom = 0; + for(int i = sizeof(size_t)/2-1; i >= 0; --i) + if(!flext::CanbeInt(argv[i])) { + atom = 0; + break; + } + else + atom = (atom<<16)+flext::GetAInt(argv[i]); + + if(atom) { + PyObject *el = PyAtom::Retrieve(atom); + if(!el) el = Py_None; // object already gone.... + Py_INCREF(el); + return el; + } + else + return NULL; +} -/* - if(!s && args.Count() == 1) { - pArgs = MakePyAtom(args[0]); - if(!pArgs) - post("py/pyext: cannot convert argument(s)"); +PyObject *pybase::MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,int inlet) +{ + PyObject *ret,*el; + + if(s == symatom && (el = MakePyAtom(argc,argv)) != NULL) { + ret = PyTuple_New(1); + PyTuple_SET_ITEM(ret,0,el); } - else -*/ - { + else { bool any = IsAnything(s); - pArgs = PyTuple_New(argc+(any?1:0)+(inlet >= 0?1:0)); + ret = PyTuple_New(argc+(any?1:0)+(inlet >= 0?1:0)); int pix = 0; if(inlet >= 0) - PyTuple_SetItem(pArgs, pix++, PyInt_FromLong(inlet)); - - int ix; - PyObject *tmp; -// if(!withself || argc < (any?1:2)) - tmp = pArgs,ix = pix; -// else -// tmp = PyTuple_New(argc+(any?1:0)),ix = 0; + PyTuple_SET_ITEM(ret,pix++,PyInt_FromLong(inlet)); if(any) - PyTuple_SET_ITEM(tmp, ix++, pySymbol_FromSymbol(s)); + PyTuple_SET_ITEM(ret,pix++,pySymbol_FromSymbol(s)); for(int i = 0; i < argc; ++i) { - PyObject *pValue = MakePyAtom(argv[i]); - if(!pValue) { + el = MakePyAtom(argv[i]); + if(!el) { post("py/pyext: cannot convert argument %i",any?i+1:i); - continue; - } - - /* pValue reference stolen here: */ - PyTuple_SET_ITEM(tmp, ix++, pValue); + + el = Py_None; + Py_INCREF(Py_None); + } + + PyTuple_SET_ITEM(ret,pix++,el); // reference stolen } + } + + return ret; +} - if(tmp != pArgs) { - PyTuple_SET_ITEM(pArgs, pix++, tmp); - #if PY_VERSION_HEX >= 0x02020000 - _PyTuple_Resize(&pArgs,pix); - #else - _PyTuple_Resize(&pArgs,pix,0); - #endif +PyObject *pybase::MakePyArg(const t_symbol *s,int argc,const t_atom *argv) +{ + PyObject *ret; + + if(s == symatom && (ret = MakePyAtom(argc,argv)) != NULL) { + // ok! + } + else if(argc == 1 && IsAtom(s)) + ret = MakePyAtom(*argv); + else { + bool any = s != sym_list; + ret = PyTuple_New(argc+(any?1:0)); + + int pix = 0; + if(any) + PyTuple_SET_ITEM(ret,pix++,pySymbol_FromSymbol(s)); + + for(int i = 0; i < argc; ++i) { + PyObject *el = MakePyAtom(argv[i]); + if(!el) { + post("py/pyext: cannot convert argument %i",any?i+1:i); + + el = Py_None; + Py_INCREF(Py_None); + } + + PyTuple_SET_ITEM(ret,pix++,el); // reference stolen } } - return pArgs; + return ret; } -bool pybase::GetPyArgs(AtomList &lst,PyObject *pValue,int offs,PyObject **self) +bool pybase::GetPyArgs(AtomList &lst,PyObject *pValue,int offs) { if(pValue == NULL) return false; @@ -124,11 +165,13 @@ bool pybase::GetPyArgs(AtomList &lst,PyObject *pValue,int offs,PyObject **self) else if(PyFloat_Check(arg)) SetFloat(at,(float)PyFloat_AsDouble(arg)); else if(pySymbol_Check(arg)) SetSymbol(at,pySymbol_AS_SYMBOL(arg)); else if(PyString_Check(arg)) SetString(at,PyString_AS_STRING(arg)); - else if(ix == 0 && self && PyInstance_Check(arg)) { +/* + else if(ix == 0 && self && PyInstance_Check(arg)) { // assumed to be self ... that should be checked _somehow_ !!! Py_INCREF(arg); *self = arg; } +*/ else { PyObject *tp = PyObject_Type(arg); PyObject *stp = tp?PyObject_Str(tp):NULL; @@ -146,3 +189,16 @@ bool pybase::GetPyArgs(AtomList &lst,PyObject *pValue,int offs,PyObject **self) return ok; } + + +bool pybase::GetPyAtom(AtomList &lst,PyObject *obj) +{ + size_t atom = PyAtom::Register(obj); + size_t szat = sizeof(atom)/2; + + lst(1+szat); + SetSymbol(lst[0],symatom); + for(size_t i = 0; i < szat; ++i,atom >>= 16) + flext::SetInt(lst[i+1],(int)(atom&((1<<16)-1))); + return true; +} |