aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2005-12-12 13:55:28 +0000
committerThomas Grill <xovo@users.sourceforge.net>2005-12-12 13:55:28 +0000
commitb85f70523233c6c12ab8be4f0af61c8ef8e01ce0 (patch)
tree3fd4a92b58219e86da7213a5741084e0114f53f1
parent671f1403cf5755638217c59d3dead2c113ed4d58 (diff)
fixed rich comparison method in Symbol class
added message bundle functionality (pyext.Bundle class) small optimizations and fixes added forgotten files svn path=/trunk/; revision=4197
-rw-r--r--externals/grill/py/package.txt4
-rw-r--r--externals/grill/py/source/pybundle.cpp232
-rw-r--r--externals/grill/py/source/pybundle.h60
-rw-r--r--externals/grill/py/source/pysymbol.cpp14
4 files changed, 301 insertions, 9 deletions
diff --git a/externals/grill/py/package.txt b/externals/grill/py/package.txt
index 5204b0a8..001023bf 100644
--- a/externals/grill/py/package.txt
+++ b/externals/grill/py/package.txt
@@ -10,7 +10,7 @@ SRCS= \
main.cpp \
py.cpp pyext.cpp modmeth.cpp clmeth.cpp \
register.cpp bound.cpp pyargs.cpp \
- pysymbol.cpp pybuffer.cpp pydsp.cpp \
+ pysymbol.cpp pybuffer.cpp pybundle.cpp pydsp.cpp \
pyatom.cpp pybase.cpp pymeth.cpp
-HDRS= pyprefix.h main.h pyext.h pysymbol.h pybuffer.h pyatom.h pybase.h
+HDRS= pyprefix.h main.h pyext.h pysymbol.h pybuffer.h pybundle.h pyatom.h pybase.h
diff --git a/externals/grill/py/source/pybundle.cpp b/externals/grill/py/source/pybundle.cpp
new file mode 100644
index 00000000..69f5d90c
--- /dev/null
+++ b/externals/grill/py/source/pybundle.cpp
@@ -0,0 +1,232 @@
+/*
+
+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);
+}
diff --git a/externals/grill/py/source/pybundle.h b/externals/grill/py/source/pybundle.h
new file mode 100644
index 00000000..5978cc38
--- /dev/null
+++ b/externals/grill/py/source/pybundle.h
@@ -0,0 +1,60 @@
+/*
+
+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
diff --git a/externals/grill/py/source/pysymbol.cpp b/externals/grill/py/source/pysymbol.cpp
index 502606af..b5c5b127 100644
--- a/externals/grill/py/source/pysymbol.cpp
+++ b/externals/grill/py/source/pysymbol.cpp
@@ -61,15 +61,15 @@ 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(a);
+ const t_symbol *bsym = pySymbol_AS_SYMBOL(b);
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;
+ 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);
}