Update of /cvsroot/pure-data/externals/grill/py/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16348/source
Modified Files: pysymbol.cpp Added Files: pybundle.cpp pybundle.h Log Message: fixed rich comparison method in Symbol class added message bundle functionality (pyext.Bundle class) small optimizations and fixes added forgotten files
Index: pysymbol.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/py/source/pysymbol.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** pysymbol.cpp 12 Dec 2005 00:18:42 -0000 1.4 --- pysymbol.cpp 12 Dec 2005 13:55:28 -0000 1.5 *************** *** 62,74 **** if(pySymbol_Check(a) && pySymbol_Check(b)) { const t_symbol *asym = pySymbol_AS_SYMBOL(a); ! const t_symbol *bsym = pySymbol_AS_SYMBOL(a); bool ret; switch(cmp) { ! case Py_LT: ret = asym < bsym; ! case Py_LE: ret = asym <= bsym; ! case Py_EQ: ret = asym == bsym; ! case Py_NE: ret = asym != bsym; ! case Py_GT: ret = asym > bsym; ! case Py_GE: ret = asym >= bsym; } return PyBool_FromLong(ret); --- 62,74 ---- 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);
--- NEW FILE: pybundle.cpp --- /*
py/pyext - python script object for PD and Max/MSP
Copyright (c)2002-2005 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution.
*/
#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); }
--- NEW FILE: pybundle.h --- /*
py/pyext - python script object for PD and Max/MSP
Copyright (c)2002-2005 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution.
*/
#ifndef __PYBUNDLE_H #define __PYBUNDLE_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. */ 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