aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/py/source/clmeth.cpp
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2002-10-22 23:16:30 +0000
committerThomas Grill <xovo@users.sourceforge.net>2002-10-22 23:16:30 +0000
commitc2645dc4003b1391aba9b387a79a66cff1e63d3e (patch)
tree1ea6dccb8011a8ff64efb7c2ecf9a22caad860b3 /externals/grill/py/source/clmeth.cpp
parentd62e56f4df9594f72ce501f5e19c974fd18e7295 (diff)
This commit was generated by cvs2svn to compensate for changes in r189,
which included commits to RCS files with non-trunk default branches. svn path=/trunk/; revision=190
Diffstat (limited to 'externals/grill/py/source/clmeth.cpp')
-rw-r--r--externals/grill/py/source/clmeth.cpp278
1 files changed, 278 insertions, 0 deletions
diff --git a/externals/grill/py/source/clmeth.cpp b/externals/grill/py/source/clmeth.cpp
new file mode 100644
index 00000000..0a30d1f7
--- /dev/null
+++ b/externals/grill/py/source/clmeth.cpp
@@ -0,0 +1,278 @@
+/*
+
+py/pyext - python external object for PD and MaxMSP
+
+Copyright (c) 2002 Thomas Grill (xovo@gmx.net)
+For information on usage and redistribution, and for a DISCLAIMER OF ALL
+WARRANTIES, see the file, "license.txt," in this distribution.
+
+*/
+
+#include "pyext.h"
+
+
+PyMethodDef pyext::meth_tbl[] =
+{
+ {"__init__", pyext::pyext__init__, METH_VARARGS, "Constructor"},
+ {"__del__", pyext::pyext__del__, METH_VARARGS, "Destructor"},
+
+ {"_outlet", pyext::pyext_outlet, METH_VARARGS,"Send message to outlet"},
+ {"_tocanvas", pyext::pyext_tocanvas, METH_VARARGS,"Send message to canvas" },
+
+ { "_bind", pyext::pyext_bind, METH_VARARGS,"Bind function to a receiving symbol" },
+ { "_unbind", pyext::pyext_unbind, METH_VARARGS,"Unbind function from a receiving symbol" },
+#ifdef FLEXT_THREADS
+ { "_detach", pyext::pyext_detach, METH_VARARGS,"Set detach flag for called methods" },
+ { "_stop", pyext::pyext_stop, METH_VARARGS,"Stop running threads" },
+#endif
+ {NULL, NULL, 0, NULL} /* Sentinel */
+};
+
+PyMethodDef pyext::attr_tbl[] =
+{
+ { "__setattr__", pyext::pyext_setattr, METH_VARARGS,"Set class attribute" },
+ { "__getattr__", pyext::pyext_getattr, METH_VARARGS,"Get class attribute" },
+ { NULL, NULL,0,NULL },
+};
+
+
+const C *pyext::pyext_doc =
+ "py/pyext - python external object for PD and MaxMSP, (C)2002 Thomas Grill\n"
+ "\n"
+ "This is the pyext base class. Available methods:\n"
+ "_outlet(self,ix,args...): Send a message to an indexed outlet\n"
+ "_tocanvas(self,args...): Send a message to the parent canvas\n"
+#ifdef FLEXT_THREADS
+ "_detach(self,int): Define whether a called Python method has its own thread\n"
+#endif
+ "_bind(self,name,func): Bind a python function to a symbol\n"
+ "_unbind(self,name,func): Unbind a python function from a symbol\n"
+;
+
+PyObject* pyext::pyext__init__(PyObject *,PyObject *args)
+{
+// post("pyext.__init__ called");
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyObject* pyext::pyext__del__(PyObject *,PyObject *args)
+{
+// post("pyext.__del__ called");
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyObject* pyext::pyext_setattr(PyObject *,PyObject *args)
+{
+ PyObject *self,*name,*val,*ret = NULL;
+ if(!PyArg_ParseTuple(args, "OOO:test_foo", &self,&name,&val)) {
+ // handle error
+ ERRINTERNAL();
+ return NULL;
+ }
+
+ BL handled = false;
+ if(PyString_Check(name)) {
+ char* sname = PyString_AsString(name);
+ if (sname) {
+// post("pyext::setattr %s",sname);
+ }
+ }
+
+ if(!handled) {
+ if(PyInstance_Check(self))
+ PyDict_SetItem(((PyInstanceObject *)self)->in_dict, name,val);
+ else
+ ERRINTERNAL();
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyObject* pyext::pyext_getattr(PyObject *,PyObject *args)
+{
+ PyObject *self,*name,*ret = NULL;
+ if(!PyArg_ParseTuple(args, "OO:test_foo", &self,&name)) {
+ // handle error
+ ERRINTERNAL();
+ }
+
+ if(PyString_Check(name)) {
+ char* sname = PyString_AsString(name);
+ if (sname) {
+ if(!strcmp(sname,"_shouldexit")) {
+ pyext *ext = GetThis(self);
+ if(ext)
+ ret = PyLong_FromLong(ext->shouldexit?1:0);
+ }
+// post("pyext::getattr %s",sname);
+ }
+ }
+
+ if(!ret) {
+#if PY_VERSION_HEX >= 0x02020000
+ ret = PyObject_GenericGetAttr(self,name);
+#else
+ if(PyInstance_Check(self))
+ ret = PyDict_GetItem(((PyInstanceObject *)self)->in_dict,name);
+#endif
+ }
+ return ret;
+}
+
+
+//! Send message to outlet
+PyObject *pyext::pyext_outlet(PyObject *,PyObject *args)
+{
+ BL ok = false;
+ if(PySequence_Check(args)) {
+ PyObject *self = PySequence_GetItem(args,0);
+ PyObject *outl = PySequence_GetItem(args,1);
+ if(
+ self && PyInstance_Check(self) &&
+ outl && PyInt_Check(outl)
+ ) {
+ pyext *ext = GetThis(self);
+
+ I sz = PySequence_Size(args);
+ PyObject *val;
+ BL tp = sz == 3 && PySequence_Check(PySequence_GetItem(args,2));
+
+ if(tp)
+ val = PySequence_GetItem(args,2); // borrowed
+ else
+ val = PySequence_GetSlice(args,2,sz); // new ref
+
+ AtomList *lst = GetPyArgs(val);
+ if(lst) {
+ I o = PyInt_AsLong(outl);
+ if(o >= 1 && o <= ext->Outlets()) {
+ // by using the queue there is no immediate call of the next object
+ // deadlock would occur if this was another py/pyext object!
+ if(lst->Count() && IsSymbol((*lst)[0]))
+ ext->ToQueueAnything(o-1,GetSymbol((*lst)[0]),lst->Count()-1,lst->Atoms()+1);
+ else
+ ext->ToQueueList(o-1,*lst);
+ }
+ else
+ post("pyext: outlet index out of range");
+
+ ok = true;
+ }
+ else
+ post("py/pyext - No data to send");
+ if(lst) delete lst;
+
+ if(!tp) Py_DECREF(val);
+ }
+ }
+
+ if(!ok) post("pyext - Syntax: _outlet(self,outlet,args...)");
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+
+#ifdef FLEXT_THREADS
+//! Detach threads
+PyObject *pyext::pyext_detach(PyObject *,PyObject *args)
+{
+ PyObject *self;
+ int val;
+ if(!PyArg_ParseTuple(args, "Oi:pyext_detach",&self,&val)) {
+ // handle error
+ post("pyext - Syntax: _detach(self,[0/1])");
+ }
+ else {
+ pyext *ext = GetThis(self);
+ ext->m_detach(val != 0);
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+//! Stop running threads
+PyObject *pyext::pyext_stop(PyObject *,PyObject *args)
+{
+ PyObject *self;
+ int val = -1;
+ if(!PyArg_ParseTuple(args, "O|i:pyext_stop",&self,&val)) {
+ // handle error
+ post("pyext - Syntax: _stop(self,{wait time}");
+ }
+ else {
+ pyext *ext = GetThis(self);
+ I cnt = 0;
+ t_atom at;
+ if(val >= 0) flext::SetInt(at,val);
+ ext->m_stop(cnt,&at);
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#endif
+
+//! Send message to canvas
+PyObject *pyext::pyext_tocanvas(PyObject *,PyObject *args)
+{
+ BL ok = false;
+ if(PySequence_Check(args)) {
+ PyObject *self = PySequence_GetItem(args,0);
+ if(self && PyInstance_Check(self)) {
+ pyext *ext = GetThis(self);
+
+#ifdef PD
+ I sz = PySequence_Size(args);
+ PyObject *val;
+ BL tp = sz == 2 && PySequence_Check(PyTuple_GetItem(args,1));
+
+ if(tp)
+ val = PySequence_GetItem(args,1); // borrowed
+ else
+ val = PySequence_GetSlice(args,1,sz); // new ref
+
+ AtomList *lst = GetPyArgs(val);
+ if(lst) {
+ t_glist *gl = ext->thisCanvas(); //canvas_getcurrent();
+ t_class **cl = (t_pd *)gl;
+ if(cl) {
+#ifdef PD
+ pd_forwardmess(cl,lst->Count(),lst->Atoms());
+#else
+ #pragma message ("Send is not implemented")
+#endif
+ }
+#ifdef _DEBUG
+ else
+ post("pyext - no parent canvas?!");
+#endif
+ ok = true;
+ }
+ else
+ post("py/pyext - No data to send");
+ if(lst) delete lst;
+
+ if(!tp) Py_DECREF(val);
+#else
+#pragma message ("Not implemented for MaxMSP")
+#endif
+ }
+ }
+
+ if(!ok) post("pyext - Syntax: _tocanvas(self,args...)");
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+