From 4651f8a117cd663ddd77355055b0580cce636da3 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Mon, 10 Jan 2005 05:00:56 +0000 Subject: closed multi-interpreter branch (no chance to have several interpreters in the same thread!) other thread-related cleanups py: added ability to choose function from message tag enabled int-tags for pyext class methods svn path=/trunk/; revision=2487 --- externals/grill/py/maxmsp/py-objectmappings.txt | 22 ++++----- externals/grill/py/pd/pak.pd | 20 ++++----- externals/grill/py/pd/script-1.pd | 2 +- externals/grill/py/py.vcproj | 14 ++++-- externals/grill/py/readme.txt | 2 + externals/grill/py/scripts/simple.py | 3 ++ externals/grill/py/scripts/threads.py | 2 +- externals/grill/py/source/main.cpp | 60 +++++++++++++++---------- externals/grill/py/source/main.h | 14 +++--- externals/grill/py/source/py.cpp | 50 ++++++++++++++------- externals/grill/py/source/pyext.cpp | 56 ++++++++++++++--------- 11 files changed, 151 insertions(+), 94 deletions(-) (limited to 'externals') diff --git a/externals/grill/py/maxmsp/py-objectmappings.txt b/externals/grill/py/maxmsp/py-objectmappings.txt index 6634810c..e7616537 100755 --- a/externals/grill/py/maxmsp/py-objectmappings.txt +++ b/externals/grill/py/maxmsp/py-objectmappings.txt @@ -1,11 +1,11 @@ -max objectfile py py; -max objectfile py. py; -max objectfile pyext py; -max objectfile pyext. py; -max objectfile pyx py; -max objectfile pyx. py; - -max oblist python py; -max oblist python py.; -max oblist python pyext; -max oblist python pyext.; +max objectfile py py; +max objectfile py. py; +max objectfile pyext py; +max objectfile pyext. py; +max objectfile pyx py; +max objectfile pyx. py; + +max oblist python py; +max oblist python py.; +max oblist python pyext; +max oblist python pyext.; diff --git a/externals/grill/py/pd/pak.pd b/externals/grill/py/pd/pak.pd index 99d0ac5b..139350a2 100644 --- a/externals/grill/py/pd/pak.pd +++ b/externals/grill/py/pd/pak.pd @@ -1,22 +1,22 @@ -#N canvas 463 293 278 228 12; +#N canvas 463 293 282 232 12; #X obj 17 32 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 10 --262144 -1 -1 18 256; +-262144 -1 -1 47 256; #X obj 34 52 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 10 --262144 -1 -1 11 256; +-262144 -1 -1 182 256; #X obj 56 68 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 10 --262144 -1 -1 13 256; +-262144 -1 -1 86 256; #X obj 68 88 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 10 --262144 -1 -1 21 256; +-262144 -1 -1 31 256; #X obj 118 29 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 -10 -262144 -1 -1 13 256; +10 -262144 -1 -1 117 256; #X obj 135 49 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 -10 -262144 -1 -1 13 256; +10 -262144 -1 -1 0 256; #X obj 157 65 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 -10 -262144 -1 -1 10 256; +10 -262144 -1 -1 86 256; #X obj 169 85 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 -10 -262144 -1 -1 11 256; +10 -262144 -1 -1 0 256; #X obj 36 168 print; -#X obj 37 129 pyx pak pak 8; +#X obj 37 129 pyx. pak 8; #X connect 0 0 9 1; #X connect 1 0 9 2; #X connect 2 0 9 3; diff --git a/externals/grill/py/pd/script-1.pd b/externals/grill/py/pd/script-1.pd index d0d7e5b2..39e3b27b 100644 --- a/externals/grill/py/pd/script-1.pd +++ b/externals/grill/py/pd/script-1.pd @@ -1,4 +1,4 @@ -#N canvas 297 17 680 522 12; +#N canvas 297 17 684 526 12; #X obj 39 278 print; #X obj 345 251 print; #X msg 499 149 freakhole; diff --git a/externals/grill/py/py.vcproj b/externals/grill/py/py.vcproj index c108f9a7..ed43729f 100644 --- a/externals/grill/py/py.vcproj +++ b/externals/grill/py/py.vcproj @@ -85,7 +85,7 @@ + RelativePath=".\build\config-win.def"> + RelativePath=".\config.txt"> + + + + PyThrMap; -static PyInterpreterState *pystate = NULL; +static PyInterpreterState *pymain = NULL; static PyThreadState *pythrmain = NULL; static PyThrMap pythrmap; -PyThreadState *FindThreadState() +PyThreadState *py::FindThreadState() { flext::thrid_t id = flext::GetThreadId(); PyThrMap::iterator it = pythrmap.find(id); if(it == pythrmap.end()) { // Make new thread state - PyThreadState *st = PyThreadState_New(pystate); + PyThreadState *st = PyThreadState_New(pymain); pythrmap[id] = st; return st; } @@ -39,7 +40,7 @@ PyThreadState *FindThreadState() return it->second; } -void FreeThreadState() +void py::FreeThreadState() { flext::thrid_t id = flext::GetThreadId(); PyThrMap::iterator it = pythrmap.find(id); @@ -58,15 +59,16 @@ void FreeThreadState() void py::lib_setup() { post(""); - post("--------------------------------------"); + post("------------------------------------------------"); post("py/pyext %s - python script objects",PY__VERSION); - post(" (C)2002-2005 Thomas Grill"); - post(" http://grrrr.org/ext"); + post("(C)2002-2005 Thomas Grill - http://grrrr.org/ext"); + post(""); + post("using Python %s",Py_GetVersion()); #ifdef FLEXT_DEBUG post(""); post("DEBUG version compiled on %s %s",__DATE__,__TIME__); #endif - post("--------------------------------------"); + post("------------------------------------------------"); post(""); // ------------------------------------------------------------- @@ -85,7 +87,7 @@ void py::lib_setup() // get thread state pythrmain = PyThreadState_Get(); // get main interpreter state - pystate = pythrmain->interp; + pymain = pythrmain->interp; // add thread state of main thread to map pythrmap[GetThreadId()] = pythrmain; @@ -104,15 +106,15 @@ void py::lib_setup() py_out = Py_InitModule("stderr", StdOut_Methods); PySys_SetObject("stderr", py_out); -#ifdef FLEXT_THREADS - // release global lock - PyEval_ReleaseLock(); -#endif - // ------------------------------------------------------------- FLEXT_SETUP(pyobj); FLEXT_SETUP(pyext); + +#ifdef FLEXT_THREADS + // release global lock + PyEval_ReleaseLock(); +#endif } FLEXT_LIB_SETUP(py,py::lib_setup) @@ -127,11 +129,9 @@ py::py(): detach(0),shouldexit(false),thrcount(0), stoptick(0) { -// interpreter = PyInterpreterState_New(); - PyThreadState *state = PyLock(); Py_INCREF(module_obj); - PyUnlock(state); + PyUnlock(state); FLEXT_ADDTIMER(stoptmr,tick); @@ -153,14 +153,10 @@ py::~py() while(thrcount) Sleep(0.2f); post("%s - Okay, all threads have terminated",thisName()); } - + + PyThreadState *state = PyLock(); Py_XDECREF(module_obj); -/* - PyEval_AcquireLock(); - PyInterpreterState_Clear(interpreter); - PyInterpreterState_Delete(interpreter); - PyEval_ReleaseLock(); -*/ + PyUnlock(state); } @@ -505,12 +501,28 @@ void py::threadworker() Py_XDECREF(fun); Py_XDECREF(args); } + PyUnlock(state); } +#if FLEXT_SYS == FLEXT_SYS_MAX +short py::patcher_myvol(t_patcher *x) +{ + t_box *w; + if (x->p_vol) + return x->p_vol; + else if (w = (t_box *)x->p_vnewobj) + return patcher_myvol(w->b_patcher); + else + return 0; +} +#endif + + Fifo::~Fifo() { FifoEl *el = head; + head = tail = NULL; // reset it, in case there's a thread wanting to Pop while(el) { FifoEl *n = el->nxt; delete el; diff --git a/externals/grill/py/source/main.h b/externals/grill/py/source/main.h index e953b319..03b67e1c 100644 --- a/externals/grill/py/source/main.h +++ b/externals/grill/py/source/main.h @@ -58,9 +58,6 @@ protected: }; -PyThreadState *FindThreadState(); -void FreeThreadState(); - class py: public flext_base { @@ -141,9 +138,11 @@ protected: bool gencall(PyObject *fun,PyObject *args); virtual bool callpy(PyObject *fun,PyObject *args) = 0; -private: -// PyInterpreterState *interpreter; +#if FLEXT_SYS == FLEXT_SYS_MAX + static short patcher_myvol(t_patcher *x); +#endif +private: bool qucall(PyObject *fun,PyObject *args); void threadworker(); Fifo qufifo; @@ -157,6 +156,11 @@ private: FLEXT_CALLBACK_X(work_wrapper) #endif +#ifdef FLEXT_THREADS + static PyThreadState *FindThreadState(); + static void FreeThreadState(); +#endif + public: #ifdef FLEXT_THREADS diff --git a/externals/grill/py/source/py.cpp b/externals/grill/py/source/py.cpp index 05aeea8d..3bad1890 100644 --- a/externals/grill/py/source/py.cpp +++ b/externals/grill/py/source/py.cpp @@ -25,7 +25,6 @@ protected: bool work(const t_symbol *s,int argc,const t_atom *argv); - void m_bang() { callwork(sym_bang,0,NULL); } void m_reload(); void m_reload_(int argc,const t_atom *argv); void m_set(int argc,const t_atom *argv); @@ -37,6 +36,7 @@ protected: // methods for python arguments void callwork(const t_symbol *s,int argc,const t_atom *argv); + void m_bang() { callwork(sym_bang,0,NULL); } void m_py_list(int argc,const t_atom *argv) { callwork(sym_list,argc,argv); } void m_py_float(int argc,const t_atom *argv) { callwork(sym_float,argc,argv); } void m_py_int(int argc,const t_atom *argv) { callwork(sym_int,argc,argv); } @@ -44,6 +44,7 @@ protected: const t_symbol *funname; PyObject *function; + bool withfunction; virtual void Reload(); @@ -102,7 +103,7 @@ void pyobj::Setup(t_classid c) } pyobj::pyobj(int argc,const t_atom *argv): - function(NULL),funname(NULL) + function(NULL),funname(NULL),withfunction(false) { PyThreadState *state = PyLock(); @@ -130,11 +131,9 @@ pyobj::pyobj(int argc,const t_atom *argv): // add current dir to path AddToPath(GetString(canvas_getcurrentdir())); #elif FLEXT_SYS == FLEXT_SYS_MAX -/* short path = patcher_myvol(thisCanvas()); path_topathname(path,NULL,dir); AddToPath(dir); -*/ #else #pragma message("Adding current dir to path is not implemented") #endif @@ -146,6 +145,8 @@ pyobj::pyobj(int argc,const t_atom *argv): Register("_py"); if(argc >= 2) { + withfunction = true; + // set function name if(!IsString(argv[1])) post("%s - function name argument is invalid",thisName()); @@ -154,6 +155,8 @@ pyobj::pyobj(int argc,const t_atom *argv): SetFunction(GetString(argv[1])); } } + else + withfunction = false; PyUnlock(state); } @@ -280,10 +283,13 @@ void pyobj::SetFunction(const char *func) { if(func) { funname = MakeSymbol(func); + withfunction = true; ResetFunction(); } - else + else { + withfunction = false; function = NULL,funname = NULL; + } } @@ -319,19 +325,29 @@ void pyobj::callwork(const t_symbol *s,int argc,const t_atom *argv) { bool ret = false; - if(function) { - PyThreadState *state = PyLock(); - - PyObject *pargs = MakePyArgs(s,argc,argv); - Py_INCREF(function); - ret = gencall(function,pargs); - - PyUnlock(state); + PyThreadState *state = PyLock(); + + if(withfunction) { + if(function) { + PyObject *pargs = MakePyArgs(s,argc,argv); + Py_INCREF(function); + ret = gencall(function,pargs); + } + else + post("%s: no valid function defined",thisName()); } - else { - post("%s: no function defined",thisName()); - ret = false; - } + else { + // no function defined as creation argument -> use message tag + PyObject *func = PyObject_GetAttrString(module,const_cast(GetString(s))); + if(func) { + PyObject *pargs = MakePyArgs(sym_list,argc,argv); + ret = gencall(func,pargs); + } + else + PyErr_Print(); + } + + PyUnlock(state); Respond(ret); } diff --git a/externals/grill/py/source/pyext.cpp b/externals/grill/py/source/pyext.cpp index f0fc25ba..fed6c89e 100644 --- a/externals/grill/py/source/pyext.cpp +++ b/externals/grill/py/source/pyext.cpp @@ -99,20 +99,6 @@ void pyext::SetThis() } -#if FLEXT_SYS == FLEXT_SYS_MAX -static short patcher_myvol(t_patcher *x) -{ - t_box *w; - if (x->p_vol) - return x->p_vol; - else if (w = (t_box *)x->p_vnewobj) - return patcher_myvol(w->b_patcher); - else - return 0; -} -#endif - - PyObject *pyext::class_obj = NULL; PyObject *pyext::class_dict = NULL; @@ -509,14 +495,29 @@ bool pyext::work(int n,const t_symbol *s,int argc,const t_atom *argv) // should be enough... char str[256]; - { - // try tag/inlet + bool isfloat = s == sym_float && argc == 1; + + // if float equals an integer, try int_* method + if(isfloat && GetAFloat(argv[0]) == GetAInt(argv[0])) { + sprintf(str,"int_%i",n); + ret = call(str,0,NULL,1,argv); + } + + // try tag/inlet + if(!ret) { sprintf(str,"%s_%i",GetString(s),n); ret = call(str,0,NULL,argc,argv); } - if(!ret) { - // try anything/inlet + // try truncated int + if(!ret && isfloat) { + t_atom at; SetInt(at,GetAInt(argv[0])); + sprintf(str,"int_%i",n); + ret = call(str,0,NULL,1,&at); + } + + // try anything/inlet + if(!ret) { sprintf(str,"_anything_%i",n); if(s == sym_bang && !argc) { t_atom argv; @@ -526,12 +527,25 @@ bool pyext::work(int n,const t_symbol *s,int argc,const t_atom *argv) else ret = call(str,0,s,argc,argv); } - if(!ret) { - // try tag at any inlet + + // try int at any inlet + if(!ret && isfloat && GetAFloat(argv[0]) == GetAInt(argv[0])) { + ret = call("int_",0,NULL,1,argv); + } + + // try tag at any inlet + if(!ret) { sprintf(str,"%s_",GetString(s)); ret = call(str,n,NULL,argc,argv); } - if(!ret) { + + // try truncated int at any inlet + if(!ret && isfloat) { + t_atom at; SetInt(at,GetAInt(argv[0])); + ret = call("int_",0,NULL,1,&at); + } + + if(!ret) { // try anything at any inlet const char *str1 = "_anything_"; if(s == sym_bang && !argc) { -- cgit v1.2.1