aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/py/source
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2005-01-10 05:00:56 +0000
committerThomas Grill <xovo@users.sourceforge.net>2005-01-10 05:00:56 +0000
commit4651f8a117cd663ddd77355055b0580cce636da3 (patch)
tree155faf09847ac1a0c5d10f131053946ffcd0a8ab /externals/grill/py/source
parent97492d5628f603856df9a3dd2abd55d33918dc4f (diff)
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
Diffstat (limited to 'externals/grill/py/source')
-rw-r--r--externals/grill/py/source/main.cpp60
-rw-r--r--externals/grill/py/source/main.h14
-rw-r--r--externals/grill/py/source/py.cpp50
-rw-r--r--externals/grill/py/source/pyext.cpp56
4 files changed, 113 insertions, 67 deletions
diff --git a/externals/grill/py/source/main.cpp b/externals/grill/py/source/main.cpp
index 86b5dd38..636435b3 100644
--- a/externals/grill/py/source/main.cpp
+++ b/externals/grill/py/source/main.cpp
@@ -19,19 +19,20 @@ static PyMethodDef StdOut_Methods[] =
#ifdef FLEXT_THREADS
+
typedef std::map<flext::thrid_t,PyThreadState *> 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<char *>(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) {