diff options
Diffstat (limited to 'externals/grill/py/source/pybase.h')
-rw-r--r-- | externals/grill/py/source/pybase.h | 479 |
1 files changed, 251 insertions, 228 deletions
diff --git a/externals/grill/py/source/pybase.h b/externals/grill/py/source/pybase.h index b5cc8220..61518a2a 100644 --- a/externals/grill/py/source/pybase.h +++ b/externals/grill/py/source/pybase.h @@ -1,228 +1,251 @@ -/*
-
-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"
-#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
+/* + +py/pyext - python script object for PD and MaxMSP + +Copyright (c)2002-2007 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" +#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 |