Update of /cvsroot/pure-data/externals/grill/py/source
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18937/source
Modified Files:
bound.cpp clmeth.cpp modmeth.cpp py.cpp pyatom.cpp pyatom.h
pybase.cpp pybase.h pybundle.cpp pybundle.h pydsp.cpp
pyext.cpp pyext.h pymeth.cpp pyprefix.h pysymbol.cpp
pysymbol.h
Log Message:
multiply inlets for py (hot and cold inlets)
small optimizations and fixes
use PyGILState_\*() functionality (enabled with PY_USE_GIL)
updates for DSP processing
__str__ method for pyext, to enable print self calls
added message bundle functionality (pyext.Bundle class)
enable compiled-only scripts (without .py)
enable optimization of Python code in reease build
let _inlets and _outlets default to 0
fix for numpy
some ASSERTs for explicitly created pyext classes (should be runtime checks i guess)
open editor for script under OS X
fixing numpy initialization quirks
enable symbol binding for all callables (not only functions and methods)
_isthreaded is now a data member instead of a method
fix for gcc4
added pyext._list and pyext._tuple to convert input lists to Python sequence objects
enable module packages (module/__init__.py[co]), now also for Max
python-like dotted module.function syntax
cleaned up float vs. int pyext tags
compiler flag to exclude DSP objects
some optimizations and py reload fix
more safety for calls where association python-pd has already been removed
always run Python interpreter in the background
Index: clmeth.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/clmeth.cpp,v
retrieving revision 1.27
retrieving revision 1.28
diff -C2 -d -r1.27 -r1.28
*** clmeth.cpp 12 Dec 2005 00:18:42 -0000 1.27
--- clmeth.cpp 7 Mar 2007 13:40:14 -0000 1.28
***************
*** 3,7 ****
py/pyext - python external object for PD and Max/MSP
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
--- 3,7 ----
py/pyext - python external object for PD and Max/MSP
! Copyright (c)2002-2007 Thomas Grill (gr(a)grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
***************
*** 44,48 ****
const char *pyext::pyext_doc =
! "py/pyext - python external object for PD and Max/MSP, (C)2002-2005 Thomas Grill\n"
"\n"
"This is the pyext base class. Available methods:\n"
--- 44,48 ----
const char *pyext::pyext_doc =
! "py/pyext - python external object for PD and Max/MSP, (C)2002-2007 Thomas Grill\n"
"\n"
"This is the pyext base class. Available methods:\n"
Index: pyprefix.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pyprefix.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** pyprefix.h 1 Aug 2005 11:58:01 -0000 1.5
--- pyprefix.h 7 Mar 2007 13:40:14 -0000 1.6
***************
*** 1,43 ****
! /*
!
! py/pyext - python script object for PD and MaxMSP
!
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
! #ifndef __PYPREFIX_H
! #define __PYPREFIX_H
!
! #define FLEXT_ATTRIBUTES 1
! #include <flext.h>
!
! // hack: must include math.h before Python.h (at least on OSX)
! // otherwise some functions don't get defined
! #include <math.h>
!
! #if FLEXT_OS == FLEXT_OS_MAC
! #include <Python/Python.h>
! #else
! #include <Python.h>
! #endif
!
! #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 501)
! #error You need at least flext version 0.5.1
! #endif
!
! #if FLEXT_OS == FLEXT_LINUX || FLEXT_OS == FLEXT_IRIX
! #include <unistd.h>
! #endif
!
! #if FLEXT_SYS == FLEXT_SYS_PD && (!defined (PD_MINOR_VERSION) || PD_MINOR_VERSION < 37)
! #error PD version >= 0.37 required, please upgrade!
! #endif
!
! #include <flcontainers.h>
! #include <string>
!
!
! #endif
--- 1,43 ----
! /*
!
! py/pyext - python script object for PD and MaxMSP
!
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
! #ifndef __PYPREFIX_H
! #define __PYPREFIX_H
!
! #define FLEXT_ATTRIBUTES 1
! #include <flext.h>
!
! // hack: must include math.h before Python.h (at least on OSX)
! // otherwise some functions don't get defined
! #include <math.h>
!
! #if FLEXT_OS == FLEXT_OS_MAC
! #include <Python/Python.h>
! #else
! #include <Python.h>
! #endif
!
! #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 501)
! #error You need at least flext version 0.5.1
! #endif
!
! #if FLEXT_OS == FLEXT_LINUX || FLEXT_OS == FLEXT_IRIX
! #include <unistd.h>
! #endif
!
! #if FLEXT_SYS == FLEXT_SYS_PD && (!defined (PD_MINOR_VERSION) || PD_MINOR_VERSION < 37)
! #error PD version >= 0.37 required, please upgrade!
! #endif
!
! #include <flcontainers.h>
! #include <string>
!
!
! #endif
Index: pyext.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pyext.h,v
retrieving revision 1.30
retrieving revision 1.31
diff -C2 -d -r1.30 -r1.31
*** pyext.h 12 Dec 2005 00:18:42 -0000 1.30
--- pyext.h 7 Mar 2007 13:40:14 -0000 1.31
***************
*** 115,119 ****
static bool stcallpy(PyObject *fun,PyObject *args);
! PyThreadState *pythr;
private:
--- 115,121 ----
static bool stcallpy(PyObject *fun,PyObject *args);
! #ifndef PY_USE_GIL
! ThrState pythr;
! #endif
private:
Index: modmeth.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/modmeth.cpp,v
retrieving revision 1.23
retrieving revision 1.24
diff -C2 -d -r1.23 -r1.24
*** modmeth.cpp 3 Aug 2006 16:33:37 -0000 1.23
--- modmeth.cpp 7 Mar 2007 13:40:14 -0000 1.24
***************
*** 3,7 ****
py/pyext - python external object for PD and Max/MSP
! Copyright (c)2002-2006 Thomas Grill (gr(a)grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
--- 3,7 ----
py/pyext - python external object for PD and Max/MSP
! Copyright (c)2002-2007 Thomas Grill (gr(a)grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
***************
*** 36,40 ****
const char *pybase::py_doc =
! "py/pyext - python external object for PD and Max/MSP, (C)2002-2006 Thomas Grill\n"
"\n"
"This is the pyext module. Available function:\n"
--- 36,40 ----
const char *pybase::py_doc =
! "py/pyext - python external object for PD and Max/MSP, (C)2002-2007 Thomas Grill\n"
"\n"
"This is the pyext module. Available function:\n"
Index: bound.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/bound.cpp,v
retrieving revision 1.18
retrieving revision 1.19
diff -C2 -d -r1.18 -r1.19
*** bound.cpp 21 Sep 2005 10:52:33 -0000 1.18
--- bound.cpp 7 Mar 2007 13:40:14 -0000 1.19
***************
*** 65,69 ****
pyext *pyth = static_cast<pyext *>(th);
! PyThreadState *state = pyth->PyLock();
PyObject *args = MakePyArgs(sym,argc,argv);
--- 65,69 ----
pyext *pyth = static_cast<pyext *>(th);
! ThrState state = pyth->PyLock();
PyObject *args = MakePyArgs(sym,argc,argv);
Index: pyext.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pyext.cpp,v
retrieving revision 1.46
retrieving revision 1.47
diff -C2 -d -r1.46 -r1.47
*** pyext.cpp 23 Mar 2006 01:42:05 -0000 1.46
--- pyext.cpp 7 Mar 2007 13:40:14 -0000 1.47
***************
*** 118,123 ****
pyobj(NULL),
inlets(-1),outlets(-1),
! siginlets(0),sigoutlets(0),
! pythr(NULL)
{
#ifdef FLEXT_THREADS
--- 118,125 ----
pyobj(NULL),
inlets(-1),outlets(-1),
! siginlets(0),sigoutlets(0)
! #ifndef PY_USE_GIL
! ,pythr(NULL)
! #endif
{
#ifdef FLEXT_THREADS
***************
*** 142,146 ****
bool dotted = strrchr(thisName(),'.') != NULL;
! PyThreadState *state = PyLockSys();
// init script module
--- 144,148 ----
bool dotted = strrchr(thisName(),'.') != NULL;
! ThrState state = PyLockSys();
// init script module
***************
*** 195,199 ****
bool pyext::Init()
{
! PyThreadState *state = PyLockSys();
if(methname) {
--- 197,201 ----
bool pyext::Init()
{
! ThrState state = PyLockSys();
if(methname) {
***************
*** 222,226 ****
pybase::Exit(); // exit threads
! PyThreadState *state = PyLockSys();
DoExit();
--- 224,228 ----
pybase::Exit(); // exit threads
! ThrState state = PyLockSys();
DoExit();
***************
*** 415,419 ****
void pyext::m_get(const t_symbol *s)
{
! PyThreadState *state = PyLockSys();
PyObject *pvar = PyObject_GetAttrString(pyobj,const_cast<char *>(GetString(s))); /* fetch bound method */
--- 417,421 ----
void pyext::m_get(const t_symbol *s)
{
! ThrState state = PyLockSys();
PyObject *pvar = PyObject_GetAttrString(pyobj,const_cast<char *>(GetString(s))); /* fetch bound method */
***************
*** 438,442 ****
void pyext::m_set(int argc,const t_atom *argv)
{
! PyThreadState *state = PyLockSys();
if(argc < 2 || !IsString(argv[0]))
--- 440,444 ----
void pyext::m_set(int argc,const t_atom *argv)
{
! ThrState state = PyLockSys();
if(argc < 2 || !IsString(argv[0]))
***************
*** 543,547 ****
bool ret = false;
! PyThreadState *state = PyLock();
// should be enough...
--- 545,549 ----
bool ret = false;
! ThrState state = PyLock();
// should be enough...
Index: pyatom.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pyatom.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** pyatom.h 8 Jul 2005 14:30:31 -0000 1.1
--- pyatom.h 7 Mar 2007 13:40:14 -0000 1.2
***************
*** 1,19 ****
! /*
!
! py/pyext - python script object for PD and Max/MSP
!
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
! #include "main.h"
!
! class PyAtom
! {
! public:
! static size_t Register(PyObject *obj);
! static PyObject *Retrieve(size_t id);
! static void Collect();
! };
--- 1,19 ----
! /*
!
! py/pyext - python script object for PD and Max/MSP
!
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
! #include "main.h"
!
! class PyAtom
! {
! public:
! static size_t Register(PyObject *obj);
! static PyObject *Retrieve(size_t id);
! static void Collect();
! };
Index: pyatom.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pyatom.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** pyatom.cpp 8 Jul 2005 14:30:31 -0000 1.1
--- pyatom.cpp 7 Mar 2007 13:40:14 -0000 1.2
***************
*** 1,61 ****
! /*
!
! py/pyext - python script object for PD and Max/MSP
!
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
! #include "pyatom.h"
! #include <map>
!
! #define INTV 0.01
!
! typedef std::map<size_t,PyObject *> ObjMap;
!
! static ObjMap objmap;
! static size_t collix = 0,curix = 0;
! static double last = 0;
!
! size_t PyAtom::Register(PyObject *obj)
! {
! Collect();
!
! Py_INCREF(obj);
! objmap[++curix] = obj;
!
! #ifdef _DEBUG
! // post("REG %p (%i)\n",obj,objmap.size());
! #endif
! return curix;
! }
!
! PyObject *PyAtom::Retrieve(size_t id)
! {
! ObjMap::iterator it = objmap.find(id);
! PyObject *ret = it == objmap.end()?NULL:it->second;
! Collect();
! return ret;
! }
!
! void PyAtom::Collect()
! {
! for(;;) {
! ObjMap::iterator it = objmap.begin();
! if(it == objmap.end() || it->first > collix) break;
!
! PyObject *obj = it->second;
! Py_DECREF(obj);
! objmap.erase(it);
!
! #ifdef _DEBUG
! // post("DEL %p\n",obj);
! #endif
! }
!
! // schedule next collect time
! double tm = flext::GetTime();
! if(tm > last+INTV) last = tm,collix = curix;
! }
--- 1,61 ----
! /*
!
! py/pyext - python script object for PD and Max/MSP
!
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
! #include "pyatom.h"
! #include <map>
!
! #define INTV 0.01
!
! typedef std::map<size_t,PyObject *> ObjMap;
!
! static ObjMap objmap;
! static size_t collix = 0,curix = 0;
! static double last = 0;
!
! size_t PyAtom::Register(PyObject *obj)
! {
! Collect();
!
! Py_INCREF(obj);
! objmap[++curix] = obj;
!
! #ifdef _DEBUG
! // post("REG %p (%i)\n",obj,objmap.size());
! #endif
! return curix;
! }
!
! PyObject *PyAtom::Retrieve(size_t id)
! {
! ObjMap::iterator it = objmap.find(id);
! PyObject *ret = it == objmap.end()?NULL:it->second;
! Collect();
! return ret;
! }
!
! void PyAtom::Collect()
! {
! for(;;) {
! ObjMap::iterator it = objmap.begin();
! if(it == objmap.end() || it->first > collix) break;
!
! PyObject *obj = it->second;
! Py_DECREF(obj);
! objmap.erase(it);
!
! #ifdef _DEBUG
! // post("DEL %p\n",obj);
! #endif
! }
!
! // schedule next collect time
! double tm = flext::GetTime();
! if(tm > last+INTV) last = tm,collix = curix;
! }
Index: pybundle.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pybundle.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** pybundle.h 12 Dec 2005 13:55:28 -0000 1.1
--- pybundle.h 7 Mar 2007 13:40:14 -0000 1.2
***************
*** 1,15 ****
! /*
!
! py/pyext - python script object for PD and Max/MSP
!
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
! #ifndef __PYBUNDLE_H
! #define __PYBUNDLE_H
!
#include <flext.h>
--- 1,15 ----
! /*
!
! py/pyext - python script object for PD and Max/MSP
!
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
! #ifndef __PYBUNDLE_H
! #define __PYBUNDLE_H
!
#include <flext.h>
***************
*** 34,60 ****
#define PY_EXPORT
#endif
!
! typedef struct {
! PyObject_HEAD
! /* Type-specific fields go here. */
! flext::MsgBundle *bundle;
! } pyBundle;
!
! PY_EXPORT extern PyTypeObject pyBundle_Type;
!
#define pyBundle_Check(op) PyObject_TypeCheck(op, &pyBundle_Type)
#define pyBundle_CheckExact(op) ((op)->ob_type == &pyBundle_Type)
! inline flext::MsgBundle *pyBundle_AS_BUNDLE(PyObject *op)
! {
! return ((pyBundle *)op)->bundle;
! }
!
! inline flext::MsgBundle *pyBundle_AsBundle(PyObject *op)
! {
! return pyBundle_Check(op)?pyBundle_AS_BUNDLE(op):NULL;
! }
!
! #endif
--- 34,60 ----
#define PY_EXPORT
#endif
!
! typedef struct {
! PyObject_HEAD
! /* Type-specific fields go here. */
! flext::MsgBundle *bundle;
! } pyBundle;
!
! PY_EXPORT extern PyTypeObject pyBundle_Type;
!
#define pyBundle_Check(op) PyObject_TypeCheck(op, &pyBundle_Type)
#define pyBundle_CheckExact(op) ((op)->ob_type == &pyBundle_Type)
! inline flext::MsgBundle *pyBundle_AS_BUNDLE(PyObject *op)
! {
! return ((pyBundle *)op)->bundle;
! }
! inline flext::MsgBundle *pyBundle_AsBundle(PyObject *op)
! {
! return pyBundle_Check(op)?pyBundle_AS_BUNDLE(op):NULL;
! }
!
!
! #endif
Index: pysymbol.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pysymbol.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** pysymbol.cpp 20 Jan 2007 14:27:22 -0000 1.6
--- pysymbol.cpp 7 Mar 2007 13:40:14 -0000 1.7
***************
*** 1,254 ****
! /*
!
! py/pyext - python script object for PD and Max/MSP
!
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
! #include "pyprefix.h"
! #include "pysymbol.h"
!
! inline pySymbol *symbol_newsym(const t_symbol *sym)
! {
! pySymbol *self = (pySymbol *)pySymbol_Type.tp_alloc(&pySymbol_Type, 0);
! if(self) self->sym = sym;
! return self;
! }
!
! static PyObject *symbol_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
! {
! return (PyObject *)symbol_newsym(flext::sym__);
! }
!
! static int symbol_init(PyObject *self, PyObject *args, PyObject *kwds)
! {
! FLEXT_ASSERT(pySymbol_Check(self));
!
! PyObject *arg = PySequence_GetItem(args,0); // new reference
! if(!arg) return -1;
!
! int ret = 0;
!
! if(pySymbol_Check(arg))
! ((pySymbol *)self)->sym = pySymbol_AS_SYMBOL(arg);
! else if(PyString_Check(arg))
! ((pySymbol *)self)->sym = flext::MakeSymbol(PyString_AS_STRING(arg));
! else {
! PyErr_SetString(PyExc_TypeError,"string or symbol argument expected");
! ret = -1;
! }
! Py_DECREF(arg);
!
! return ret;
! }
!
! static PyObject *symbol_str(PyObject *self)
! {
! FLEXT_ASSERT(pySymbol_Check(self));
! return (PyObject *)PyString_FromString(pySymbol_AS_STRING(self));
! }
!
! static PyObject *symbol_repr(PyObject *self)
! {
! FLEXT_ASSERT(pySymbol_Check(self));
! return (PyObject *)PyString_FromFormat("<Symbol %s>",pySymbol_AS_STRING(self));
! }
!
! static PyObject *symbol_richcompare(PyObject *a,PyObject *b,int cmp)
! {
! if(pySymbol_Check(a) && pySymbol_Check(b)) {
! const t_symbol *asym = pySymbol_AS_SYMBOL(a);
! const t_symbol *bsym = pySymbol_AS_SYMBOL(b);
! bool ret;
! switch(cmp) {
! case Py_LT: ret = asym < bsym; break;
! case Py_LE: ret = asym <= bsym; break;
! case Py_EQ: ret = asym == bsym; break;
! case Py_NE: ret = asym != bsym; break;
! case Py_GT: ret = asym > bsym; break;
! case Py_GE: ret = asym >= bsym; break;
! }
! return PyBool_FromLong(ret);
! }
! Py_INCREF(Py_NotImplemented);
! return Py_NotImplemented;
! }
!
! static long symbol_hash(PyObject *self)
! {
! FLEXT_ASSERT(pySymbol_Check(self));
! return (long)pySymbol_AS_SYMBOL(self);
! }
!
!
! static int symbol_length(pySymbol *self)
! {
! return strlen(flext::GetString(self->sym));
! }
!
! static PyObject *symbol_item(pySymbol *self, int i)
! {
! const char *str = flext::GetString(self->sym);
! int len = strlen(str);
! if(i < 0) i += len;
!
! if(i >= 0 && i < len)
! return PyString_FromStringAndSize(str+i,1);
! else {
! Py_INCREF(Py_None);
! return Py_None;
! }
! }
!
! static PyObject *symbol_slice(pySymbol *self,int ilow = 0,int ihigh = 1<<(sizeof(int)*8-2))
! {
! const char *str = flext::GetString(self->sym);
! int len = strlen(str);
! if(ilow < 0) {
! ilow += len;
! if(ilow < 0) ilow = 0;
! }
! if(ihigh < 0) ihigh += len;
! if(ihigh >= len) ihigh = len-1;
!
! return PyString_FromStringAndSize(str+ilow,ilow <= ihigh?ihigh-ilow+1:0);
! }
!
! static PyObject *symbol_concat(pySymbol *self,PyObject *op)
! {
! PyObject *nobj = symbol_slice(self); // take all
! if(nobj) {
! PyObject *ret = PySequence_Concat(nobj,op);
! Py_DECREF(nobj);
! return ret;
! }
! else
! return NULL;
! }
!
! static PyObject *symbol_repeat(pySymbol *self,int rep)
! {
! PyObject *nobj = symbol_slice(self); // take all
! if(nobj) {
! PyObject *ret = PySequence_Repeat(nobj,rep);
! Py_DECREF(nobj);
! return ret;
! }
! else
! return NULL;
! }
!
! static PySequenceMethods symbol_as_seq = {
! (inquiry)symbol_length, /* inquiry sq_length; __len__ */
! (binaryfunc)symbol_concat, /* __add__ */
! (intargfunc)symbol_repeat, /* __mul__ */
! (intargfunc)symbol_item, /* intargfunc sq_item; __getitem__ */
! (intintargfunc)symbol_slice, /* intintargfunc sq_slice; __getslice__ */
! NULL, /* intobjargproc sq_ass_item; __setitem__ */
! NULL, /* intintobjargproc sq_ass_slice; __setslice__ */
! };
!
! static PyObject *symbol_iter(PyObject *obj)
! {
! pySymbol *self = (pySymbol *)obj;
! PyObject *nobj = symbol_slice(self);
! if(nobj) {
! PyObject *it = PyObject_GetIter(nobj);
! Py_DECREF(nobj);
! return it;
! }
! else
! return NULL;
! }
!
!
!
! PyTypeObject pySymbol_Type = {
! PyObject_HEAD_INIT(NULL)
! 0, /*ob_size*/
! "Symbol", /*tp_name*/
! sizeof(pySymbol), /*tp_basicsize*/
! 0, /*tp_itemsize*/
! 0, /*tp_dealloc*/
! 0, /*tp_print*/
! 0, /*tp_getattr*/
! 0, /*tp_setattr*/
! 0, /*tp_compare*/
! symbol_repr, /*tp_repr*/
! 0, /*tp_as_number*/
! &symbol_as_seq, /*tp_as_sequence*/
! 0, /*tp_as_mapping*/
! symbol_hash, /*tp_hash */
! 0, /*tp_call*/
! symbol_str, /*tp_str*/
! 0, /*tp_getattro*/
! 0, /*tp_setattro*/
! 0, /*tp_as_buffer*/
! Py_TPFLAGS_DEFAULT /*| Py_TPFLAGS_BASETYPE*/, /*tp_flags*/
! "Symbol objects", /* tp_doc */
! 0, /* tp_traverse */
! 0, /* tp_clear */
! symbol_richcompare, /* tp_richcompare */
! 0, /* tp_weaklistoffset */
! symbol_iter, /* tp_iter */
! 0, /* tp_iternext */
! 0, /* tp_methods */
! 0, /* tp_members */
! 0, /* tp_getset */
! 0, /* tp_base */
! 0, /* tp_dict */
! 0, /* tp_descr_get */
! 0, /* tp_descr_set */
! 0, /* tp_dictoffset */
! symbol_init, /* tp_init */
! 0, /* tp_alloc */
! symbol_new, /* tp_new */
! };
!
! pySymbol *pySymbol__;
! pySymbol *pySymbol_bang;
! pySymbol *pySymbol_list;
! pySymbol *pySymbol_symbol;
! pySymbol *pySymbol_float;
! pySymbol *pySymbol_int;
!
!
! void initsymbol()
! {
! if(PyType_Ready(&pySymbol_Type) < 0)
! return;
!
! Py_INCREF(&pySymbol_Type);
!
! // initialize predefined objects
! pySymbol__ = symbol_newsym(flext::sym__);
! pySymbol_bang = symbol_newsym(flext::sym_bang);
! pySymbol_list = symbol_newsym(flext::sym_list);
! pySymbol_symbol = symbol_newsym(flext::sym_symbol);
! pySymbol_float = symbol_newsym(flext::sym_float);
! pySymbol_int = symbol_newsym(flext::sym_int);
! }
!
!
! PyObject *pySymbol_FromSymbol(const t_symbol *sym)
! {
! pySymbol *op;
! if(sym == flext::sym__)
! Py_INCREF(op = pySymbol__);
! else if(sym == flext::sym_bang)
! Py_INCREF(op = pySymbol_bang);
! else if(sym == flext::sym_list)
! Py_INCREF(op = pySymbol_list);
! else if(sym == flext::sym_symbol)
! Py_INCREF(op = pySymbol_symbol);
! else if(sym == flext::sym_float)
! Py_INCREF(op = pySymbol_float);
! else if(sym == flext::sym_int)
! Py_INCREF(op = pySymbol_int);
! else
! op = symbol_newsym(sym);
! return (PyObject *)op;
! }
--- 1,254 ----
! /*
!
! py/pyext - python script object for PD and Max/MSP
!
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
! #include "pyprefix.h"
! #include "pysymbol.h"
!
! inline pySymbol *symbol_newsym(const t_symbol *sym)
! {
! pySymbol *self = (pySymbol *)pySymbol_Type.tp_alloc(&pySymbol_Type, 0);
! if(self) self->sym = sym;
! return self;
! }
!
! static PyObject *symbol_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
! {
! return (PyObject *)symbol_newsym(flext::sym__);
! }
!
! static int symbol_init(PyObject *self, PyObject *args, PyObject *kwds)
! {
! FLEXT_ASSERT(pySymbol_Check(self));
!
! PyObject *arg = PySequence_GetItem(args,0); // new reference
! if(!arg) return -1;
!
! int ret = 0;
!
! if(pySymbol_Check(arg))
! ((pySymbol *)self)->sym = pySymbol_AS_SYMBOL(arg);
! else if(PyString_Check(arg))
! ((pySymbol *)self)->sym = flext::MakeSymbol(PyString_AS_STRING(arg));
! else {
! PyErr_SetString(PyExc_TypeError,"string or symbol argument expected");
! ret = -1;
! }
! Py_DECREF(arg);
!
! return ret;
! }
!
! static PyObject *symbol_str(PyObject *self)
! {
! FLEXT_ASSERT(pySymbol_Check(self));
! return (PyObject *)PyString_FromString(pySymbol_AS_STRING(self));
! }
!
! static PyObject *symbol_repr(PyObject *self)
! {
! FLEXT_ASSERT(pySymbol_Check(self));
! return (PyObject *)PyString_FromFormat("<Symbol %s>",pySymbol_AS_STRING(self));
! }
!
! static PyObject *symbol_richcompare(PyObject *a,PyObject *b,int cmp)
! {
! if(pySymbol_Check(a) && pySymbol_Check(b)) {
! const t_symbol *asym = pySymbol_AS_SYMBOL(a);
! const t_symbol *bsym = pySymbol_AS_SYMBOL(b);
! bool ret;
! switch(cmp) {
! case Py_LT: ret = asym < bsym; break;
! case Py_LE: ret = asym <= bsym; break;
! case Py_EQ: ret = asym == bsym; break;
! case Py_NE: ret = asym != bsym; break;
! case Py_GT: ret = asym > bsym; break;
! case Py_GE: ret = asym >= bsym; break;
! }
! return PyBool_FromLong(ret);
! }
! Py_INCREF(Py_NotImplemented);
! return Py_NotImplemented;
! }
!
! static long symbol_hash(PyObject *self)
! {
! FLEXT_ASSERT(pySymbol_Check(self));
! return (long)pySymbol_AS_SYMBOL(self);
! }
!
!
! static int symbol_length(pySymbol *self)
! {
! return strlen(flext::GetString(self->sym));
! }
!
! static PyObject *symbol_item(pySymbol *self, int i)
! {
! const char *str = flext::GetString(self->sym);
! int len = strlen(str);
! if(i < 0) i += len;
!
! if(i >= 0 && i < len)
! return PyString_FromStringAndSize(str+i,1);
! else {
! Py_INCREF(Py_None);
! return Py_None;
! }
! }
!
! static PyObject *symbol_slice(pySymbol *self,int ilow = 0,int ihigh = 1<<(sizeof(int)*8-2))
! {
! const char *str = flext::GetString(self->sym);
! int len = strlen(str);
! if(ilow < 0) {
! ilow += len;
! if(ilow < 0) ilow = 0;
! }
! if(ihigh < 0) ihigh += len;
! if(ihigh >= len) ihigh = len-1;
!
! return PyString_FromStringAndSize(str+ilow,ilow <= ihigh?ihigh-ilow+1:0);
! }
!
! static PyObject *symbol_concat(pySymbol *self,PyObject *op)
! {
! PyObject *nobj = symbol_slice(self); // take all
! if(nobj) {
! PyObject *ret = PySequence_Concat(nobj,op);
! Py_DECREF(nobj);
! return ret;
! }
! else
! return NULL;
! }
!
! static PyObject *symbol_repeat(pySymbol *self,int rep)
! {
! PyObject *nobj = symbol_slice(self); // take all
! if(nobj) {
! PyObject *ret = PySequence_Repeat(nobj,rep);
! Py_DECREF(nobj);
! return ret;
! }
! else
! return NULL;
! }
!
! static PySequenceMethods symbol_as_seq = {
! (inquiry)symbol_length, /* inquiry sq_length; __len__ */
! (binaryfunc)symbol_concat, /* __add__ */
! (intargfunc)symbol_repeat, /* __mul__ */
! (intargfunc)symbol_item, /* intargfunc sq_item; __getitem__ */
! (intintargfunc)symbol_slice, /* intintargfunc sq_slice; __getslice__ */
! NULL, /* intobjargproc sq_ass_item; __setitem__ */
! NULL, /* intintobjargproc sq_ass_slice; __setslice__ */
! };
!
! static PyObject *symbol_iter(PyObject *obj)
! {
! pySymbol *self = (pySymbol *)obj;
! PyObject *nobj = symbol_slice(self);
! if(nobj) {
! PyObject *it = PyObject_GetIter(nobj);
! Py_DECREF(nobj);
! return it;
! }
! else
! return NULL;
! }
!
!
!
! PyTypeObject pySymbol_Type = {
! PyObject_HEAD_INIT(NULL)
! 0, /*ob_size*/
! "Symbol", /*tp_name*/
! sizeof(pySymbol), /*tp_basicsize*/
! 0, /*tp_itemsize*/
! 0, /*tp_dealloc*/
! 0, /*tp_print*/
! 0, /*tp_getattr*/
! 0, /*tp_setattr*/
! 0, /*tp_compare*/
! symbol_repr, /*tp_repr*/
! 0, /*tp_as_number*/
! &symbol_as_seq, /*tp_as_sequence*/
! 0, /*tp_as_mapping*/
! symbol_hash, /*tp_hash */
! 0, /*tp_call*/
! symbol_str, /*tp_str*/
! 0, /*tp_getattro*/
! 0, /*tp_setattro*/
! 0, /*tp_as_buffer*/
! Py_TPFLAGS_DEFAULT /*| Py_TPFLAGS_BASETYPE*/, /*tp_flags*/
! "Symbol objects", /* tp_doc */
! 0, /* tp_traverse */
! 0, /* tp_clear */
! symbol_richcompare, /* tp_richcompare */
! 0, /* tp_weaklistoffset */
! symbol_iter, /* tp_iter */
! 0, /* tp_iternext */
! 0, /* tp_methods */
! 0, /* tp_members */
! 0, /* tp_getset */
! 0, /* tp_base */
! 0, /* tp_dict */
! 0, /* tp_descr_get */
! 0, /* tp_descr_set */
! 0, /* tp_dictoffset */
! symbol_init, /* tp_init */
! 0, /* tp_alloc */
! symbol_new, /* tp_new */
! };
!
! pySymbol *pySymbol__;
! pySymbol *pySymbol_bang;
! pySymbol *pySymbol_list;
! pySymbol *pySymbol_symbol;
! pySymbol *pySymbol_float;
! pySymbol *pySymbol_int;
!
!
! void initsymbol()
! {
! if(PyType_Ready(&pySymbol_Type) < 0)
! return;
!
! Py_INCREF(&pySymbol_Type);
!
! // initialize predefined objects
! pySymbol__ = symbol_newsym(flext::sym__);
! pySymbol_bang = symbol_newsym(flext::sym_bang);
! pySymbol_list = symbol_newsym(flext::sym_list);
! pySymbol_symbol = symbol_newsym(flext::sym_symbol);
! pySymbol_float = symbol_newsym(flext::sym_float);
! pySymbol_int = symbol_newsym(flext::sym_int);
! }
!
!
! PyObject *pySymbol_FromSymbol(const t_symbol *sym)
! {
! pySymbol *op;
! if(sym == flext::sym__)
! Py_INCREF(op = pySymbol__);
! else if(sym == flext::sym_bang)
! Py_INCREF(op = pySymbol_bang);
! else if(sym == flext::sym_list)
! Py_INCREF(op = pySymbol_list);
! else if(sym == flext::sym_symbol)
! Py_INCREF(op = pySymbol_symbol);
! else if(sym == flext::sym_float)
! Py_INCREF(op = pySymbol_float);
! else if(sym == flext::sym_int)
! Py_INCREF(op = pySymbol_int);
! else
! op = symbol_newsym(sym);
! return (PyObject *)op;
! }
Index: pydsp.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pydsp.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** pydsp.cpp 20 Sep 2005 20:50:40 -0000 1.6
--- pydsp.cpp 7 Mar 2007 13:40:14 -0000 1.7
***************
*** 1,190 ****
! /*
!
! py/pyext - python script object for PD and Max/MSP
!
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
! #ifndef PY_NODSP
!
! #include "pyext.h"
!
! class pydsp
! : public pyext
! {
! FLEXT_HEADER(pydsp,pyext)
! public:
! pydsp(int argc,const t_atom *argv);
!
! protected:
! virtual bool CbDsp();
! virtual void CbSignal();
!
! virtual bool DoInit();
! virtual void DoExit();
!
! virtual PyObject *GetSig(int ix,bool in);
!
! void NewBuffers();
! void FreeBuffers();
!
! PyObject *dspfun,*sigfun;
! PyObject **buffers;
! };
!
! FLEXT_LIB_DSP_V("pyext~ pyext.~ pyx~ pyx.~",pydsp)
!
! pydsp::pydsp(int argc,const t_atom *argv)
! : pyext(argc,argv,true)
! , dspfun(NULL),sigfun(NULL)
! {}
!
! bool pydsp::DoInit()
! {
! if(!pyext::DoInit()) return false;
!
! if(pyobj)
! {
! dspfun = PyObject_GetAttrString(pyobj,"_dsp"); // get ref
! if(!dspfun)
! PyErr_Clear();
! else if(!PyMethod_Check(dspfun)) {
! Py_DECREF(dspfun);
! dspfun = NULL;
! }
! }
! return true;
! }
!
! void pydsp::DoExit()
! {
! if(dspfun) { Py_DECREF(dspfun); dspfun = NULL; }
! if(sigfun) { Py_DECREF(sigfun); sigfun = NULL; }
!
! FreeBuffers();
! }
!
! PyObject *arrayfrombuffer(PyObject *buf,int c,int n);
!
! void pydsp::NewBuffers()
! {
! int i,n = Blocksize();
! const int ins = CntInSig(),outs = CntOutSig();
! t_sample *const *insigs = InSig();
! t_sample *const *outsigs = OutSig();
!
! // inlet/outlet count can't change so we don't have to deallocate
! if(!buffers) {
! int cnt = ins+outs;
! buffers = new PyObject *[cnt];
! memset(buffers,0,cnt*sizeof(*buffers));
! }
!
! for(i = 0; i < ins; ++i) {
! Py_XDECREF(buffers[i]);
! PyObject *b = PyBuffer_FromReadWriteMemory(insigs[i],n*sizeof(t_sample));
! buffers[i] = arrayfrombuffer(b,1,n);
! Py_DECREF(b);
! }
! for(i = 0; i < outs; ++i) {
! Py_XDECREF(buffers[ins+i]);
! if(i < ins && outsigs[i] == insigs[i]) {
! // same vectors - share the objects!
! buffers[ins+i] = buffers[i];
! Py_XINCREF(buffers[i]);
! }
! else {
! PyObject *b = PyBuffer_FromReadWriteMemory(outsigs[i],n*sizeof(t_sample));
! buffers[ins+i] = arrayfrombuffer(b,1,n);
! Py_DECREF(b);
! }
! }
! }
!
! void pydsp::FreeBuffers()
! {
! if(buffers) {
! int cnt = CntInSig()+CntOutSig();
! for(int i = 0; i < cnt; ++i) Py_XDECREF(buffers[i]);
! delete[] buffers;
! buffers = NULL;
! }
! }
!
! bool pydsp::CbDsp()
! {
! if(pyobj && (CntInSig() || CntOutSig()))
! {
! PyThreadState *state = PyLockSys();
!
! NewBuffers();
!
! bool dodsp = true;
! if(dspfun) {
! PyObject *ret = PyObject_CallObject(dspfun,NULL);
! if(ret) {
! dodsp = PyObject_IsTrue(ret) != 0;
! Py_DECREF(ret);
! }
! else {
! #ifdef FLEXT_DEBUG
! PyErr_Print();
! #else
! PyErr_Clear();
! #endif
! }
! }
!
! // do that here instead of where dspfun is initialized, so that
! // _signal can be assigned in _dsp
! // optimizations may be done there to assign the right _signal version
! Py_XDECREF(sigfun);
!
! if(dodsp) {
! sigfun = PyObject_GetAttrString(pyobj,"_signal"); // get ref
! if(!sigfun)
! PyErr_Clear();
! else if(!PyMethod_Check(sigfun)) {
! Py_DECREF(sigfun);
! sigfun = NULL;
! }
! }
! else
! sigfun = NULL;
!
! PyUnlock(state);
! return sigfun != NULL;
! }
! else
! // switch on dsp only if there are signal inlets or outlets
! return false;
! }
!
! void pydsp::CbSignal()
! {
! PyThreadState *state = PyLockSys();
! PyObject *ret = PyObject_CallObject(sigfun,NULL);
!
! if(ret)
! Py_DECREF(ret);
! else {
! #ifdef FLEXT_DEBUG
! PyErr_Print();
! #else
! PyErr_Clear();
! #endif
! }
! PyUnlock(state);
! }
!
! PyObject *pydsp::GetSig(int ix,bool in)
! {
! PyObject *r = buffers[in?ix:CntInSig()+ix];
! Py_XINCREF(r);
! return r;
! }
!
! #endif
--- 1,190 ----
! /*
!
! py/pyext - python script object for PD and Max/MSP
!
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
! #ifndef PY_NODSP
!
! #include "pyext.h"
!
! class pydsp
! : public pyext
! {
! FLEXT_HEADER(pydsp,pyext)
! public:
! pydsp(int argc,const t_atom *argv);
!
! protected:
! virtual bool CbDsp();
! virtual void CbSignal();
!
! virtual bool DoInit();
! virtual void DoExit();
!
! virtual PyObject *GetSig(int ix,bool in);
!
! void NewBuffers();
! void FreeBuffers();
!
! PyObject *dspfun,*sigfun;
! PyObject **buffers;
! };
!
! FLEXT_LIB_DSP_V("pyext~ pyext.~ pyx~ pyx.~",pydsp)
!
! pydsp::pydsp(int argc,const t_atom *argv)
! : pyext(argc,argv,true)
! , dspfun(NULL),sigfun(NULL)
! {}
!
! bool pydsp::DoInit()
! {
! if(!pyext::DoInit()) return false;
!
! if(pyobj)
! {
! dspfun = PyObject_GetAttrString(pyobj,"_dsp"); // get ref
! if(!dspfun)
! PyErr_Clear();
! else if(!PyMethod_Check(dspfun)) {
! Py_DECREF(dspfun);
! dspfun = NULL;
! }
! }
! return true;
! }
!
! void pydsp::DoExit()
! {
! if(dspfun) { Py_DECREF(dspfun); dspfun = NULL; }
! if(sigfun) { Py_DECREF(sigfun); sigfun = NULL; }
!
! FreeBuffers();
! }
!
! PyObject *arrayfrombuffer(PyObject *buf,int c,int n);
!
! void pydsp::NewBuffers()
! {
! int i,n = Blocksize();
! const int ins = CntInSig(),outs = CntOutSig();
! t_sample *const *insigs = InSig();
! t_sample *const *outsigs = OutSig();
!
! // inlet/outlet count can't change so we don't have to deallocate
! if(!buffers) {
! int cnt = ins+outs;
! buffers = new PyObject *[cnt];
! memset(buffers,0,cnt*sizeof(*buffers));
! }
!
! for(i = 0; i < ins; ++i) {
! Py_XDECREF(buffers[i]);
! PyObject *b = PyBuffer_FromReadWriteMemory(insigs[i],n*sizeof(t_sample));
! buffers[i] = arrayfrombuffer(b,1,n);
! Py_DECREF(b);
! }
! for(i = 0; i < outs; ++i) {
! Py_XDECREF(buffers[ins+i]);
! if(i < ins && outsigs[i] == insigs[i]) {
! // same vectors - share the objects!
! buffers[ins+i] = buffers[i];
! Py_XINCREF(buffers[i]);
! }
! else {
! PyObject *b = PyBuffer_FromReadWriteMemory(outsigs[i],n*sizeof(t_sample));
! buffers[ins+i] = arrayfrombuffer(b,1,n);
! Py_DECREF(b);
! }
! }
! }
!
! void pydsp::FreeBuffers()
! {
! if(buffers) {
! int cnt = CntInSig()+CntOutSig();
! for(int i = 0; i < cnt; ++i) Py_XDECREF(buffers[i]);
! delete[] buffers;
! buffers = NULL;
! }
! }
!
! bool pydsp::CbDsp()
! {
! if(pyobj && (CntInSig() || CntOutSig()))
! {
! ThrState state = PyLockSys();
!
! NewBuffers();
!
! bool dodsp = true;
! if(dspfun) {
! PyObject *ret = PyObject_CallObject(dspfun,NULL);
! if(ret) {
! dodsp = PyObject_IsTrue(ret) != 0;
! Py_DECREF(ret);
! }
! else {
! #ifdef FLEXT_DEBUG
! PyErr_Print();
! #else
! PyErr_Clear();
! #endif
! }
! }
!
! // do that here instead of where dspfun is initialized, so that
! // _signal can be assigned in _dsp
! // optimizations may be done there to assign the right _signal version
! Py_XDECREF(sigfun);
!
! if(dodsp) {
! sigfun = PyObject_GetAttrString(pyobj,"_signal"); // get ref
! if(!sigfun)
! PyErr_Clear();
! else if(!PyMethod_Check(sigfun)) {
! Py_DECREF(sigfun);
! sigfun = NULL;
! }
! }
! else
! sigfun = NULL;
!
! PyUnlock(state);
! return sigfun != NULL;
! }
! else
! // switch on dsp only if there are signal inlets or outlets
! return false;
! }
!
! void pydsp::CbSignal()
! {
! ThrState state = PyLockSys();
! PyObject *ret = PyObject_CallObject(sigfun,NULL);
!
! if(ret)
! Py_DECREF(ret);
! else {
! #ifdef FLEXT_DEBUG
! PyErr_Print();
! #else
! PyErr_Clear();
! #endif
! }
! PyUnlock(state);
! }
!
! PyObject *pydsp::GetSig(int ix,bool in)
! {
! PyObject *r = buffers[in?ix:CntInSig()+ix];
! Py_XINCREF(r);
! return r;
! }
!
! #endif
Index: pymeth.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pymeth.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** pymeth.cpp 11 Aug 2005 15:00:58 -0000 1.6
--- pymeth.cpp 7 Mar 2007 13:40:14 -0000 1.7
***************
*** 1,428 ****
! /*
!
! py/pyext - python script object for PD and Max/MSP
!
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
! #include "pybase.h"
! #include <map>
!
! struct xlt { const t_symbol *from,*to; };
!
! static const xlt xtdefs[] = {
! { flext::MakeSymbol("+"),flext::MakeSymbol("__add__") },
! { flext::MakeSymbol("+="),flext::MakeSymbol("__iadd__") },
! { flext::MakeSymbol("!+"),flext::MakeSymbol("__radd__") },
! { flext::MakeSymbol("-"),flext::MakeSymbol("__sub__") },
! { flext::MakeSymbol("-="),flext::MakeSymbol("__isub__") },
! { flext::MakeSymbol("!-"),flext::MakeSymbol("__rsub__") },
! { flext::MakeSymbol("*"),flext::MakeSymbol("__mul__") },
! { flext::MakeSymbol("*="),flext::MakeSymbol("__imul__") },
! { flext::MakeSymbol("!*"),flext::MakeSymbol("__rmul__") },
! { flext::MakeSymbol("/"),flext::MakeSymbol("__div__") },
! { flext::MakeSymbol("/="),flext::MakeSymbol("__idiv__") },
! { flext::MakeSymbol("!/"),flext::MakeSymbol("__rdiv__") },
! { flext::MakeSymbol("//"),flext::MakeSymbol("__floordiv__") },
! { flext::MakeSymbol("//="),flext::MakeSymbol("__ifloordiv__") },
! { flext::MakeSymbol("!//"),flext::MakeSymbol("__rfloordiv__") },
! { flext::MakeSymbol("%"),flext::MakeSymbol("__mod__") },
! { flext::MakeSymbol("%="),flext::MakeSymbol("__imod__") },
! { flext::MakeSymbol("!%"),flext::MakeSymbol("__rmod__") },
! { flext::MakeSymbol("**"),flext::MakeSymbol("__pow__") },
! { flext::MakeSymbol("**="),flext::MakeSymbol("__ipow__") },
! { flext::MakeSymbol("!**"),flext::MakeSymbol("__rpow__") },
! { flext::MakeSymbol("&"),flext::MakeSymbol("__and__") },
! { flext::MakeSymbol("&="),flext::MakeSymbol("__iand__") },
! { flext::MakeSymbol("!&"),flext::MakeSymbol("__rand__") },
! { flext::MakeSymbol("|"),flext::MakeSymbol("__or__") },
! { flext::MakeSymbol("|="),flext::MakeSymbol("__ior__") },
! { flext::MakeSymbol("!|"),flext::MakeSymbol("__ror__") },
! { flext::MakeSymbol("^"),flext::MakeSymbol("__xor__") },
! { flext::MakeSymbol("^="),flext::MakeSymbol("__ixor__") },
! { flext::MakeSymbol("!^"),flext::MakeSymbol("__rxor__") },
! { flext::MakeSymbol("<<"),flext::MakeSymbol("__lshift__") },
! { flext::MakeSymbol("<<="),flext::MakeSymbol("__ilshift__") },
! { flext::MakeSymbol("!<<"),flext::MakeSymbol("__rlshift__") },
! { flext::MakeSymbol(">>"),flext::MakeSymbol("__rshift__") },
! { flext::MakeSymbol(">>="),flext::MakeSymbol("__irshift__") },
! { flext::MakeSymbol("!>>"),flext::MakeSymbol("__rrshift__") },
! { flext::MakeSymbol("=="),flext::MakeSymbol("__eq__") },
! { flext::MakeSymbol("!="),flext::MakeSymbol("__ne__") },
! { flext::MakeSymbol("<"),flext::MakeSymbol("__lt__") },
! { flext::MakeSymbol(">"),flext::MakeSymbol("__gt__") },
! { flext::MakeSymbol("<="),flext::MakeSymbol("__le__") },
! { flext::MakeSymbol(">="),flext::MakeSymbol("__ge__") },
! { flext::MakeSymbol("!"),flext::MakeSymbol("__nonzero__") },
! { flext::MakeSymbol("~"),flext::MakeSymbol("__invert__") },
! { flext::MakeSymbol("[]"),flext::MakeSymbol("__getitem__") },
! { flext::MakeSymbol("[]="),flext::MakeSymbol("__setitem__") },
! { flext::MakeSymbol("[:]"),flext::MakeSymbol("__getslice__") },
! { flext::MakeSymbol("[:]="),flext::MakeSymbol("__setslice__") },
!
! { flext::MakeSymbol(".abs"),flext::MakeSymbol("__abs__") },
! { flext::MakeSymbol(".neg"),flext::MakeSymbol("__neg__") },
! { flext::MakeSymbol(".pos"),flext::MakeSymbol("__pos__") },
! { flext::MakeSymbol(".divmod"),flext::MakeSymbol("__divmod__") },
!
! { flext::MakeSymbol(".int"),flext::MakeSymbol("__int__") },
! { flext::MakeSymbol(".long"),flext::MakeSymbol("__long__") },
! { flext::MakeSymbol(".float"),flext::MakeSymbol("__float__") },
! { flext::MakeSymbol(".complex"),flext::MakeSymbol("__complex__") },
! { flext::MakeSymbol(".str"),flext::MakeSymbol("__str__") },
! { flext::MakeSymbol(".coerce"),flext::MakeSymbol("__coerce__") },
!
! { flext::MakeSymbol(".doc"),flext::MakeSymbol("__doc__") },
! { flext::MakeSymbol(".repr"),flext::MakeSymbol("__repr__") },
!
! { flext::MakeSymbol(".len"),flext::MakeSymbol("__len__") },
! { flext::MakeSymbol(".in"),flext::MakeSymbol("__contains") },
!
! { NULL,NULL } // sentinel
! };
!
! typedef std::map<const t_symbol *,const t_symbol *> XTable;
! static XTable xtable;
!
!
! class pymeth
! : public pybase
! , public flext_base
! {
! FLEXT_HEADER_S(pymeth,flext_base,Setup)
!
! public:
! pymeth(int argc,const t_atom *argv);
! ~pymeth();
!
! protected:
! virtual void Exit();
!
! virtual bool CbMethodResort(int n,const t_symbol *s,int argc,const t_atom *argv);
!
! void m_help();
!
! void m_reload() { Reload(); }
! void m_reload_(int argc,const t_atom *argv) { args(argc,argv); Reload(); }
! void m_set(int argc,const t_atom *argv);
! void m_dir_() { m__dir(function); }
! void m_doc_() { m__doc(function); }
!
! const t_symbol *funname;
! PyObject *function;
!
! virtual void LoadModule();
! virtual void UnloadModule();
!
! virtual void Load();
! virtual void Unload();
!
! void SetFunction(const t_symbol *func);
! void ResetFunction();
!
! virtual void DumpOut(const t_symbol *sym,int argc,const t_atom *argv);
!
! PyObject **objects;
!
! private:
!
! virtual void callpy(PyObject *fun,PyObject *args);
!
! static void Setup(t_classid c);
!
! FLEXT_CALLBACK(m_help)
! FLEXT_CALLBACK(m_reload)
! FLEXT_CALLBACK_V(m_reload_)
! FLEXT_CALLBACK_V(m_set)
! FLEXT_CALLBACK(m_dir_)
! FLEXT_CALLBACK(m_doc_)
!
! // callbacks
! FLEXT_ATTRVAR_I(detach)
! FLEXT_ATTRVAR_B(pymsg)
! FLEXT_ATTRVAR_B(respond)
!
! FLEXT_CALLBACK_V(m_stop)
! FLEXT_CALLBACK(m_dir)
! FLEXT_CALLGET_V(mg_dir)
! FLEXT_CALLBACK(m_doc)
!
! #ifdef FLEXT_THREADS
! FLEXT_CALLBACK_T(tick)
! #endif
! };
!
! FLEXT_LIB_V("pym",pymeth)
!
!
! void pymeth::Setup(t_classid c)
! {
! FLEXT_CADDMETHOD_(c,0,"doc",m_doc);
! FLEXT_CADDMETHOD_(c,0,"dir",m_dir);
! #ifdef FLEXT_THREADS
! FLEXT_CADDATTR_VAR1(c,"detach",detach);
! FLEXT_CADDMETHOD_(c,0,"stop",m_stop);
! #endif
!
! FLEXT_CADDMETHOD_(c,0,"help",m_help);
! FLEXT_CADDMETHOD_(c,0,"reload",m_reload_);
! FLEXT_CADDMETHOD_(c,0,"reload.",m_reload);
! FLEXT_CADDMETHOD_(c,0,"doc+",m_doc_);
! FLEXT_CADDMETHOD_(c,0,"dir+",m_dir_);
!
! FLEXT_CADDMETHOD_(c,0,"set",m_set);
!
! FLEXT_CADDATTR_VAR1(c,"py",pymsg);
! FLEXT_CADDATTR_VAR1(c,"respond",respond);
!
! // init translation map
! for(const xlt *xi = xtdefs; xi->from; ++xi) xtable[xi->from] = xi->to;
! }
!
! pymeth::pymeth(int argc,const t_atom *argv)
! : funname(NULL)
! , function(NULL)
! , objects(NULL)
! {
! #ifdef FLEXT_THREADS
! FLEXT_ADDTIMER(stoptmr,tick);
! #endif
!
! PyThreadState *state = PyLockSys();
!
! int inlets;
! if(argc && CanbeInt(*argv)) {
! inlets = GetAInt(*argv);
! if(inlets < 1) inlets = 1;
! argv++,argc--;
! }
! else inlets = 1;
!
! objects = new PyObject *[inlets];
! for(int i = 0; i < inlets; ++i) { objects[i] = Py_None; Py_INCREF(Py_None); }
!
! if(inlets <= 0) InitProblem();
!
! AddInAnything(1+(inlets < 0?1:inlets));
! AddOutAnything();
!
! Register(GetRegistry(REGNAME));
!
! if(argc) {
! const t_symbol *funnm = GetASymbol(*argv);
! argv++,argc--;
!
! if(funnm)
! SetFunction(funnm);
! else
! PyErr_SetString(PyExc_ValueError,"Invalid function name");
! }
!
! if(argc) args(argc,argv);
!
! Report();
!
! PyUnlock(state);
! }
!
! pymeth::~pymeth()
! {
! if(objects) {
! for(int i = 0; i < CntIn()-1; ++i) Py_DECREF(objects[i]);
! delete[] objects;
! }
!
! PyThreadState *state = PyLockSys();
! Unregister(GetRegistry(REGNAME));
! Report();
! PyUnlock(state);
! }
!
! void pymeth::Exit()
! {
! pybase::Exit();
! flext_base::Exit();
! }
!
! void pymeth::m_set(int argc,const t_atom *argv)
! {
! PyThreadState *state = PyLockSys();
!
! // function name has precedence
! if(argc >= 2) {
! const char *sn = GetAString(*argv);
! ++argv,--argc;
!
! if(sn) {
! if(!module || !strcmp(sn,PyModule_GetName(module))) {
! ImportModule(sn);
! Register(GetRegistry(REGNAME));
! }
! }
! else
! PyErr_SetString(PyExc_ValueError,"Invalid module name");
! }
!
! if(argc) {
! const t_symbol *fn = GetASymbol(*argv);
! if(fn)
! SetFunction(fn);
! else
! PyErr_SetString(PyExc_ValueError,"Invalid function name");
! }
!
! Report();
!
! PyUnlock(state);
! }
!
! void pymeth::m_help()
! {
! post("");
! post("%s %s - python method object, (C)2002-2005 Thomas Grill",thisName(),PY__VERSION);
! #ifdef FLEXT_DEBUG
! post("DEBUG VERSION, compiled on " __DATE__ " " __TIME__);
! #endif
!
! post("Arguments: %s [method name] {args...}",thisName());
!
! post("Inlet 1:messages to control the py object");
! post(" 2:call python function with message as argument(s)");
! post("Outlet: 1:return values from python function");
! post("Methods:");
! post("\thelp: shows this help");
! post("\tbang: call script without arguments");
! post("\tset [script name] [function name]: set (script and) function name");
! post("\treload {args...}: reload python script");
! 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/2: detach threads");
! post("\tstop {wait time (ms)}: stop threads");
! #endif
! post("");
! }
!
! void pymeth::ResetFunction()
! {
! Py_XDECREF(function);
! function = NULL;
!
! if(funname && objects[0] != Py_None) {
! function = PyObject_GetAttrString(objects[0],(char *)GetString(funname)); // new reference
! if(!function)
! PyErr_SetString(PyExc_AttributeError,"Method not found");
! }
!
! // exception could be set here
! }
!
! void pymeth::SetFunction(const t_symbol *func)
! {
! // look for method name in translation table
! XTable::iterator it = xtable.find(func);
! funname = it == xtable.end()?func:it->second;
!
! ResetFunction();
! }
!
!
! void pymeth::LoadModule()
! {
! SetFunction(funname);
! }
!
! void pymeth::UnloadModule()
! {
! }
!
! void pymeth::Load()
! {
! ResetFunction();
! }
!
! void pymeth::Unload()
! {
! SetFunction(NULL);
! }
!
! void pymeth::callpy(PyObject *fun,PyObject *args)
! {
! PyObject *ret = PyObject_CallObject(fun,args);
! if(ret) {
! OutObject(this,0,ret); // exception might be raised here
! Py_DECREF(ret);
! }
! }
!
! bool pymeth::CbMethodResort(int n,const t_symbol *s,int argc,const t_atom *argv)
! {
! if(n == 0 && s != sym_bang)
! return flext_base::CbMethodResort(n,s,argc,argv);
!
! PyThreadState *state = PyLockSys();
!
! bool ret = false;
!
! if(n >= 1) {
! // store args
! PyObject *&obj = objects[n-1];
! Py_DECREF(obj);
! obj = MakePyArg(s,argc,argv); // steal reference
!
! if(n > 1) ret = true; // just store, don't trigger
! }
!
! if(!ret) {
! if(function) {
! PyObject *self = PyMethod_Self(function);
! PyErr_Clear();
! if(!self || self->ob_type != objects[0]->ob_type)
! // type has changed, search for new method
! ResetFunction();
! else if(self != objects[0]) {
! // type hasn't changed, but object has
! PyObject *f = function;
! function = PyMethod_New(PyMethod_GET_FUNCTION(f),objects[0],PyMethod_GET_CLASS(f));
! Py_DECREF(f);
! }
! }
! else
! ResetFunction();
!
! if(function) {
! Py_INCREF(function);
!
! int inlets = CntIn()-1;
! PyObject *pargs = PyTuple_New(inlets-1);
! for(int i = 1; i < inlets; ++i) {
! Py_INCREF(objects[i]);
! PyTuple_SET_ITEM(pargs,i-1,objects[i]);
! }
!
! gencall(function,pargs); // references are stolen
! ret = true;
! }
! else
! PyErr_SetString(PyExc_RuntimeError,"No function set");
!
! Report();
! }
!
! PyUnlock(state);
!
! Respond(ret);
!
! return ret;
! }
!
! void pymeth::DumpOut(const t_symbol *sym,int argc,const t_atom *argv)
! {
! ToOutAnything(GetOutAttr(),sym?sym:thisTag(),argc,argv);
! }
--- 1,428 ----
! /*
!
! py/pyext - python script object for PD and Max/MSP
!
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
! #include "pybase.h"
! #include <map>
!
! struct xlt { const t_symbol *from,*to; };
!
! static const xlt xtdefs[] = {
! { flext::MakeSymbol("+"),flext::MakeSymbol("__add__") },
! { flext::MakeSymbol("+="),flext::MakeSymbol("__iadd__") },
! { flext::MakeSymbol("!+"),flext::MakeSymbol("__radd__") },
! { flext::MakeSymbol("-"),flext::MakeSymbol("__sub__") },
! { flext::MakeSymbol("-="),flext::MakeSymbol("__isub__") },
! { flext::MakeSymbol("!-"),flext::MakeSymbol("__rsub__") },
! { flext::MakeSymbol("*"),flext::MakeSymbol("__mul__") },
! { flext::MakeSymbol("*="),flext::MakeSymbol("__imul__") },
! { flext::MakeSymbol("!*"),flext::MakeSymbol("__rmul__") },
! { flext::MakeSymbol("/"),flext::MakeSymbol("__div__") },
! { flext::MakeSymbol("/="),flext::MakeSymbol("__idiv__") },
! { flext::MakeSymbol("!/"),flext::MakeSymbol("__rdiv__") },
! { flext::MakeSymbol("//"),flext::MakeSymbol("__floordiv__") },
! { flext::MakeSymbol("//="),flext::MakeSymbol("__ifloordiv__") },
! { flext::MakeSymbol("!//"),flext::MakeSymbol("__rfloordiv__") },
! { flext::MakeSymbol("%"),flext::MakeSymbol("__mod__") },
! { flext::MakeSymbol("%="),flext::MakeSymbol("__imod__") },
! { flext::MakeSymbol("!%"),flext::MakeSymbol("__rmod__") },
! { flext::MakeSymbol("**"),flext::MakeSymbol("__pow__") },
! { flext::MakeSymbol("**="),flext::MakeSymbol("__ipow__") },
! { flext::MakeSymbol("!**"),flext::MakeSymbol("__rpow__") },
! { flext::MakeSymbol("&"),flext::MakeSymbol("__and__") },
! { flext::MakeSymbol("&="),flext::MakeSymbol("__iand__") },
! { flext::MakeSymbol("!&"),flext::MakeSymbol("__rand__") },
! { flext::MakeSymbol("|"),flext::MakeSymbol("__or__") },
! { flext::MakeSymbol("|="),flext::MakeSymbol("__ior__") },
! { flext::MakeSymbol("!|"),flext::MakeSymbol("__ror__") },
! { flext::MakeSymbol("^"),flext::MakeSymbol("__xor__") },
! { flext::MakeSymbol("^="),flext::MakeSymbol("__ixor__") },
! { flext::MakeSymbol("!^"),flext::MakeSymbol("__rxor__") },
! { flext::MakeSymbol("<<"),flext::MakeSymbol("__lshift__") },
! { flext::MakeSymbol("<<="),flext::MakeSymbol("__ilshift__") },
! { flext::MakeSymbol("!<<"),flext::MakeSymbol("__rlshift__") },
! { flext::MakeSymbol(">>"),flext::MakeSymbol("__rshift__") },
! { flext::MakeSymbol(">>="),flext::MakeSymbol("__irshift__") },
! { flext::MakeSymbol("!>>"),flext::MakeSymbol("__rrshift__") },
! { flext::MakeSymbol("=="),flext::MakeSymbol("__eq__") },
! { flext::MakeSymbol("!="),flext::MakeSymbol("__ne__") },
! { flext::MakeSymbol("<"),flext::MakeSymbol("__lt__") },
! { flext::MakeSymbol(">"),flext::MakeSymbol("__gt__") },
! { flext::MakeSymbol("<="),flext::MakeSymbol("__le__") },
! { flext::MakeSymbol(">="),flext::MakeSymbol("__ge__") },
! { flext::MakeSymbol("!"),flext::MakeSymbol("__nonzero__") },
! { flext::MakeSymbol("~"),flext::MakeSymbol("__invert__") },
! { flext::MakeSymbol("[]"),flext::MakeSymbol("__getitem__") },
! { flext::MakeSymbol("[]="),flext::MakeSymbol("__setitem__") },
! { flext::MakeSymbol("[:]"),flext::MakeSymbol("__getslice__") },
! { flext::MakeSymbol("[:]="),flext::MakeSymbol("__setslice__") },
!
! { flext::MakeSymbol(".abs"),flext::MakeSymbol("__abs__") },
! { flext::MakeSymbol(".neg"),flext::MakeSymbol("__neg__") },
! { flext::MakeSymbol(".pos"),flext::MakeSymbol("__pos__") },
! { flext::MakeSymbol(".divmod"),flext::MakeSymbol("__divmod__") },
!
! { flext::MakeSymbol(".int"),flext::MakeSymbol("__int__") },
! { flext::MakeSymbol(".long"),flext::MakeSymbol("__long__") },
! { flext::MakeSymbol(".float"),flext::MakeSymbol("__float__") },
! { flext::MakeSymbol(".complex"),flext::MakeSymbol("__complex__") },
! { flext::MakeSymbol(".str"),flext::MakeSymbol("__str__") },
! { flext::MakeSymbol(".coerce"),flext::MakeSymbol("__coerce__") },
!
! { flext::MakeSymbol(".doc"),flext::MakeSymbol("__doc__") },
! { flext::MakeSymbol(".repr"),flext::MakeSymbol("__repr__") },
!
! { flext::MakeSymbol(".len"),flext::MakeSymbol("__len__") },
! { flext::MakeSymbol(".in"),flext::MakeSymbol("__contains") },
!
! { NULL,NULL } // sentinel
! };
!
! typedef std::map<const t_symbol *,const t_symbol *> XTable;
! static XTable xtable;
!
!
! class pymeth
! : public pybase
! , public flext_base
! {
! FLEXT_HEADER_S(pymeth,flext_base,Setup)
!
! public:
! pymeth(int argc,const t_atom *argv);
! ~pymeth();
!
! protected:
! virtual void Exit();
!
! virtual bool CbMethodResort(int n,const t_symbol *s,int argc,const t_atom *argv);
!
! void m_help();
!
! void m_reload() { Reload(); }
! void m_reload_(int argc,const t_atom *argv) { args(argc,argv); Reload(); }
! void m_set(int argc,const t_atom *argv);
! void m_dir_() { m__dir(function); }
! void m_doc_() { m__doc(function); }
!
! const t_symbol *funname;
! PyObject *function;
!
! virtual void LoadModule();
! virtual void UnloadModule();
!
! virtual void Load();
! virtual void Unload();
!
! void SetFunction(const t_symbol *func);
! void ResetFunction();
!
! virtual void DumpOut(const t_symbol *sym,int argc,const t_atom *argv);
!
! PyObject **objects;
!
! private:
!
! virtual void callpy(PyObject *fun,PyObject *args);
!
! static void Setup(t_classid c);
!
! FLEXT_CALLBACK(m_help)
! FLEXT_CALLBACK(m_reload)
! FLEXT_CALLBACK_V(m_reload_)
! FLEXT_CALLBACK_V(m_set)
! FLEXT_CALLBACK(m_dir_)
! FLEXT_CALLBACK(m_doc_)
!
! // callbacks
! FLEXT_ATTRVAR_I(detach)
! FLEXT_ATTRVAR_B(pymsg)
! FLEXT_ATTRVAR_B(respond)
!
! FLEXT_CALLBACK_V(m_stop)
! FLEXT_CALLBACK(m_dir)
! FLEXT_CALLGET_V(mg_dir)
! FLEXT_CALLBACK(m_doc)
!
! #ifdef FLEXT_THREADS
! FLEXT_CALLBACK_T(tick)
! #endif
! };
!
! FLEXT_LIB_V("pym",pymeth)
!
!
! void pymeth::Setup(t_classid c)
! {
! FLEXT_CADDMETHOD_(c,0,"doc",m_doc);
! FLEXT_CADDMETHOD_(c,0,"dir",m_dir);
! #ifdef FLEXT_THREADS
! FLEXT_CADDATTR_VAR1(c,"detach",detach);
! FLEXT_CADDMETHOD_(c,0,"stop",m_stop);
! #endif
!
! FLEXT_CADDMETHOD_(c,0,"help",m_help);
! FLEXT_CADDMETHOD_(c,0,"reload",m_reload_);
! FLEXT_CADDMETHOD_(c,0,"reload.",m_reload);
! FLEXT_CADDMETHOD_(c,0,"doc+",m_doc_);
! FLEXT_CADDMETHOD_(c,0,"dir+",m_dir_);
!
! FLEXT_CADDMETHOD_(c,0,"set",m_set);
!
! FLEXT_CADDATTR_VAR1(c,"py",pymsg);
! FLEXT_CADDATTR_VAR1(c,"respond",respond);
!
! // init translation map
! for(const xlt *xi = xtdefs; xi->from; ++xi) xtable[xi->from] = xi->to;
! }
!
! pymeth::pymeth(int argc,const t_atom *argv)
! : funname(NULL)
! , function(NULL)
! , objects(NULL)
! {
! #ifdef FLEXT_THREADS
! FLEXT_ADDTIMER(stoptmr,tick);
! #endif
!
! ThrState state = PyLockSys();
!
! int inlets;
! if(argc && CanbeInt(*argv)) {
! inlets = GetAInt(*argv);
! if(inlets < 1) inlets = 1;
! argv++,argc--;
! }
! else inlets = 1;
!
! objects = new PyObject *[inlets];
! for(int i = 0; i < inlets; ++i) { objects[i] = Py_None; Py_INCREF(Py_None); }
!
! if(inlets <= 0) InitProblem();
!
! AddInAnything(1+(inlets < 0?1:inlets));
! AddOutAnything();
!
! Register(GetRegistry(REGNAME));
!
! if(argc) {
! const t_symbol *funnm = GetASymbol(*argv);
! argv++,argc--;
!
! if(funnm)
! SetFunction(funnm);
! else
! PyErr_SetString(PyExc_ValueError,"Invalid function name");
! }
!
! if(argc) args(argc,argv);
!
! Report();
!
! PyUnlock(state);
! }
!
! pymeth::~pymeth()
! {
! if(objects) {
! for(int i = 0; i < CntIn()-1; ++i) Py_DECREF(objects[i]);
! delete[] objects;
! }
!
! ThrState state = PyLockSys();
! Unregister(GetRegistry(REGNAME));
! Report();
! PyUnlock(state);
! }
!
! void pymeth::Exit()
! {
! pybase::Exit();
! flext_base::Exit();
! }
!
! void pymeth::m_set(int argc,const t_atom *argv)
! {
! ThrState state = PyLockSys();
!
! // function name has precedence
! if(argc >= 2) {
! const char *sn = GetAString(*argv);
! ++argv,--argc;
!
! if(sn) {
! if(!module || !strcmp(sn,PyModule_GetName(module))) {
! ImportModule(sn);
! Register(GetRegistry(REGNAME));
! }
! }
! else
! PyErr_SetString(PyExc_ValueError,"Invalid module name");
! }
!
! if(argc) {
! const t_symbol *fn = GetASymbol(*argv);
! if(fn)
! SetFunction(fn);
! else
! PyErr_SetString(PyExc_ValueError,"Invalid function name");
! }
!
! Report();
!
! PyUnlock(state);
! }
!
! void pymeth::m_help()
! {
! post("");
! post("%s %s - python method object, (C)2002-2005 Thomas Grill",thisName(),PY__VERSION);
! #ifdef FLEXT_DEBUG
! post("DEBUG VERSION, compiled on " __DATE__ " " __TIME__);
! #endif
!
! post("Arguments: %s [method name] {args...}",thisName());
!
! post("Inlet 1:messages to control the py object");
! post(" 2:call python function with message as argument(s)");
! post("Outlet: 1:return values from python function");
! post("Methods:");
! post("\thelp: shows this help");
! post("\tbang: call script without arguments");
! post("\tset [script name] [function name]: set (script and) function name");
! post("\treload {args...}: reload python script");
! 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/2: detach threads");
! post("\tstop {wait time (ms)}: stop threads");
! #endif
! post("");
! }
!
! void pymeth::ResetFunction()
! {
! Py_XDECREF(function);
! function = NULL;
!
! if(funname && objects[0] != Py_None) {
! function = PyObject_GetAttrString(objects[0],(char *)GetString(funname)); // new reference
! if(!function)
! PyErr_SetString(PyExc_AttributeError,"Method not found");
! }
!
! // exception could be set here
! }
!
! void pymeth::SetFunction(const t_symbol *func)
! {
! // look for method name in translation table
! XTable::iterator it = xtable.find(func);
! funname = it == xtable.end()?func:it->second;
!
! ResetFunction();
! }
!
!
! void pymeth::LoadModule()
! {
! SetFunction(funname);
! }
!
! void pymeth::UnloadModule()
! {
! }
!
! void pymeth::Load()
! {
! ResetFunction();
! }
!
! void pymeth::Unload()
! {
! SetFunction(NULL);
! }
!
! void pymeth::callpy(PyObject *fun,PyObject *args)
! {
! PyObject *ret = PyObject_CallObject(fun,args);
! if(ret) {
! OutObject(this,0,ret); // exception might be raised here
! Py_DECREF(ret);
! }
! }
!
! bool pymeth::CbMethodResort(int n,const t_symbol *s,int argc,const t_atom *argv)
! {
! if(n == 0 && s != sym_bang)
! return flext_base::CbMethodResort(n,s,argc,argv);
!
! ThrState state = PyLockSys();
!
! bool ret = false;
!
! if(n >= 1) {
! // store args
! PyObject *&obj = objects[n-1];
! Py_DECREF(obj);
! obj = MakePyArg(s,argc,argv); // steal reference
!
! if(n > 1) ret = true; // just store, don't trigger
! }
!
! if(!ret) {
! if(function) {
! PyObject *self = PyMethod_Self(function);
! PyErr_Clear();
! if(!self || self->ob_type != objects[0]->ob_type)
! // type has changed, search for new method
! ResetFunction();
! else if(self != objects[0]) {
! // type hasn't changed, but object has
! PyObject *f = function;
! function = PyMethod_New(PyMethod_GET_FUNCTION(f),objects[0],PyMethod_GET_CLASS(f));
! Py_DECREF(f);
! }
! }
! else
! ResetFunction();
!
! if(function) {
! Py_INCREF(function);
!
! int inlets = CntIn()-1;
! PyObject *pargs = PyTuple_New(inlets-1);
! for(int i = 1; i < inlets; ++i) {
! Py_INCREF(objects[i]);
! PyTuple_SET_ITEM(pargs,i-1,objects[i]);
! }
!
! gencall(function,pargs); // references are stolen
! ret = true;
! }
! else
! PyErr_SetString(PyExc_RuntimeError,"No function set");
!
! Report();
! }
!
! PyUnlock(state);
!
! Respond(ret);
!
! return ret;
! }
!
! void pymeth::DumpOut(const t_symbol *sym,int argc,const t_atom *argv)
! {
! ToOutAnything(GetOutAttr(),sym?sym:thisTag(),argc,argv);
! }
Index: pybundle.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pybundle.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** pybundle.cpp 12 Dec 2005 13:55:28 -0000 1.1
--- pybundle.cpp 7 Mar 2007 13:40:14 -0000 1.2
***************
*** 1,232 ****
! /*
!
! py/pyext - python script object for PD and Max/MSP
!
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
! #include "pyprefix.h"
! #include "pybundle.h"
! #include "pyext.h"
!
! static PyObject *bundle_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
! {
! pyBundle *self = (pyBundle *)pyBundle_Type.tp_alloc(&pyBundle_Type, 0);
! if(self) self->bundle = flext::MsgNew();
! return (PyObject *)self;
! }
!
! static int bundle_init(PyObject *self, PyObject *args, PyObject *kwds)
! {
! FLEXT_ASSERT(pyBundle_Check(self));
!
! int len = PySequence_Length(args);
! if(len) {
! PyErr_SetString(PyExc_TypeError,"no arguments expected");
! return -1;
! }
!
! return 0;
! }
!
! static void bundle_dealloc(PyObject *obj)
! {
! pyBundle *self = (pyBundle *)obj;
! if(self->bundle) flext::MsgFree(self->bundle);
! obj->ob_type->tp_free(obj);
! }
!
! static PyObject *bundle_send(PyObject *obj)
! {
! pyBundle *self = (pyBundle *)obj;
! if(self->bundle) {
! flext::ToOutMsg(self->bundle);
! self->bundle = NULL;
!
! Py_INCREF(obj);
! return obj;
! }
! else {
! PyErr_SetString(PyExc_RuntimeError,"already sent");
! return NULL;
! }
! }
!
! static PyObject *bundle_repr(PyObject *self)
! {
! FLEXT_ASSERT(pyBundle_Check(self));
! return (PyObject *)PyString_FromFormat("<Bundle %p>",pyBundle_AS_BUNDLE(self));
! }
!
! static PyObject *bundle_str(PyObject *self)
! {
! return bundle_repr(self);
! }
!
! static PyObject *bundle_richcompare(PyObject *a,PyObject *b,int cmp)
! {
! if(pyBundle_Check(a) && pyBundle_Check(b)) {
! const flext::MsgBundle *abnd = pyBundle_AS_BUNDLE(a);
! const flext::MsgBundle *bbnd = pyBundle_AS_BUNDLE(b);
! bool ret;
! switch(cmp) {
! case Py_LT: ret = abnd < bbnd; break;
! case Py_LE: ret = abnd <= bbnd; break;
! case Py_EQ: ret = abnd == bbnd; break;
! case Py_NE: ret = abnd != bbnd; break;
! case Py_GT: ret = abnd > bbnd; break;
! case Py_GE: ret = abnd >= bbnd; break;
! }
! return PyBool_FromLong(ret);
! }
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
! }
!
! static long bundle_hash(PyObject *self)
! {
! FLEXT_ASSERT(pyBundle_Check(self));
! return (long)pyBundle_AS_BUNDLE(self);
! }
!
!
! static PyObject *bundle_append(PyObject *self,PyObject *args)
! {
! flext::MsgBundle *b = pyBundle_AS_BUNDLE(self);
! if(b) {
! int sz = PyTuple_GET_SIZE(args),offs = 0;
! PyObject *tg,*outl;
! pyext *ext = NULL;
! const t_symbol *recv;
! int o;
!
! if(sz > 2 &&
! (tg = PyTuple_GET_ITEM(args,0)) != NULL && PyInstance_Check(tg) &&
! (outl = PyTuple_GET_ITEM(args,1)) != NULL && PyInt_Check(outl)
! ) {
! // Sending to outlet
! ext = pyext::GetThis(tg);
! o = PyInt_AS_LONG(outl);
!
! if(o < 1 || o > ext->Outlets()) {
! PyErr_SetString(PyExc_ValueError,"Outlet index out of range");
! return NULL;
! }
!
! offs += 2;
! }
! else if(sz > 1 &&
! (tg = PyTuple_GET_ITEM(args,0)) != NULL && (recv = pyObject_AsSymbol(tg)) != NULL
! ) {
! // Sending to receiver
! offs++;
! }
! else {
! // not recognized
! PyErr_SetString(PyExc_SyntaxError,"Unrecognized arguments");
! return NULL;
! }
!
! PyObject *val;
! if(sz-offs == 1) {
! val = PyTuple_GET_ITEM(args,offs); // borrow reference
! Py_INCREF(val);
! }
! else
! val = PyTuple_GetSlice(args,offs,sz); // new ref
!
! flext::AtomListStatic<16> lst;
! const t_symbol *sym = pybase::GetPyArgs(lst,val);
! Py_DECREF(val);
!
! if(sym) {
! if(ext) {
! FLEXT_ASSERT(outl);
! ext->MsgAddAnything(b,o-1,sym,lst.Count(),lst.Atoms());
! }
! else {
! FLEXT_ASSERT(sym);
! if(!flext::MsgForward(b,recv,sym,lst.Count(),lst.Atoms())) {
! PyErr_SetString(PyExc_ValueError,"Receiver not found");
! return NULL;
! }
! }
!
! Py_INCREF(Py_None);
! return Py_None;
! }
! else {
! FLEXT_ASSERT(PyErr_Occurred());
! return NULL;
! }
!
! Py_INCREF(self);
! return self;
! }
! else {
! PyErr_SetString(PyExc_RuntimeError,"Invalid bundle");
! return NULL;
! }
! }
!
! static PyMethodDef bundle_methods[] = {
! {"append", (PyCFunction)bundle_append,METH_VARARGS,"Append message to bundle"},
! {"send", (PyCFunction)bundle_send,METH_NOARGS,"Send bundle"},
! {NULL} /* Sentinel */
! };
!
!
!
! PyTypeObject pyBundle_Type = {
! PyObject_HEAD_INIT(NULL)
! 0, /*ob_size*/
! "Bundle", /*tp_name*/
! sizeof(pyBundle), /*tp_basicsize*/
! 0, /*tp_itemsize*/
! bundle_dealloc, /*tp_dealloc*/
! 0, /*tp_print*/
! 0, /*tp_getattr*/
! 0, /*tp_setattr*/
! 0, /*tp_compare*/
! bundle_repr, /*tp_repr*/
! 0, /*tp_as_number*/
! 0, /*tp_as_sequence*/
! 0, /*tp_as_mapping*/
! bundle_hash, /*tp_hash */
! 0, /*tp_call*/
! bundle_str, /*tp_str*/
! 0, /*tp_getattro*/
! 0, /*tp_setattro*/
! 0, /*tp_as_buffer*/
! Py_TPFLAGS_DEFAULT /*| Py_TPFLAGS_BASETYPE*/, /*tp_flags*/
! "Bundle objects", /* tp_doc */
! 0, /* tp_traverse */
! 0, /* tp_clear */
! bundle_richcompare, /* tp_richcompare */
! 0, /* tp_weaklistoffset */
! 0, /* tp_iter */
! 0, /* tp_iternext */
! bundle_methods, /* tp_methods */
! 0, /* tp_members */
! 0, /* tp_getset */
! 0, /* tp_base */
! 0, /* tp_dict */
! 0, /* tp_descr_get */
! 0, /* tp_descr_set */
! 0, /* tp_dictoffset */
! bundle_init, /* tp_init */
! 0, /* tp_alloc */
! bundle_new, /* tp_new */
! };
!
!
! void initbundle()
! {
! if(PyType_Ready(&pyBundle_Type) < 0)
! FLEXT_ASSERT(false);
! else
! Py_INCREF(&pyBundle_Type);
! }
--- 1,232 ----
! /*
!
! py/pyext - python script object for PD and Max/MSP
!
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
! #include "pyprefix.h"
! #include "pybundle.h"
! #include "pyext.h"
!
! static PyObject *bundle_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
! {
! pyBundle *self = (pyBundle *)pyBundle_Type.tp_alloc(&pyBundle_Type, 0);
! if(self) self->bundle = flext::MsgNew();
! return (PyObject *)self;
! }
!
! static int bundle_init(PyObject *self, PyObject *args, PyObject *kwds)
! {
! FLEXT_ASSERT(pyBundle_Check(self));
!
! int len = PySequence_Length(args);
! if(len) {
! PyErr_SetString(PyExc_TypeError,"no arguments expected");
! return -1;
! }
!
! return 0;
! }
!
! static void bundle_dealloc(PyObject *obj)
! {
! pyBundle *self = (pyBundle *)obj;
! if(self->bundle) flext::MsgFree(self->bundle);
! obj->ob_type->tp_free(obj);
! }
!
! static PyObject *bundle_send(PyObject *obj)
! {
! pyBundle *self = (pyBundle *)obj;
! if(self->bundle) {
! flext::ToOutMsg(self->bundle);
! self->bundle = NULL;
!
! Py_INCREF(obj);
! return obj;
! }
! else {
! PyErr_SetString(PyExc_RuntimeError,"already sent");
! return NULL;
! }
! }
!
! static PyObject *bundle_repr(PyObject *self)
! {
! FLEXT_ASSERT(pyBundle_Check(self));
! return (PyObject *)PyString_FromFormat("<Bundle %p>",pyBundle_AS_BUNDLE(self));
! }
!
! static PyObject *bundle_str(PyObject *self)
! {
! return bundle_repr(self);
! }
!
! static PyObject *bundle_richcompare(PyObject *a,PyObject *b,int cmp)
! {
! if(pyBundle_Check(a) && pyBundle_Check(b)) {
! const flext::MsgBundle *abnd = pyBundle_AS_BUNDLE(a);
! const flext::MsgBundle *bbnd = pyBundle_AS_BUNDLE(b);
! bool ret;
! switch(cmp) {
! case Py_LT: ret = abnd < bbnd; break;
! case Py_LE: ret = abnd <= bbnd; break;
! case Py_EQ: ret = abnd == bbnd; break;
! case Py_NE: ret = abnd != bbnd; break;
! case Py_GT: ret = abnd > bbnd; break;
! case Py_GE: ret = abnd >= bbnd; break;
! }
! return PyBool_FromLong(ret);
! }
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
! }
!
! static long bundle_hash(PyObject *self)
! {
! FLEXT_ASSERT(pyBundle_Check(self));
! return (long)pyBundle_AS_BUNDLE(self);
! }
!
!
! static PyObject *bundle_append(PyObject *self,PyObject *args)
! {
! flext::MsgBundle *b = pyBundle_AS_BUNDLE(self);
! if(b) {
! int sz = PyTuple_GET_SIZE(args),offs = 0;
! PyObject *tg,*outl;
! pyext *ext = NULL;
! const t_symbol *recv;
! int o;
!
! if(sz > 2 &&
! (tg = PyTuple_GET_ITEM(args,0)) != NULL && PyInstance_Check(tg) &&
! (outl = PyTuple_GET_ITEM(args,1)) != NULL && PyInt_Check(outl)
! ) {
! // Sending to outlet
! ext = pyext::GetThis(tg);
! o = PyInt_AS_LONG(outl);
!
! if(o < 1 || o > ext->Outlets()) {
! PyErr_SetString(PyExc_ValueError,"Outlet index out of range");
! return NULL;
! }
!
! offs += 2;
! }
! else if(sz > 1 &&
! (tg = PyTuple_GET_ITEM(args,0)) != NULL && (recv = pyObject_AsSymbol(tg)) != NULL
! ) {
! // Sending to receiver
! offs++;
! }
! else {
! // not recognized
! PyErr_SetString(PyExc_SyntaxError,"Unrecognized arguments");
! return NULL;
! }
!
! PyObject *val;
! if(sz-offs == 1) {
! val = PyTuple_GET_ITEM(args,offs); // borrow reference
! Py_INCREF(val);
! }
! else
! val = PyTuple_GetSlice(args,offs,sz); // new ref
!
! flext::AtomListStatic<16> lst;
! const t_symbol *sym = pybase::GetPyArgs(lst,val);
! Py_DECREF(val);
!
! if(sym) {
! if(ext) {
! FLEXT_ASSERT(outl);
! ext->MsgAddAnything(b,o-1,sym,lst.Count(),lst.Atoms());
! }
! else {
! FLEXT_ASSERT(sym);
! if(!flext::MsgForward(b,recv,sym,lst.Count(),lst.Atoms())) {
! PyErr_SetString(PyExc_ValueError,"Receiver not found");
! return NULL;
! }
! }
!
! Py_INCREF(Py_None);
! return Py_None;
! }
! else {
! FLEXT_ASSERT(PyErr_Occurred());
! return NULL;
! }
!
! Py_INCREF(self);
! return self;
! }
! else {
! PyErr_SetString(PyExc_RuntimeError,"Invalid bundle");
! return NULL;
! }
! }
!
! static PyMethodDef bundle_methods[] = {
! {"append", (PyCFunction)bundle_append,METH_VARARGS,"Append message to bundle"},
! {"send", (PyCFunction)bundle_send,METH_NOARGS,"Send bundle"},
! {NULL} /* Sentinel */
! };
!
!
!
! PyTypeObject pyBundle_Type = {
! PyObject_HEAD_INIT(NULL)
! 0, /*ob_size*/
! "Bundle", /*tp_name*/
! sizeof(pyBundle), /*tp_basicsize*/
! 0, /*tp_itemsize*/
! bundle_dealloc, /*tp_dealloc*/
! 0, /*tp_print*/
! 0, /*tp_getattr*/
! 0, /*tp_setattr*/
! 0, /*tp_compare*/
! bundle_repr, /*tp_repr*/
! 0, /*tp_as_number*/
! 0, /*tp_as_sequence*/
! 0, /*tp_as_mapping*/
! bundle_hash, /*tp_hash */
! 0, /*tp_call*/
! bundle_str, /*tp_str*/
! 0, /*tp_getattro*/
! 0, /*tp_setattro*/
! 0, /*tp_as_buffer*/
! Py_TPFLAGS_DEFAULT /*| Py_TPFLAGS_BASETYPE*/, /*tp_flags*/
! "Bundle objects", /* tp_doc */
! 0, /* tp_traverse */
! 0, /* tp_clear */
! bundle_richcompare, /* tp_richcompare */
! 0, /* tp_weaklistoffset */
! 0, /* tp_iter */
! 0, /* tp_iternext */
! bundle_methods, /* tp_methods */
! 0, /* tp_members */
! 0, /* tp_getset */
! 0, /* tp_base */
! 0, /* tp_dict */
! 0, /* tp_descr_get */
! 0, /* tp_descr_set */
! 0, /* tp_dictoffset */
! bundle_init, /* tp_init */
! 0, /* tp_alloc */
! bundle_new, /* tp_new */
! };
!
!
! void initbundle()
! {
! if(PyType_Ready(&pyBundle_Type) < 0)
! FLEXT_ASSERT(false);
! else
! Py_INCREF(&pyBundle_Type);
! }
Index: pybase.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pybase.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -C2 -d -r1.12 -r1.13
*** pybase.h 3 Aug 2006 16:33:37 -0000 1.12
--- pybase.h 7 Mar 2007 13:40:14 -0000 1.13
***************
*** 1,228 ****
! /*
!
! py/pyext - python script object for PD and MaxMSP
!
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
! #ifndef __PYBASE_H
! #define __PYBASE_H
!
! #include "main.h"
! #include "pysymbol.h"
! #include "pybuffer.h"
! #include "pybundle.h"
!
! class pybase
! : public flext
! {
! public:
! pybase();
! virtual ~pybase();
!
! void Exit();
!
! static PyObject *MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,int inlet = -1);
! static PyObject *MakePyArg(const t_symbol *s,int argc,const t_atom *argv);
! static const t_symbol *GetPyArgs(AtomList &lst,PyObject *pValue,int offs = 0);
! static const t_symbol *GetPyAtom(AtomList &lst,PyObject *pValue);
!
! static void lib_setup();
!
! protected:
!
! virtual void DumpOut(const t_symbol *sym,int argc,const t_atom *argv) = 0;
!
! void m__dir(PyObject *obj);
! void m__doc(PyObject *obj);
!
! void m_dir() { m__dir(module); }
! void mg_dir(AtomList &lst) { m__dir(module); }
! void m_doc() { m__doc(dict); }
!
! std::string modname; // module name
! PyObject *module,*dict; // object module and associated dictionary
!
! static const char *py_doc;
!
! void GetDir(PyObject *obj,AtomList &lst);
!
! AtomList args;
!
! void AddCurrentPath(flext_base *o);
! void SetArgs();
!
! bool OutObject(flext_base *ext,int o,PyObject *obj);
!
! // reload module and all connected objects
! void Reload();
!
! bool ImportModule(const char *name);
! void UnimportModule();
! bool ReloadModule();
!
! // Get module registry
! PyObject *GetRegistry(const char *regname);
! // Set module registry
! void SetRegistry(const char *regname,PyObject *reg);
!
! // Register object
! void Register(PyObject *reg);
! // Unregister object
! void Unregister(PyObject *reg);
!
! virtual void LoadModule() = 0;
! virtual void UnloadModule() = 0;
!
! virtual void Load() = 0;
! virtual void Unload() = 0;
!
! void OpenEditor();
!
! void Respond(bool b)
! {
! if(respond) {
! t_atom a;
! SetBool(a,b);
! DumpOut(sym_response,1,&a);
! }
! }
!
! void Report() { while(PyErr_Occurred()) PyErr_Print(); }
!
! static bool IsAnything(const t_symbol *s) { return s && s != sym_float && s != sym_int && s != sym_symbol && s != sym_list && s != sym_pointer; }
! static bool IsAtom(const t_symbol *s) { return s == sym_float || s == sym_int || s == sym_symbol || s == sym_pointer; }
!
! // enum retval { nothing,atom,sequ };
!
! // --- module stuff -----
!
! static PyObject *module_obj,*module_dict;
! static PyObject *builtins_obj,*builtins_dict;
! static PyMethodDef func_tbl[];
!
! static PyObject *py__doc__(PyObject *,PyObject *args);
! static PyObject *py_send(PyObject *,PyObject *args);
! #ifdef FLEXT_THREADS
! static PyObject *py_priority(PyObject *,PyObject *args);
! #endif
!
! static PyObject *py_arraysupport(PyObject *,PyObject *args);
! static PyObject *py_samplerate(PyObject *,PyObject *args);
! static PyObject *py_blocksize(PyObject *,PyObject *args);
!
! #if FLEXT_SYS == FLEXT_SYS_PD
! static PyObject *py_getvalue(PyObject *,PyObject *args);
! static PyObject *py_setvalue(PyObject *,PyObject *args);
! #endif
!
! static PyObject *py_list(PyObject *,PyObject *args);
! static PyObject *py_tuple(PyObject *,PyObject *args);
!
! // ----thread stuff ------------
!
! virtual void m_stop(int argc,const t_atom *argv);
!
! bool respond;
! #ifdef FLEXT_THREADS
! int thrcount;
! bool shouldexit;
! int stoptick;
! Timer stoptmr;
!
! void tick(void *);
! #endif
!
! int detach;
! bool pymsg;
!
! bool gencall(PyObject *fun,PyObject *args);
!
! bool docall(PyObject *fun,PyObject *args)
! {
! callpy(fun,args);
! if(PyErr_Occurred()) {
! exchandle();
! return false;
! }
! else
! return true;
! }
!
! virtual void callpy(PyObject *fun,PyObject *args) = 0;
!
! void exchandle();
!
! static bool collect();
!
! protected:
!
! #ifdef FLEXT_THREADS
! static void thrworker(thr_params *data);
!
! bool qucall(PyObject *fun,PyObject *args)
! {
! FifoEl *el = qufifo.New();
! el->Set(this,fun,args);
! qufifo.Put(el);
! qucond.Signal();
! return true;
! }
!
! static void quworker(thr_params *);
! void erasethreads();
!
! static PyFifo qufifo;
! static ThrCond qucond;
! static PyThreadState *pythrsys;
! #endif
!
! static const t_symbol *sym_fint; // float or int symbol, depending on native number message type
! static const t_symbol *sym_response;
!
! static const t_symbol *getone(t_atom &at,PyObject *arg);
! static const t_symbol *getlist(t_atom *lst,PyObject *seq,int cnt,int offs = 0);
!
! public:
!
! static void AddToPath(const char *dir);
!
! #ifdef FLEXT_THREADS
! static PyThreadState *FindThreadState();
! static void FreeThreadState();
!
! // this is especially needed when one py/pyext object calls another one
! // we don't want the message to be queued, but otoh we have to avoid deadlock
! // (recursive calls can only happen in the system thread)
! static int lockcount;
!
! static PyThreadState *PyLock(PyThreadState *st = FindThreadState())
! {
! if(!IsSystemThread() || !lockcount++) PyEval_AcquireLock();
! return PyThreadState_Swap(st);
! }
!
! static PyThreadState *PyLockSys()
! {
! if(!lockcount++) PyEval_AcquireLock();
! return PyThreadState_Swap(pythrsys);
! }
!
! static void PyUnlock(PyThreadState *st)
! {
! PyThreadState *old = PyThreadState_Swap(st);
! if(old != pythrsys || !--lockcount) PyEval_ReleaseLock();
! }
! #else
! static PyThreadState *PyLock(PyThreadState * = NULL) { return NULL; }
! static PyThreadState *PyLockSys() { return NULL; }
! static void PyUnlock(PyThreadState *st) {}
! #endif
!
! static PyObject* StdOut_Write(PyObject* Self, PyObject* Args);
! };
!
! #endif
--- 1,251 ----
! /*
!
! py/pyext - python script object for PD and MaxMSP
!
! Copyright (c)2002-2007 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
! #ifndef __PYBASE_H
! #define __PYBASE_H
!
! #include "main.h"
! #include "pysymbol.h"
! #include "pybuffer.h"
! #include "pybundle.h"
!
! #ifdef PY_USE_GIL
! typedef PyGILState_STATE ThrState;
! #else
! typedef PyThreadState *ThrState;
! #endif
!
! class pybase
! : public flext
! {
! public:
! pybase();
! virtual ~pybase();
!
! void Exit();
!
! static PyObject *MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,int inlet = -1);
! static PyObject *MakePyArg(const t_symbol *s,int argc,const t_atom *argv);
! static const t_symbol *GetPyArgs(AtomList &lst,PyObject *pValue,int offs = 0);
! static const t_symbol *GetPyAtom(AtomList &lst,PyObject *pValue);
!
! static void lib_setup();
!
! protected:
!
! virtual void DumpOut(const t_symbol *sym,int argc,const t_atom *argv) = 0;
!
! void m__dir(PyObject *obj);
! void m__doc(PyObject *obj);
!
! void m_dir() { m__dir(module); }
! void mg_dir(AtomList &lst) { m__dir(module); }
! void m_doc() { m__doc(dict); }
!
! std::string modname; // module name
! PyObject *module,*dict; // object module and associated dictionary
!
! static const char *py_doc;
!
! void GetDir(PyObject *obj,AtomList &lst);
!
! AtomList args;
!
! void AddCurrentPath(flext_base *o);
! void SetArgs();
!
! bool OutObject(flext_base *ext,int o,PyObject *obj);
!
! // reload module and all connected objects
! void Reload();
!
! bool ImportModule(const char *name);
! void UnimportModule();
! bool ReloadModule();
!
! // Get module registry
! PyObject *GetRegistry(const char *regname);
! // Set module registry
! void SetRegistry(const char *regname,PyObject *reg);
!
! // Register object
! void Register(PyObject *reg);
! // Unregister object
! void Unregister(PyObject *reg);
!
! virtual void LoadModule() = 0;
! virtual void UnloadModule() = 0;
!
! virtual void Load() = 0;
! virtual void Unload() = 0;
!
! void OpenEditor();
!
! void Respond(bool b)
! {
! if(respond) {
! t_atom a;
! SetBool(a,b);
! DumpOut(sym_response,1,&a);
! }
! }
!
! void Report() { while(PyErr_Occurred()) PyErr_Print(); }
!
! static bool IsAnything(const t_symbol *s) { return s && s != sym_float && s != sym_int && s != sym_symbol && s != sym_list && s != sym_pointer; }
! static bool IsAtom(const t_symbol *s) { return s == sym_float || s == sym_int || s == sym_symbol || s == sym_pointer; }
!
! // enum retval { nothing,atom,sequ };
!
! // --- module stuff -----
!
! static PyObject *module_obj,*module_dict;
! static PyObject *builtins_obj,*builtins_dict;
! static PyMethodDef func_tbl[];
!
! static PyObject *py__doc__(PyObject *,PyObject *args);
! static PyObject *py_send(PyObject *,PyObject *args);
! #ifdef FLEXT_THREADS
! static PyObject *py_priority(PyObject *,PyObject *args);
! #endif
!
! static PyObject *py_arraysupport(PyObject *,PyObject *args);
! static PyObject *py_samplerate(PyObject *,PyObject *args);
! static PyObject *py_blocksize(PyObject *,PyObject *args);
!
! #if FLEXT_SYS == FLEXT_SYS_PD
! static PyObject *py_getvalue(PyObject *,PyObject *args);
! static PyObject *py_setvalue(PyObject *,PyObject *args);
! #endif
!
! static PyObject *py_list(PyObject *,PyObject *args);
! static PyObject *py_tuple(PyObject *,PyObject *args);
!
! // ----thread stuff ------------
!
! virtual void m_stop(int argc,const t_atom *argv);
!
! bool respond;
! #ifdef FLEXT_THREADS
! int thrcount;
! bool shouldexit;
! int stoptick;
! Timer stoptmr;
!
! void tick(void *);
! #endif
!
! int detach;
! bool pymsg;
!
! bool gencall(PyObject *fun,PyObject *args);
!
! bool docall(PyObject *fun,PyObject *args)
! {
! callpy(fun,args);
! if(PyErr_Occurred()) {
! exchandle();
! return false;
! }
! else
! return true;
! }
!
! virtual void callpy(PyObject *fun,PyObject *args) = 0;
!
! void exchandle();
!
! static bool collect();
!
! protected:
!
! #ifdef FLEXT_THREADS
! static void thrworker(thr_params *data);
!
! bool qucall(PyObject *fun,PyObject *args)
! {
! FifoEl *el = qufifo.New();
! el->Set(this,fun,args);
! qufifo.Put(el);
! qucond.Signal();
! return true;
! }
!
! static void quworker(thr_params *);
! static void pyworker(thr_params *);
! void erasethreads();
!
! static PyFifo qufifo;
! static ThrCond qucond;
!
! #ifndef PY_USE_GIL
! static ThrState pythrsys;
! #endif
! #endif
!
! static const t_symbol *sym_fint; // float or int symbol, depending on native number message type
! static const t_symbol *sym_response;
!
! static const t_symbol *getone(t_atom &at,PyObject *arg);
! static const t_symbol *getlist(t_atom *lst,PyObject *seq,int cnt,int offs = 0);
!
! public:
!
! static void AddToPath(const char *dir);
!
! #ifdef FLEXT_THREADS
! // this is especially needed when one py/pyext object calls another one
! // we don't want the message to be queued, but otoh we have to avoid deadlock
! // (recursive calls can only happen in the system thread)
! static int lockcount;
!
! #ifdef PY_USE_GIL
! static inline ThrState FindThreadState() { return ThrState(); }
!
! static inline ThrState PyLock(ThrState = ThrState()) { return PyGILState_Ensure(); }
! static inline ThrState PyLockSys() { return PyLock(); }
! static inline void PyUnlock(ThrState st) { PyGILState_Release(st); }
! #else // PY_USE_GIL
! static ThrState FindThreadState();
! static void FreeThreadState();
!
! static ThrState PyLock(ThrState st = FindThreadState())
! {
! if(!IsSystemThread() || !lockcount++) PyEval_AcquireLock();
! return PyThreadState_Swap(st);
! }
!
! #if 1
! static inline ThrState PyLockSys() { return PyLock(); }
! #else
! static ThrState PyLockSys()
! {
! if(!lockcount++) PyEval_AcquireLock();
! return PyThreadState_Swap(pythrsys);
! }
! #endif
!
! static void PyUnlock(ThrState st)
! {
! ThrState old = PyThreadState_Swap(st);
! if(old != pythrsys || !--lockcount) PyEval_ReleaseLock();
! }
! #endif // PY_USE_GIL
!
! #else // FLEXT_THREADS
! static inline ThrState PyLock(ThrState = NULL) { return NULL; }
! static inline ThrState PyLockSys() { return NULL; }
! static inline void PyUnlock(ThrState st) {}
! #endif
!
! static PyObject* StdOut_Write(PyObject* Self, PyObject* Args);
! };
!
! #endif
Index: pybase.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pybase.cpp,v
retrieving revision 1.17
retrieving revision 1.18
diff -C2 -d -r1.17 -r1.18
*** pybase.cpp 19 Apr 2006 17:39:41 -0000 1.17
--- pybase.cpp 7 Mar 2007 13:40:14 -0000 1.18
***************
*** 1,881 ****
! /*
!
! py/pyext - python external object for PD and MaxMSP
!
! Copyright (c)2002-2006 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
[...1764 lines suppressed...]
! // Push back
! while(el = tmp.Get()) qufifo.Put(el);
! }
! #endif
!
! bool pybase::collect()
! {
! if(gcollect) {
! PyObject *ret = PyObject_CallObject(gcollect,NULL);
! if(ret) {
! #ifdef FLEXT_DEBUG
! int refs = PyInt_AsLong(ret);
! if(refs) post("py/pyext - Garbage collector reports %i unreachable objects",refs);
! #endif
! Py_DECREF(ret);
! return false;
! }
! }
! return true;
! }
Index: py.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/py.cpp,v
retrieving revision 1.35
retrieving revision 1.36
diff -C2 -d -r1.35 -r1.36
*** py.cpp 23 Mar 2006 01:42:05 -0000 1.35
--- py.cpp 7 Mar 2007 13:40:14 -0000 1.36
***************
*** 3,7 ****
py/pyext - python script object for PD and Max/MSP
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
--- 3,7 ----
py/pyext - python script object for PD and Max/MSP
! Copyright (c)2002-2007 Thomas Grill (gr(a)grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
***************
*** 118,122 ****
#endif
! PyThreadState *state = PyLockSys();
int inlets;
--- 118,122 ----
#endif
! ThrState state = PyLockSys();
int inlets;
***************
*** 194,198 ****
}
! PyThreadState *state = PyLockSys();
Unregister(GetRegistry(REGNAME));
Report();
--- 194,198 ----
}
! ThrState state = PyLockSys();
Unregister(GetRegistry(REGNAME));
Report();
***************
*** 208,212 ****
void pyobj::m_set(int argc,const t_atom *argv)
{
! PyThreadState *state = PyLockSys();
// function name has precedence
--- 208,212 ----
void pyobj::m_set(int argc,const t_atom *argv)
{
! ThrState state = PyLockSys();
// function name has precedence
***************
*** 242,246 ****
{
post("");
! post("%s %s - python script object, (C)2002-2006 Thomas Grill",thisName(),PY__VERSION);
#ifdef FLEXT_DEBUG
post("DEBUG VERSION, compiled on " __DATE__ " " __TIME__);
--- 242,246 ----
{
post("");
! post("%s %s - python script object, (C)2002-2007 Thomas Grill",thisName(),PY__VERSION);
#ifdef FLEXT_DEBUG
post("DEBUG VERSION, compiled on " __DATE__ " " __TIME__);
***************
*** 347,351 ****
return flext_base::CbMethodResort(n,s,argc,argv);
! PyThreadState *state = PyLockSys();
bool ret = false;
--- 347,351 ----
return flext_base::CbMethodResort(n,s,argc,argv);
! ThrState state = PyLockSys();
bool ret = false;
Index: pysymbol.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pysymbol.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** pysymbol.h 26 Sep 2005 13:59:59 -0000 1.4
--- pysymbol.h 7 Mar 2007 13:40:14 -0000 1.5
***************
*** 1,54 ****
! /*
!
! py/pyext - python script object for PD and Max/MSP
!
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
! #ifndef __PYSYMBOL_H
! #define __PYSYMBOL_H
!
! #include <flext.h>
!
! #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 500)
! #error You need at least flext version 0.5.0
! #endif
!
! #if FLEXT_OS == FLEXT_OS_MAC
! #include <Python/Python.h>
! #else
! #include <Python.h>
! #endif
!
!
! #ifdef _MSC_VER
! #ifdef PY_EXPORTS
! #define PY_EXPORT __declspec(dllexport)
! #else
! #define PY_EXPORT __declspec(dllimport)
! #endif
! #else
! #define PY_EXPORT
! #endif
!
! typedef struct {
! PyObject_HEAD
! /* Type-specific fields go here. */
! const t_symbol *sym;
! } pySymbol;
!
! PY_EXPORT extern PyTypeObject pySymbol_Type;
!
! PY_EXPORT extern pySymbol *pySymbol__;
! PY_EXPORT extern pySymbol *pySymbol_bang;
! PY_EXPORT extern pySymbol *pySymbol_list;
! PY_EXPORT extern pySymbol *pySymbol_symbol;
! PY_EXPORT extern pySymbol *pySymbol_float;
! PY_EXPORT extern pySymbol *pySymbol_int;
!
!
#define pySymbol_Check(op) PyObject_TypeCheck(op, &pySymbol_Type)
#define pySymbol_CheckExact(op) ((op)->ob_type == &pySymbol_Type)
--- 1,54 ----
! /*
!
! py/pyext - python script object for PD and Max/MSP
!
! Copyright (c)2002-2005 Thomas Grill (gr(a)grrrr.org)
! For information on usage and redistribution, and for a DISCLAIMER OF ALL
! WARRANTIES, see the file, "license.txt," in this distribution.
!
! */
!
! #ifndef __PYSYMBOL_H
! #define __PYSYMBOL_H
!
! #include <flext.h>
!
! #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 500)
! #error You need at least flext version 0.5.0
! #endif
!
! #if FLEXT_OS == FLEXT_OS_MAC
! #include <Python/Python.h>
! #else
! #include <Python.h>
! #endif
!
!
! #ifdef _MSC_VER
! #ifdef PY_EXPORTS
! #define PY_EXPORT __declspec(dllexport)
! #else
! #define PY_EXPORT __declspec(dllimport)
! #endif
! #else
! #define PY_EXPORT
! #endif
!
! typedef struct {
! PyObject_HEAD
! /* Type-specific fields go here. */
! const t_symbol *sym;
! } pySymbol;
!
! PY_EXPORT extern PyTypeObject pySymbol_Type;
!
! PY_EXPORT extern pySymbol *pySymbol__;
! PY_EXPORT extern pySymbol *pySymbol_bang;
! PY_EXPORT extern pySymbol *pySymbol_list;
! PY_EXPORT extern pySymbol *pySymbol_symbol;
! PY_EXPORT extern pySymbol *pySymbol_float;
! PY_EXPORT extern pySymbol *pySymbol_int;
!
!
#define pySymbol_Check(op) PyObject_TypeCheck(op, &pySymbol_Type)
#define pySymbol_CheckExact(op) ((op)->ob_type == &pySymbol_Type)
***************
*** 67,92 ****
}
! inline const t_symbol *pySymbol_AS_SYMBOL(PyObject *op)
! {
! return ((pySymbol *)op)->sym;
! }
!
! inline const t_symbol *pySymbol_AsSymbol(PyObject *op)
! {
! return pySymbol_Check(op)?pySymbol_AS_SYMBOL(op):NULL;
! }
!
! inline const char *pySymbol_AS_STRING(PyObject *op)
! {
! return flext::GetString(pySymbol_AS_SYMBOL(op));
! }
!
! inline const t_symbol *pyObject_AsSymbol(PyObject *op)
! {
! if(PyString_Check(op))
! return flext::MakeSymbol(PyString_AS_STRING(op));
! else
! return pySymbol_AsSymbol(op);
! }
!
! #endif
--- 67,92 ----
}
! inline const t_symbol *pySymbol_AS_SYMBOL(PyObject *op)
! {
! return ((pySymbol *)op)->sym;
! }
!
! inline const t_symbol *pySymbol_AsSymbol(PyObject *op)
! {
! return pySymbol_Check(op)?pySymbol_AS_SYMBOL(op):NULL;
! }
!
! inline const char *pySymbol_AS_STRING(PyObject *op)
! {
! return flext::GetString(pySymbol_AS_SYMBOL(op));
! }
!
! inline const t_symbol *pyObject_AsSymbol(PyObject *op)
! {
! if(PyString_Check(op))
! return flext::MakeSymbol(PyString_AS_STRING(op));
! else
! return pySymbol_AsSymbol(op);
! }
!
! #endif