From 897b80c5585f7c9031ff1aafb504c21a9d3b1606 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Fri, 8 Jul 2005 14:30:31 +0000 Subject: better reload handling, but still far fom perfect fixed minor other issues cleaned up float vs. int pyext tags simplifications in py and pyext bumped version number python-like dotted module.function syntax send and receive wrapped PyObjects through inlets/outlets multiply inlets for py (hot and cold inlets) svn path=/trunk/; revision=3308 --- externals/grill/py/source/pybase.h | 206 +++++++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 externals/grill/py/source/pybase.h (limited to 'externals/grill/py/source/pybase.h') diff --git a/externals/grill/py/source/pybase.h b/externals/grill/py/source/pybase.h new file mode 100644 index 00000000..ea5f6b49 --- /dev/null +++ b/externals/grill/py/source/pybase.h @@ -0,0 +1,206 @@ +/* + +py/pyext - python script object for PD and MaxMSP + +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 __PYBASE_H +#define __PYBASE_H + +#include "main.h" +#include "pysymbol.h" +#include "pybuffer.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 bool GetPyArgs(AtomList &lst,PyObject *pValue,int offs = 0); + static bool 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(t_canvas *cnv); + void GetModulePath(const char *mod,char *dir,int len); + void AddToPath(const char *dir); + 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); + + 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 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 + +#ifdef PY_NUMARRAY + static void setupNumarray(); + static PyObject *py_import(PyObject *,PyObject *args); + static PyObject *py_export(PyObject *,PyObject *args); +#endif + + // ----thread stuff ------------ + + virtual void m_stop(int argc,const t_atom *argv); + + bool respond; +#ifdef FLEXT_THREADS + bool shouldexit; + int thrcount; + int stoptick; + Timer stoptmr; + + void tick(void *); +#endif + + int detach; + bool xlate; + + bool gencall(PyObject *fun,PyObject *args); + virtual bool thrcall(void *data) = 0; + virtual bool callpy(PyObject *fun,PyObject *args) = 0; + +#if FLEXT_SYS == FLEXT_SYS_MAX + static short patcher_myvol(t_patcher *x); +#endif + + static bool collect(); + +protected: + + void work_wrapper(void *data); + +#ifdef FLEXT_THREADS + bool qucall(PyObject *fun,PyObject *args); + void threadworker(); + PyFifo qufifo; + ThrCond qucond; + static PyThreadState *pythrsys; + + static PyThreadState *FindThreadState(); + static void FreeThreadState(); +#else + static PyThreadState *FindThreadState() { return NULL; } +#endif + +public: + +#ifdef FLEXT_THREADS + ThrMutex mutex; + inline void Lock() { mutex.Unlock(); } + inline void Unlock() { mutex.Unlock(); } + + // 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 + inline void Lock() {} + inline void Unlock() {} + + 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 -- cgit v1.2.1