[PD-cvs] externals/grill/py/source pydsp.cpp,NONE,1.1 bound.cpp,1.14,1.15 clmeth.cpp,1.15,1.16 main.cpp,1.29,1.30 main.h,1.35,1.36 modmeth.cpp,1.16,1.17 py.cpp,1.19,1.20 pyargs.cpp,1.13,1.14 pybuffer.cpp,1.2,1.3 pyext.cpp,1.28,1.29 pyext.h,1.19,1.20 register.cpp,1.5,1.6

Thomas Grill xovo at users.sourceforge.net
Sun Mar 13 05:59:50 CET 2005


Update of /cvsroot/pure-data/externals/grill/py/source
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29887/source

Modified Files:
	bound.cpp clmeth.cpp main.cpp main.h modmeth.cpp py.cpp 
	pyargs.cpp pybuffer.cpp pyext.cpp pyext.h register.cpp 
Added Files:
	pydsp.cpp 
Log Message:
pydsp: share dsp buffer objects at inplace operation
DSP support for py/pyext: new objects pyext~,pyx~,pyext.~,pyx.~
new base class for py and pyext classes
preset sys.argv for module loading
support for buffer objects (preliminary)
py: bang in left inlet now really triggers without arguments
fixes for detached operation and single-threaded version
little restructuring
adjust pd and py files for correct argument passing
more optimizations
update for new flext callback naming
use lock count instead of message queuing to avoid py->py messaging deadlock
pyext: fix for inlet count


Index: clmeth.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/clmeth.cpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -C2 -d -r1.15 -r1.16
*** clmeth.cpp	8 Mar 2005 04:59:23 -0000	1.15
--- clmeth.cpp	13 Mar 2005 04:59:47 -0000	1.16
***************
*** 30,33 ****
--- 30,36 ----
  #endif
  	{ "_isthreaded", pyext::pyext_isthreaded, METH_O,"Query whether threading is enabled" },
+ 
+ 	{ "_invec", pyext::pyext_invec, METH_VARARGS,"Get input vector" },
+ 	{ "_outvec", pyext::pyext_outvec, METH_VARARGS,"Get output vector" },
      {NULL, NULL, 0, NULL}        /* Sentinel */
  };
***************
*** 37,41 ****
  	{ "__setattr__", pyext::pyext_setattr, METH_VARARGS,"Set class attribute" },
  	{ "__getattr__", pyext::pyext_getattr, METH_VARARGS,"Get class attribute" },
! 	{ NULL, NULL,0,NULL },
  };
  
--- 40,44 ----
  	{ "__setattr__", pyext::pyext_setattr, METH_VARARGS,"Set class attribute" },
  	{ "__getattr__", pyext::pyext_getattr, METH_VARARGS,"Get class attribute" },
!     { NULL, NULL,0,NULL },
  };
  
***************
*** 175,178 ****
--- 178,184 ----
  			int o = PyInt_AsLong(outl);
  			if(o >= 1 && o <= ext->Outlets()) {
+                 // offset outlet by signal outlets
+                 o += ext->sigoutlets;
+ 
  				// by using the queue there is no immediate call of the next object
  				// deadlock would occur if this was another py/pyext object!
***************
*** 196,200 ****
  	}
  
! 	if(!ok)	post("pyext - Syntax: _outlet(self,outlet,args...)");
  
      Py_INCREF(Py_None);
--- 202,209 ----
  	}
  
!     if(!ok)	{
! 		PyErr_SetString(PyExc_SyntaxError,"pyext - Syntax: _outlet(self,outlet,args...)");
!         return NULL;
!     }
  
      Py_INCREF(Py_None);
***************
*** 212,216 ****
      if(!PyArg_ParseTuple(args, "Oi:pyext_detach",&self,&val)) {
          // handle error
! 		post("pyext - Syntax: _detach(self,[0/1])");
      }
  	else {
--- 221,226 ----
      if(!PyArg_ParseTuple(args, "Oi:pyext_detach",&self,&val)) {
          // handle error
! 		PyErr_SetString(PyExc_SyntaxError,"pyext - Syntax: _detach(self,[0/1])");
!         return NULL;
      }
  	else {
***************
*** 230,234 ****
      if(!PyArg_ParseTuple(args, "O|i:pyext_stop",&self,&val)) {
          // handle error
! 		post("pyext - Syntax: _stop(self,{wait time}");
      }
  	else {
--- 240,245 ----
      if(!PyArg_ParseTuple(args, "O|i:pyext_stop",&self,&val)) {
          // handle error
! 		PyErr_SetString(PyExc_SyntaxError,"pyext - Syntax: _stop(self,{wait time})");
!         return NULL;
      }
  	else {
***************
*** 306,310 ****
  	}
  
! 	if(!ok)	post("pyext - Syntax: _tocanvas(self,args...)");
  
      Py_INCREF(Py_None);
--- 317,324 ----
  	}
  
!     if(!ok)	{
! 		PyErr_SetString(PyExc_SyntaxError,"pyext - Syntax: _tocanvas(self,args...)");
!         return NULL;
!     }
  
      Py_INCREF(Py_None);
***************
*** 313,316 ****
--- 327,365 ----
  #endif
  
+ PyObject *pyext::pyext_invec(PyObject *,PyObject *args)
+ {
+ 	PyObject *self; 
+ 	int val = -1;
+     if(!PyArg_ParseTuple(args, "O|i:pyext_invec",&self,&val)) {
+         // handle error
+ 		PyErr_SetString(PyExc_SyntaxError,"pyext - Syntax: _invec(self,inlet)");
+         return NULL;
+     }
+ 	else {
+ 		pyext *ext = GetThis(self);
+         PyObject *b = ext->GetSig(val,true);
+         if(b) return b;
+ 	}
  
+     Py_INCREF(Py_None);
+     return Py_None;
+ }
  
+ PyObject *pyext::pyext_outvec(PyObject *,PyObject *args)
+ {
+ 	PyObject *self; 
+ 	int val = -1;
+     if(!PyArg_ParseTuple(args, "O|i:pyext_outvec",&self,&val)) {
+         // handle error
+ 		PyErr_SetString(PyExc_SyntaxError,"pyext - Syntax: _outvec(self,inlet)");
+         return NULL;
+     }
+ 	else {
+ 		pyext *ext = GetThis(self);
+         PyObject *b = ext->GetSig(val,false);
+         if(b) return b;
+ 	}
+ 
+     Py_INCREF(Py_None);
+     return Py_None;
+ }

Index: pyargs.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pyargs.cpp,v
retrieving revision 1.13
retrieving revision 1.14
diff -C2 -d -r1.13 -r1.14
*** pyargs.cpp	27 Feb 2005 04:57:47 -0000	1.13
--- pyargs.cpp	13 Mar 2005 04:59:47 -0000	1.14
***************
*** 30,34 ****
  }
  
! PyObject *py::MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,int inlet,bool withself)
  {
  	PyObject *pArgs;
--- 30,34 ----
  }
  
! PyObject *pybase::MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,int inlet,bool withself)
  {
  	PyObject *pArgs;
***************
*** 85,89 ****
  }
  
! flext::AtomList *py::GetPyArgs(PyObject *pValue,PyObject **self)
  {
  	if(pValue == NULL) return NULL; 
--- 85,89 ----
  }
  
! flext::AtomList *pybase::GetPyArgs(PyObject *pValue,PyObject **self)
  {
  	if(pValue == NULL) return NULL; 

Index: main.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/main.cpp,v
retrieving revision 1.29
retrieving revision 1.30
diff -C2 -d -r1.29 -r1.30
*** main.cpp	10 Mar 2005 04:59:00 -0000	1.29
--- main.cpp	13 Mar 2005 04:59:47 -0000	1.30
***************
*** 14,18 ****
  static PyMethodDef StdOut_Methods[] =
  {
! 	{ "write", py::StdOut_Write, 1 },
  	{ NULL,    NULL,           }  
  };
--- 14,18 ----
  static PyMethodDef StdOut_Methods[] =
  {
! 	{ "write", pybase::StdOut_Write, 1 },
  	{ NULL,    NULL,           }  
  };
***************
*** 28,34 ****
  static PyThrMap pythrmap;
  
! int py::lockcount = 0;
  
! PyThreadState *py::FindThreadState()
  {
      flext::thrid_t id = flext::GetThreadId();
--- 28,34 ----
  static PyThrMap pythrmap;
  
! int pybase::lockcount = 0;
  
! PyThreadState *pybase::FindThreadState()
  {
      flext::thrid_t id = flext::GetThreadId();
***************
*** 44,48 ****
  }
  
! void py::FreeThreadState()
  {
      flext::thrid_t id = flext::GetThreadId();
--- 44,48 ----
  }
  
! void pybase::FreeThreadState()
  {
      flext::thrid_t id = flext::GetThreadId();
***************
*** 60,67 ****
  
  
  void initsymbol();
  void initsamplebuffer();
  
! void py::lib_setup()
  {
  	post("");
--- 60,73 ----
  
  
+ PyObject *pybase::module_obj = NULL;
+ PyObject *pybase::module_dict = NULL;
+ 
+ PyObject *pybase::emptytuple = NULL;
+ 
+ 
  void initsymbol();
  void initsamplebuffer();
  
! void pybase::lib_setup()
  {
  	post("");
***************
*** 138,145 ****
--- 144,154 ----
      PyModule_AddObject(module_obj,"Buffer",(PyObject *)&pySamplebuffer_Type);
  
+     emptytuple = PyTuple_New(0);
+ 
  	// -------------------------------------------------------------
  
  	FLEXT_SETUP(pyobj);
  	FLEXT_SETUP(pyext);
+ 	FLEXT_DSP_SETUP(pydsp);
  
  #ifdef FLEXT_THREADS
***************
*** 152,173 ****
  }
  
! FLEXT_LIB_SETUP(py,py::lib_setup)
! 
! 
! PyObject *py::module_obj = NULL;
! PyObject *py::module_dict = NULL;
! 
  
- void py::Setup(t_classid c)
- {
- 	FLEXT_CADDMETHOD_(c,0,"doc",m_doc);
- 	FLEXT_CADDMETHOD_(c,0,"dir",m_dir);
- #ifdef FLEXT_THREADS
- 	FLEXT_CADDATTR_VAR1(c,"detach",detach);
- 	FLEXT_CADDMETHOD_(c,0,"stop",m_stop);
- #endif
- }
  
! py::py()
      : module(NULL),detach(0)
  #ifdef FLEXT_THREADS
--- 161,168 ----
  }
  
! FLEXT_LIB_SETUP(py,pybase::lib_setup)
  
  
! pybase::pybase()
      : module(NULL),detach(0)
  #ifdef FLEXT_THREADS
***************
*** 178,191 ****
  	Py_INCREF(module_obj);
      PyUnlock(state);
- 
- #ifdef FLEXT_THREADS
-     FLEXT_ADDTIMER(stoptmr,tick);
- 
-     // launch thread worker
-     FLEXT_CALLMETHOD(threadworker);
- #endif
  }
  
! py::~py()
  {
      PyThreadState *state = PyLock();
--- 173,179 ----
  	Py_INCREF(module_obj);
      PyUnlock(state);
  }
  
! pybase::~pybase()
  {
      PyThreadState *state = PyLock();
***************
*** 194,198 ****
  }
  
! void py::Exit()
  {
  #ifdef FLEXT_THREADS
--- 182,186 ----
  }
  
! void pybase::Exit()
  {
  #ifdef FLEXT_THREADS
***************
*** 205,218 ****
          if(thrcount) {
  		    // Wait forever
! 		    post("%s - Waiting for thread termination!",thisName());
  		    while(thrcount) Sleep(PY_STOP_TICK*0.001f);
! 		    post("%s - Okay, all threads have terminated",thisName());
          }
  	}
  #endif
-     flext_base::Exit();
  }
  
! void py::GetDir(PyObject *obj,AtomList &lst)
  {
      if(obj) {
--- 193,205 ----
          if(thrcount) {
  		    // Wait forever
! 		    post("py/pyext - Waiting for thread termination!");
  		    while(thrcount) Sleep(PY_STOP_TICK*0.001f);
! 		    post("py/pyext - Okay, all threads have terminated");
          }
  	}
  #endif
  }
  
! void pybase::GetDir(PyObject *obj,AtomList &lst)
  {
      if(obj) {
***************
*** 228,232 ****
              }
              else
!                 post("%s - %s: List could not be created",thisName(),GetString(thisTag()));
              Py_DECREF(pvar);
          }
--- 215,219 ----
              }
              else
!                 post("py/pyext - Argument list could not be created");
              Py_DECREF(pvar);
          }
***************
*** 236,248 ****
  }
  
! void py::m__dir(PyObject *obj)
  {
      AtomList lst;
      GetDir(obj,lst);
      // dump dir to attribute outlet
!     ToOutAnything(GetOutAttr(),thisTag(),lst.Count(),lst.Atoms());
  }
  
! void py::m__doc(PyObject *obj)
  {
      if(obj) {
--- 223,235 ----
  }
  
! void pybase::m__dir(PyObject *obj)
  {
      AtomList lst;
      GetDir(obj,lst);
      // dump dir to attribute outlet
!     DumpOut(NULL,lst.Count(),lst.Atoms());
  }
  
! void pybase::m__doc(PyObject *obj)
  {
      if(obj) {
***************
*** 280,289 ****
  }
  
! void py::m_click()
  {
      // this should once open the editor....
  }
  
! void py::SetArgs(int argc,const t_atom *argv)
  {
  	// script arguments
--- 267,276 ----
  }
  
! void pybase::OpenEditor()
  {
      // this should once open the editor....
  }
  
! void pybase::SetArgs(int argc,const t_atom *argv)
  {
  	// script arguments
***************
*** 292,296 ****
  		sargv[i] = new char[256];
  		if(!i) 
! 			strcpy(sargv[i],thisName());
  		else
  			GetAString(argv[i-1],sargv[i],255);
--- 279,283 ----
  		sargv[i] = new char[256];
  		if(!i) 
! 			strcpy(sargv[i],"py/pyext");
  		else
  			GetAString(argv[i-1],sargv[i],255);
***************
*** 304,308 ****
  }
  
! void py::ImportModule(const char *name)
  {
  	if(!name) return;
--- 291,295 ----
  }
  
! void pybase::ImportModule(const char *name)
  {
  	if(!name) return;
***************
*** 317,321 ****
  }
  
! void py::UnimportModule()
  {
  	if(!module) return;
--- 304,308 ----
  }
  
! void pybase::UnimportModule()
  {
  	if(!module) return;
***************
*** 333,337 ****
  }
  
! void py::ReloadModule()
  {
  	if(module) {
--- 320,324 ----
  }
  
! void pybase::ReloadModule()
  {
  	if(module) {
***************
*** 349,356 ****
  	}
  	else 
! 		post("%s - No module to reload",thisName());
  }
  
! void py::GetModulePath(const char *mod,char *dir,int len)
  {
  #if FLEXT_SYS == FLEXT_SYS_PD
--- 336,343 ----
  	}
  	else 
! 		post("py/pyext - No module to reload");
  }
  
! void pybase::GetModulePath(const char *mod,char *dir,int len)
  {
  #if FLEXT_SYS == FLEXT_SYS_PD
***************
*** 395,399 ****
  }
  
! void py::AddToPath(const char *dir)
  {
  	if(dir && *dir) {
--- 382,386 ----
  }
  
! void pybase::AddToPath(const char *dir)
  {
  	if(dir && *dir) {
***************
*** 411,420 ****
  static const t_symbol *sym_response = flext::MakeSymbol("response");
  
! void py::Respond(bool b) 
  { 
      if(respond) { 
          t_atom a; 
          SetBool(a,b); 
!         ToOutAnything(GetOutAttr(),sym_response,1,&a); 
      } 
  }
--- 398,407 ----
  static const t_symbol *sym_response = flext::MakeSymbol("response");
  
! void pybase::Respond(bool b) 
  { 
      if(respond) { 
          t_atom a; 
          SetBool(a,b); 
!         DumpOut(sym_response,1,&a); 
      } 
  }
***************
*** 425,429 ****
  
  // post to the console
! PyObject* py::StdOut_Write(PyObject* self, PyObject* args)
  {
      // should always be a tuple
--- 412,416 ----
  
  // post to the console
! PyObject* pybase::StdOut_Write(PyObject* self, PyObject* args)
  {
      // should always be a tuple
***************
*** 476,480 ****
  };
  
! bool py::gencall(PyObject *pmeth,PyObject *pargs)
  {
  	bool ret = false;
--- 463,467 ----
  };
  
! bool pybase::gencall(PyObject *pmeth,PyObject *pargs)
  {
  	bool ret = false;
***************
*** 495,510 ****
              // each call a new thread
              if(!shouldexit) {
! 			    ret = FLEXT_CALLMETHOD_X(work_wrapper,new work_data(pmeth,pargs));
! 			    if(!ret) post("%s - Failed to launch thread!",thisName());
  		    }
              break;
  #endif
          default:
!             post("%s - Unknown detach mode",thisName());
      }
      return ret;
  }
  
! void py::work_wrapper(void *data)
  {
      FLEXT_ASSERT(data);
--- 482,497 ----
              // each call a new thread
              if(!shouldexit) {
! 			    ret = thrcall(new work_data(pmeth,pargs));
! 			    if(!ret) post("py/pyext - Failed to launch thread!");
  		    }
              break;
  #endif
          default:
!             post("py/pyext - Unknown detach mode");
      }
      return ret;
  }
  
! void pybase::work_wrapper(void *data)
  {
      FLEXT_ASSERT(data);
***************
*** 529,533 ****
  
  #ifdef FLEXT_THREADS
! bool py::qucall(PyObject *fun,PyObject *args)
  {
      FifoEl *el = qufifo.New();
--- 516,520 ----
  
  #ifdef FLEXT_THREADS
! bool pybase::qucall(PyObject *fun,PyObject *args)
  {
      FifoEl *el = qufifo.New();
***************
*** 538,542 ****
  }
  
! void py::threadworker()
  {
      FifoEl *el;
--- 525,529 ----
  }
  
! void pybase::threadworker()
  {
      FifoEl *el;
***************
*** 574,578 ****
  
  #if FLEXT_SYS == FLEXT_SYS_MAX
! short py::patcher_myvol(t_patcher *x)
  {
      t_box *w;
--- 561,565 ----
  
  #if FLEXT_SYS == FLEXT_SYS_MAX
! short pybase::patcher_myvol(t_patcher *x)
  {
      t_box *w;
***************
*** 586,595 ****
  #endif
  
! bool py::collect()
  {
      if(gcollect) {
!         PyObject *args = PyTuple_New(0);
!         PyObject *ret = PyObject_Call(gcollect,args,NULL);
!         Py_DECREF(args);
          if(ret) {
  #ifdef FLEXT_DEBUG
--- 573,582 ----
  #endif
  
! bool pybase::collect()
  {
      if(gcollect) {
!         Py_INCREF(emptytuple);
!         PyObject *ret = PyObject_Call(gcollect,emptytuple,NULL);
!         Py_DECREF(emptytuple);
          if(ret) {
  #ifdef FLEXT_DEBUG

Index: pyext.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pyext.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -C2 -d -r1.19 -r1.20
*** pyext.h	11 Jan 2005 04:59:27 -0000	1.19
--- pyext.h	13 Mar 2005 04:59:47 -0000	1.20
***************
*** 14,25 ****
  #include "main.h"
  
! class pyext:
! 	public py
  {
! 	FLEXT_HEADER_S(pyext,py,Setup)
  
  public:
! 	pyext(int argc,const t_atom *argv);
! 	~pyext();
  
  	static PyObject *pyext__doc__(PyObject *,PyObject *args);
--- 14,25 ----
  #include "main.h"
  
! class pyext
!     : public pybase
!     , public flext_dsp
  {
! 	FLEXT_HEADER_S(pyext,flext_dsp,Setup)
  
  public:
! 	pyext(int argc,const t_atom *argv,bool sig = false);
  
  	static PyObject *pyext__doc__(PyObject *,PyObject *args);
***************
*** 39,50 ****
  	static PyObject *pyext_isthreaded(PyObject *,PyObject *);
  
  	int Inlets() const { return inlets; }
  	int Outlets() const { return outlets; }
  
  protected:
! 	virtual bool m_method_(int n,const t_symbol *s,int argc,const t_atom *argv);
  
  	bool work(int n,const t_symbol *s,int argc,const t_atom *argv); 
  
  	void m_reload();
  	void m_reload_(int argc,const t_atom *argv);
--- 39,65 ----
  	static PyObject *pyext_isthreaded(PyObject *,PyObject *);
  
+ 	static PyObject *pyext_inbuf(PyObject *,PyObject *args);
+ 	static PyObject *pyext_invec(PyObject *,PyObject *args);
+ 	static PyObject *pyext_outbuf(PyObject *,PyObject *args);
+ 	static PyObject *pyext_outvec(PyObject *,PyObject *args);
+ 
  	int Inlets() const { return inlets; }
  	int Outlets() const { return outlets; }
  
  protected:
! 
!     virtual bool Init();
!     virtual void Exit();
! 
!     virtual bool CbMethodResort(int n,const t_symbol *s,int argc,const t_atom *argv);
!     virtual void CbClick();
!     virtual bool CbDsp();
! 
!     virtual void DumpOut(const t_symbol *sym,int argc,const t_atom *argv);
  
  	bool work(int n,const t_symbol *s,int argc,const t_atom *argv); 
  
+     void m_help();
+ 
  	void m_reload();
  	void m_reload_(int argc,const t_atom *argv);
***************
*** 53,57 ****
      void mg_dir_(AtomList &lst) { GetDir(pyobj,lst); }
      void m_doc_() { m__doc(((PyInstanceObject *)pyobj)->in_class->cl_dict); }
- 	virtual void m_help();
  
  	void m_get(const t_symbol *s);
--- 68,71 ----
***************
*** 61,81 ****
  	PyObject *pyobj;
  	int inlets,outlets;
  
  private:
  	static void Setup(t_classid);
  
- 	static pyext *GetThis(PyObject *self);
  	void SetThis();
  
  	void ClearBinding();
  	bool MakeInstance();
- 	bool DoInit();
- 	void DoExit();
      void InitInOut(int &inlets,int &outlets);
  
  	AtomList args;
  
- 	virtual void Reload();
- 
  	static PyObject *class_obj,*class_dict;
  	static PyMethodDef attr_tbl[],meth_tbl[];
--- 75,99 ----
  	PyObject *pyobj;
  	int inlets,outlets;
+     int siginlets,sigoutlets;
+ 
+ 	virtual void Reload();
+ 	virtual bool DoInit();
+ 	virtual void DoExit();
+ 
+     virtual PyObject *GetSig(int ix,bool in);
+ 
+ 	static pyext *GetThis(PyObject *self);
  
  private:
  	static void Setup(t_classid);
  
  	void SetThis();
  
  	void ClearBinding();
  	bool MakeInstance();
      void InitInOut(int &inlets,int &outlets);
  
  	AtomList args;
  
  	static PyObject *class_obj,*class_dict;
  	static PyMethodDef attr_tbl[],meth_tbl[];
***************
*** 90,93 ****
--- 108,112 ----
  	bool call(const char *meth,int inlet,const t_symbol *s,int argc,const t_atom *argv);
  
+     virtual bool thrcall(void *data);
      virtual bool callpy(PyObject *fun,PyObject *args);
      static bool stcallpy(PyObject *fun,PyObject *args);
***************
*** 97,101 ****
  private:
      static bool boundmeth(flext_base *,t_symbol *sym,int argc,t_atom *argv,void *data);
!     
      FLEXT_CALLBACK(m_reload)
  	FLEXT_CALLBACK_V(m_reload_)
--- 116,122 ----
  private:
      static bool boundmeth(flext_base *,t_symbol *sym,int argc,t_atom *argv,void *data);
! 
!     FLEXT_CALLBACK(m_help)
! 
      FLEXT_CALLBACK(m_reload)
  	FLEXT_CALLBACK_V(m_reload_)
***************
*** 109,112 ****
--- 130,149 ----
  	FLEXT_CALLBACK_S(m_get)
  	FLEXT_CALLBACK_V(m_set)
+ 
+ 	// callbacks
+ 	FLEXT_ATTRVAR_I(detach)
+ 	FLEXT_ATTRVAR_B(respond)
+ 	FLEXT_CALLBACK_V(m_stop)
+ 	FLEXT_CALLBACK(m_dir)
+ 	FLEXT_CALLGET_V(mg_dir)
+ 	FLEXT_CALLBACK(m_doc)
+ 
+ #ifdef FLEXT_THREADS
+     FLEXT_CALLBACK_T(tick)
+     FLEXT_THREAD(threadworker)
+ 	FLEXT_THREAD_X(work_wrapper)
+ #else
+ 	FLEXT_CALLBACK_X(work_wrapper)
+ #endif
  };
  

Index: modmeth.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/modmeth.cpp,v
retrieving revision 1.16
retrieving revision 1.17
diff -C2 -d -r1.16 -r1.17
*** modmeth.cpp	9 Mar 2005 04:58:11 -0000	1.16
--- modmeth.cpp	13 Mar 2005 04:59:47 -0000	1.17
***************
*** 13,34 ****
  
  // function table for module
! PyMethodDef py::func_tbl[] = 
  {
! 	{ "_send", py::py_send, METH_VARARGS,"Send message to a named object" },
  #ifdef FLEXT_THREADS
! 	{ "_priority", py::py_priority, METH_VARARGS,"Set priority of current thread" },
  #endif
  
! 	{ "_samplerate", py::py_samplerate, METH_NOARGS,"Get system sample rate" },
! 	{ "_blocksize", py::py_blocksize, METH_NOARGS,"Get system block size" },
  
  #if FLEXT_SYS == FLEXT_SYS_PD
! 	{ "_getvalue", py::py_getvalue, METH_VARARGS,"Get value of a 'value' object" },
! 	{ "_setvalue", py::py_setvalue, METH_VARARGS,"Set value of a 'value' object" },
  #endif
  	{NULL, NULL, 0, NULL} // sentinel
  };
  
! const char *py::py_doc =
  	"py/pyext - python external object for PD and Max/MSP, (C)2002-2005 Thomas Grill\n"
  	"\n"
--- 13,34 ----
  
  // function table for module
! PyMethodDef pybase::func_tbl[] = 
  {
! 	{ "_send", pybase::py_send, METH_VARARGS,"Send message to a named object" },
  #ifdef FLEXT_THREADS
! 	{ "_priority", pybase::py_priority, METH_VARARGS,"Set priority of current thread" },
  #endif
  
! 	{ "_samplerate", pybase::py_samplerate, METH_NOARGS,"Get system sample rate" },
! 	{ "_blocksize", pybase::py_blocksize, METH_NOARGS,"Get system block size" },
  
  #if FLEXT_SYS == FLEXT_SYS_PD
! 	{ "_getvalue", pybase::py_getvalue, METH_VARARGS,"Get value of a 'value' object" },
! 	{ "_setvalue", pybase::py_setvalue, METH_VARARGS,"Set value of a 'value' object" },
  #endif
  	{NULL, NULL, 0, NULL} // sentinel
  };
  
! const char *pybase::py_doc =
  	"py/pyext - python external object for PD and Max/MSP, (C)2002-2005 Thomas Grill\n"
  	"\n"
***************
*** 46,50 ****
  
  #ifdef FLEXT_THREADS
! void py::tick(void *)
  {
  	Lock();
--- 46,50 ----
  
  #ifdef FLEXT_THREADS
! void pybase::tick(void *)
  {
  	Lock();
***************
*** 58,62 ****
  		// still active threads 
  		if(!--stoptick) {
! 			post("%s - Threads couldn't be stopped entirely - %i remaining",thisName(),thrcount);
  			shouldexit = false;
  		}
--- 58,62 ----
  		// still active threads 
  		if(!--stoptick) {
! 			post("py/pyext - Threads couldn't be stopped entirely - %i remaining",thrcount);
  			shouldexit = false;
  		}
***************
*** 70,74 ****
  #endif
  
! void py::m_stop(int argc,const t_atom *argv)
  {
  #ifdef FLEXT_THREADS
--- 70,74 ----
  #endif
  
! void pybase::m_stop(int argc,const t_atom *argv)
  {
  #ifdef FLEXT_THREADS
***************
*** 94,108 ****
  }
  
! PyObject *py::py_samplerate(PyObject *self,PyObject *args)
  {
  	return PyFloat_FromDouble(sys_getsr());
  }
  
! PyObject *py::py_blocksize(PyObject *self,PyObject *args)
  {
  	return PyLong_FromLong(sys_getblksize());
  }
  
! PyObject *py::py_send(PyObject *,PyObject *args)
  {
      // should always be a tuple
--- 94,108 ----
  }
  
! PyObject *pybase::py_samplerate(PyObject *self,PyObject *args)
  {
  	return PyFloat_FromDouble(sys_getsr());
  }
  
! PyObject *pybase::py_blocksize(PyObject *self,PyObject *args)
  {
  	return PyLong_FromLong(sys_getblksize());
  }
  
! PyObject *pybase::py_send(PyObject *,PyObject *args)
  {
      // should always be a tuple
***************
*** 154,158 ****
  
  #ifdef FLEXT_THREADS
! PyObject *py::py_priority(PyObject *self,PyObject *args)
  {
  	int val;
--- 154,158 ----
  
  #ifdef FLEXT_THREADS
! PyObject *pybase::py_priority(PyObject *self,PyObject *args)
  {
  	int val;
***************
*** 169,173 ****
  
  #if FLEXT_SYS == FLEXT_SYS_PD
! PyObject *py::py_getvalue(PyObject *self,PyObject *args)
  {
      FLEXT_ASSERT(PyTuple_Check(args));
--- 169,173 ----
  
  #if FLEXT_SYS == FLEXT_SYS_PD
! PyObject *pybase::py_getvalue(PyObject *self,PyObject *args)
  {
      FLEXT_ASSERT(PyTuple_Check(args));
***************
*** 196,200 ****
  }
  
! PyObject *py::py_setvalue(PyObject *self,PyObject *args)
  {
      FLEXT_ASSERT(PyTuple_Check(args));
--- 196,200 ----
  }
  
! PyObject *pybase::py_setvalue(PyObject *self,PyObject *args)
  {
      FLEXT_ASSERT(PyTuple_Check(args));

Index: bound.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/bound.cpp,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -d -r1.14 -r1.15
*** bound.cpp	11 Jan 2005 04:59:27 -0000	1.14
--- bound.cpp	13 Mar 2005 04:59:47 -0000	1.15
***************
*** 63,67 ****
  {
      bounddata *obj = (bounddata *)data;
!     py *pyth = static_cast<py *>(th);
  
  	PyThreadState *state = pyth->PyLock();
--- 63,67 ----
  {
      bounddata *obj = (bounddata *)data;
!     pyext *pyth = static_cast<pyext *>(th);
  
  	PyThreadState *state = pyth->PyLock();
***************
*** 93,97 ****
      }
  	else {
!         py *th = GetThis(self);
          FLEXT_ASSERT(th);
  
--- 93,97 ----
      }
  	else {
!         pyext *th = GetThis(self);
          FLEXT_ASSERT(th);
  
***************
*** 135,139 ****
      }
  	else {
!         py *th = GetThis(self);
          FLEXT_ASSERT(th);
  
--- 135,139 ----
      }
  	else {
!         pyext *th = GetThis(self);
          FLEXT_ASSERT(th);
  

Index: pyext.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pyext.cpp,v
retrieving revision 1.28
retrieving revision 1.29
diff -C2 -d -r1.28 -r1.29
*** pyext.cpp	27 Feb 2005 04:57:47 -0000	1.28
--- pyext.cpp	13 Mar 2005 04:59:47 -0000	1.29
***************
*** 21,24 ****
--- 21,33 ----
      sym_get = flext::MakeSymbol("get");
      
+ 	FLEXT_CADDMETHOD_(c,0,"doc",m_doc);
+ 	FLEXT_CADDMETHOD_(c,0,"dir",m_dir);
+ #ifdef FLEXT_THREADS
+ 	FLEXT_CADDATTR_VAR1(c,"detach",detach);
+ 	FLEXT_CADDMETHOD_(c,0,"stop",m_stop);
+ #endif
+ 
+ 	FLEXT_CADDMETHOD_(c,0,"help",m_help);
+ 
  	FLEXT_CADDMETHOD_(c,0,"reload",m_reload_);
      FLEXT_CADDMETHOD_(c,0,"reload.",m_reload);
***************
*** 96,106 ****
  PyObject *pyext::class_dict = NULL;
  
! pyext::pyext(int argc,const t_atom *argv):
  	pyobj(NULL),pythr(NULL),
  	inlets(-1),outlets(-1),
  	methname(NULL)
  { 
!     int apre = 0;
  
      if(argc >= apre+2 && CanbeInt(argv[apre]) && CanbeInt(argv[apre+1])) {
          inlets = GetAInt(argv[apre]);
--- 105,121 ----
  PyObject *pyext::class_dict = NULL;
  
! pyext::pyext(int argc,const t_atom *argv,bool sig):
  	pyobj(NULL),pythr(NULL),
  	inlets(-1),outlets(-1),
+     siginlets(0),sigoutlets(0),
  	methname(NULL)
  { 
! #ifdef FLEXT_THREADS
!     FLEXT_ADDTIMER(stoptmr,tick);
!     // launch thread worker
!     FLEXT_CALLMETHOD(threadworker);
! #endif
  
+     int apre = 0;
      if(argc >= apre+2 && CanbeInt(argv[apre]) && CanbeInt(argv[apre+1])) {
          inlets = GetAInt(argv[apre]);
***************
*** 109,112 ****
--- 124,133 ----
      }
  
+     if(sig && argc >= apre+2 && CanbeInt(argv[apre]) && CanbeInt(argv[apre+1])) {
+         siginlets = GetAInt(argv[apre]);
+         sigoutlets = GetAInt(argv[apre+1]);
+         apre += 2;
+     }
+ 
      const t_atom *clname = NULL;
  
***************
*** 163,198 ****
  	if(argc > apre) args(argc-apre,argv+apre);
  
  	if(methname) {
  		MakeInstance();
! 
!         if(pyobj) 
!             InitInOut(inlets,outlets);
  	}
!     else 
          inlets = outlets = 0;
  
- 	PyUnlock(state);
- 	
      if(inlets < 0 || outlets < 0)
          InitProblem();
      else {
!     	AddInAnything(1+inlets);  
  	    AddOutAnything(outlets);  
      }
  
! 	if(!pyobj)
! 		InitProblem();
  }
  
! pyext::~pyext()
! {
! 	PyThreadState *state = PyLock();
  
      DoExit();
- 
      Unregister("_pyext");
  	UnimportModule();
  
  	PyUnlock(state);
  }
  
--- 184,227 ----
  	if(argc > apre) args(argc-apre,argv+apre);
  
+ 	PyUnlock(state);
+ }
+ 
+ bool pyext::Init()
+ {
+ 	PyThreadState *state = PyLock();
+ 
  	if(methname) {
  		MakeInstance();
!         if(pyobj) InitInOut(inlets,outlets);
  	}
!     else
          inlets = outlets = 0;
  
      if(inlets < 0 || outlets < 0)
          InitProblem();
      else {
!    	    AddInSignal(siginlets);  
!         AddInAnything((siginlets?0:1)+inlets);  
!         AddOutSignal(sigoutlets);
  	    AddOutAnything(outlets);  
      }
  
! 	PyUnlock(state);
! 
!     return pyobj && flext_dsp::Init();
  }
  
! void pyext::Exit() 
! { 
!     pybase::Exit(); // exit threads
  
+ 	PyThreadState *state = PyLock();
      DoExit();
      Unregister("_pyext");
  	UnimportModule();
  
  	PyUnlock(state);
+ 
+     flext_dsp::Exit(); 
  }
  
***************
*** 231,241 ****
          PyObject *objdel = PyObject_GetAttrString(pyobj,"_del");
          if(objdel) {
!             PyObject *args = PyTuple_New(0);
!             PyObject *ret = PyObject_Call(objdel,args,NULL);
!             if(!ret)
!                 post("%s - Could not call _del method",thisName());
!             else 
                  Py_DECREF(ret);
!             Py_DECREF(args);
              Py_DECREF(objdel);
          }
--- 260,272 ----
          PyObject *objdel = PyObject_GetAttrString(pyobj,"_del");
          if(objdel) {
!             Py_INCREF(emptytuple);
!             PyObject *ret = PyObject_Call(objdel,emptytuple,NULL);
!             if(ret)
                  Py_DECREF(ret);
! #ifdef FLEXT_DEBUG
!             else 
!                 post("%s - Could not call _del method",thisName());
! #endif
!             Py_DECREF(emptytuple);
              Py_DECREF(objdel);
          }
***************
*** 270,274 ****
      if(inl < 0) {
  		// get number of inlets
! 		inl = 1;
  		PyObject *res = PyObject_GetAttrString(pyobj,"_inlets"); // get ref
  		if(res) {
--- 301,305 ----
      if(inl < 0) {
  		// get number of inlets
! 		inl = inlets;
  		PyObject *res = PyObject_GetAttrString(pyobj,"_inlets"); // get ref
  		if(res) {
***************
*** 287,291 ****
      if(outl < 0) {
          // get number of outlets
!         outl = 1;
  		PyObject *res = PyObject_GetAttrString(pyobj,"_outlets"); // get ref
  		if(res) {
--- 318,322 ----
      if(outl < 0) {
          // get number of outlets
!         outl = outlets;
  		PyObject *res = PyObject_GetAttrString(pyobj,"_outlets"); // get ref
  		if(res) {
***************
*** 437,448 ****
  
  
! bool pyext::m_method_(int n,const t_symbol *s,int argc,const t_atom *argv)
  {
-     bool ret = false;
  	if(pyobj && n >= 1)
! 		ret = work(n,s,argc,argv);
      else
! 		post("%s - no method for type '%s' into inlet %i",thisName(),GetString(s),n);
!     return ret;
  }
  
--- 468,477 ----
  
  
! bool pyext::CbMethodResort(int n,const t_symbol *s,int argc,const t_atom *argv)
  {
  	if(pyobj && n >= 1)
! 		return work(n,s,argc,argv);
      else
!         return flext_dsp::CbMethodResort(n,s,argc,argv);
  }
  
***************
*** 523,526 ****
--- 552,559 ----
      bool isfloat = s == sym_float && argc == 1;
  
+     // offset inlet index by signal inlets
+     // \note first one is shared with messages!
+     if(siginlets) n += siginlets-1;
+ 
  	// if float equals an integer, try int_* method
      if(isfloat && GetAFloat(argv[0]) == GetAInt(argv[0])) {
***************
*** 586,587 ****
--- 619,635 ----
  	return ret;
  }
+ 
+ PyObject *pyext::GetSig(int ix,bool in) { return NULL; }
+ 
+ void pyext::CbClick() { pybase::OpenEditor(); }
+ bool pyext::CbDsp() { return false; }
+ 
+ void pyext::DumpOut(const t_symbol *sym,int argc,const t_atom *argv)
+ {
+     ToOutAnything(GetOutAttr(),sym?sym:thisTag(),argc,argv);
+ }
+ 
+ bool pyext::thrcall(void *data)
+ { 
+     return FLEXT_CALLMETHOD_X(work_wrapper,data);
+ }

--- NEW FILE: pydsp.cpp ---
/* 

py/pyext - python script object for PD and Max/MSP

Copyright (c)2002-2005 Thomas Grill (gr at grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.  

*/

#include "pyext.h"

class pydsp
    : public pyext
{
	FLEXT_HEADER(pydsp,pyext)
public:
    pydsp(int argc,const t_atom *argv);

protected:
    virtual bool CbDsp();
    virtual void CbSignal();

    virtual bool DoInit();
    virtual void DoExit();

    virtual PyObject *GetSig(int ix,bool in);

    void NewBuffers(bool update = false);
    void FreeBuffers();

    PyObject *dspfun,*sigfun;
    PyObject **buffers;
};

FLEXT_LIB_DSP_V("pyext~ pyext.~ pyx~ pyx.~",pydsp)

pydsp::pydsp(int argc,const t_atom *argv)
    : pyext(argc,argv,true) 
    , dspfun(NULL),sigfun(NULL)
{}

bool pydsp::DoInit()
{
    if(!pyext::DoInit()) return false;
    
    if(pyobj) 
	{ 
        NewBuffers();

        dspfun = PyObject_GetAttrString(pyobj,"_dsp"); // get ref
	    if(dspfun && !PyMethod_Check(dspfun)) {
            Py_DECREF(dspfun);
		    dspfun = NULL;
	    }
        sigfun = PyObject_GetAttrString(pyobj,"_signal"); // get ref
	    if(sigfun && !PyMethod_Check(sigfun)) {
            Py_DECREF(sigfun);
		    sigfun = NULL;
	    }
	}
    return true;
}

void pydsp::DoExit()
{
    if(dspfun) { Py_DECREF(dspfun); dspfun = NULL; }
    if(sigfun) { Py_DECREF(sigfun); sigfun = NULL; }

    FreeBuffers();
}

PyObject *NAFromBuffer(PyObject *buf,int c,int n);

void pydsp::NewBuffers(bool update)
{
    int i,n = Blocksize();
    const int ins = CntInSig(),outs = CntOutSig();
    t_sample *const *insigs = InSig();
    t_sample *const *outsigs = OutSig();

    if(!buffers) {
        int cnt = ins+outs;
        if(cnt) {
            buffers = new PyObject *[cnt];
            memset(buffers,0,cnt*sizeof(*buffers));
        }
    }

    for(i = 0; i < ins; ++i) {
        if(update) Py_XDECREF(buffers[i]);
        PyObject *b = PyBuffer_FromReadWriteMemory(insigs[i],n*sizeof(t_sample));
        buffers[i] = NAFromBuffer(b,1,n);
        Py_DECREF(b);
    }
    for(i = 0; i < outs; ++i) {
        if(update) Py_XDECREF(buffers[ins+i]);
        if(i < ins && outsigs[i] == insigs[i]) {
            // same vectors - share the objects!
            buffers[ins+i] = buffers[i];
            Py_XINCREF(buffers[i]);
        }
        else {
            PyObject *b = PyBuffer_FromReadWriteMemory(outsigs[i],n*sizeof(t_sample));
            buffers[ins+i] = NAFromBuffer(b,1,n);
            Py_DECREF(b);
        }
    }
}

void pydsp::FreeBuffers()
{
    if(buffers) {
        int cnt = CntInSig()+CntOutSig();
        for(int i = 0; i < cnt; ++i) Py_XDECREF(buffers[i]);
        delete[] buffers;
        buffers = NULL;
    }
}

bool pydsp::CbDsp()
{
    if(CntInSig() || CntOutSig())
    {
        NewBuffers(true);

        if(dspfun) {
        	PyThreadState *state = PyLock();
//            Py_INCREF(emptytuple);
            PyObject *ret = PyObject_Call(dspfun,emptytuple,NULL);
//            Py_DECREF(emptytuple);
            if(ret)
                Py_DECREF(ret);
            else {
#ifdef FLEXT_DEBUG
                PyErr_Print();
#else
                PyErr_Clear();
#endif   
            }
            PyUnlock(state);
        }
        return true;
    }
    else
        // switch on dsp only if there are signal inlets or outlets
        return false;
}

void pydsp::CbSignal()
{
    if(sigfun) {
      	PyThreadState *state = PyLock();
//        Py_INCREF(emptytuple);
        PyObject *ret = PyObject_Call(sigfun,emptytuple,NULL);
//        Py_DECREF(emptytuple);

        if(ret) 
            Py_DECREF(ret);
        else {
#ifdef FLEXT_DEBUG
            PyErr_Print();
#else
            PyErr_Clear();
#endif   
        }
        PyUnlock(state);
    }
    else
        flext_dsp::CbSignal();
}

PyObject *pydsp::GetSig(int ix,bool in) 
{
    PyObject *r = buffers[in?ix:CntInSig()+ix];
    Py_XINCREF(r);
    return r;
}


Index: pybuffer.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/pybuffer.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** pybuffer.cpp	10 Mar 2005 04:59:00 -0000	1.2
--- pybuffer.cpp	13 Mar 2005 04:59:47 -0000	1.3
***************
*** 179,182 ****
--- 179,197 ----
  }
  
+ PyObject *NAFromBuffer(PyObject *buf,int c,int n)
+ {
+ #ifdef PY_NUMARRAY
+     if(nasupport) {
+         maybelong shape[2];
+         shape[0] = n;
+         shape[1] = c;
+         PyArrayObject *na = NA_NewAllFromBuffer(c == 1?1:2,shape,numtype,buf,0,0,NA_ByteOrder(),1,1);
+         return (PyObject *)na;
+     }
+     else
+ #endif
+     return NULL;
+ }
+ 
  static PyObject *buffer_slice(pySamplebuffer *self,int ilow = 0,int ihigh = 1<<(sizeof(int)*8-2))
  {
***************
*** 192,199 ****
              if(ihigh > n) ihigh = n;
  
!             maybelong shape[2];
!             shape[0] = n;
!             shape[1] = c;
!             PyObject *nobj = (PyObject *)NA_NewAllFromBuffer(c == 1?1:2,shape,numtype,(PyObject *)self,0,0,NA_ByteOrder(),1,1);
              if(ilow != 0 || ihigh != n) {
                  ret = PySequence_GetSlice(nobj,ilow,ihigh);
--- 207,211 ----
              if(ihigh > n) ihigh = n;
  
!             PyObject *nobj = NAFromBuffer((PyObject *)self,c,n);
              if(ilow != 0 || ihigh != n) {
                  ret = PySequence_GetSlice(nobj,ilow,ihigh);
***************
*** 658,662 ****
      if(PyErr_Occurred())
          // catch import error
!         PyErr_Print();
      else {
          // numarray support ok
--- 670,674 ----
      if(PyErr_Occurred())
          // catch import error
!         PyErr_Clear();
      else {
          // numarray support ok

Index: main.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/main.h,v
retrieving revision 1.35
retrieving revision 1.36
diff -C2 -d -r1.35 -r1.36
*** main.h	9 Mar 2005 04:58:11 -0000	1.35
--- main.h	13 Mar 2005 04:59:47 -0000	1.36
***************
*** 42,62 ****
  typedef PooledFifo<FifoEl> PyFifo;
  
- class py:
- 	public flext_base
- {
- 	FLEXT_HEADER_S(py,flext_base,Setup)
  
  public:
! 	py();
! 	~py();
! 	static void lib_setup();
  
!     virtual void Exit();
  
  	static PyObject *MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,int inlet = -1,bool withself = false);
  	static AtomList *GetPyArgs(PyObject *pValue,PyObject **self = NULL);
  
  protected:
  
      void m__dir(PyObject *obj);
  	void m__doc(PyObject *obj);
--- 42,64 ----
  typedef PooledFifo<FifoEl> PyFifo;
  
  
+ 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,bool withself = false);
  	static AtomList *GetPyArgs(PyObject *pValue,PyObject **self = NULL);
  
+     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);
***************
*** 84,87 ****
--- 86,90 ----
  	virtual void Reload() = 0;
  
+     void OpenEditor();
      void Respond(bool b);
  
***************
*** 90,93 ****
--- 93,98 ----
  	enum retval { nothing,atom,sequ };
  
+     static PyObject *emptytuple;
+ 
  	// --- module stuff -----
  
***************
*** 132,135 ****
--- 137,141 ----
  
      bool gencall(PyObject *fun,PyObject *args);
+     virtual bool thrcall(void *data) = 0;
      virtual bool callpy(PyObject *fun,PyObject *args) = 0;
  
***************
*** 140,144 ****
      static bool collect();
  
! private:
  
  	void work_wrapper(void *data); 
--- 146,150 ----
      static bool collect();
  
! protected:
  
  	void work_wrapper(void *data); 
***************
*** 152,159 ****
      static PyThreadState *FindThreadState();
      static void FreeThreadState();
- 
- 	FLEXT_THREAD_X(work_wrapper)
- #else
- 	FLEXT_CALLBACK_X(work_wrapper)
  #endif
  
--- 158,161 ----
***************
*** 190,212 ****
  
  	static PyObject* StdOut_Write(PyObject* Self, PyObject* Args);
- 
- protected:
- 
-     virtual void m_click();
- 
- 	static void Setup(t_classid c);
- 
- 	// callbacks
- 	FLEXT_ATTRVAR_I(detach)
- 	FLEXT_ATTRVAR_B(respond)
- 	FLEXT_CALLBACK_V(m_stop)
- 	FLEXT_CALLBACK(m_dir)
- 	FLEXT_CALLGET_V(mg_dir)
- 	FLEXT_CALLBACK(m_doc)
- 
- #ifdef FLEXT_THREADS
-     FLEXT_CALLBACK_T(tick)
-     FLEXT_THREAD(threadworker)
- #endif
  };
  
--- 192,195 ----

Index: py.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/py.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -C2 -d -r1.19 -r1.20
*** py.cpp	9 Mar 2005 04:58:11 -0000	1.19
--- py.cpp	13 Mar 2005 04:59:47 -0000	1.20
***************
*** 12,19 ****
  
  
! class pyobj:
! 	public py
  {
! 	FLEXT_HEADER_S(pyobj,py,Setup)
  
  public:
--- 12,20 ----
  
  
! class pyobj
!     : public pybase
!     , public flext_base
  {
! 	FLEXT_HEADER_S(pyobj,flext_base,Setup)
  
  public:
***************
*** 22,28 ****
  
  protected:
! 	bool m_method_(int n,const t_symbol *s,int argc,const t_atom *argv);
  
! 	bool work(const t_symbol *s,int argc,const t_atom *argv); 
  
  	void m_reload();
--- 23,32 ----
  
  protected:
!     virtual void Exit();
  
! 	virtual bool CbMethodResort(int n,const t_symbol *s,int argc,const t_atom *argv);
!     virtual void CbClick();
! 
!     void m_help();    
  
  	void m_reload();
***************
*** 32,45 ****
      void m_doc_() { m__doc(function); }
  
- 	virtual void m_help();
- 
  	// 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); }
! 	void m_py_any(const t_symbol *s,int argc,const t_atom *argv) { callwork(s,argc,argv); }
  
  	const t_symbol *funname;
--- 36,47 ----
      void m_doc_() { m__doc(function); }
  
  	// methods for python arguments
  	void callwork(const t_symbol *s,int argc,const t_atom *argv);
  	
! 	inline void m_bang() { callwork(NULL,0,NULL); }
! 	inline void m_py_list(int argc,const t_atom *argv) { callwork(sym_list,argc,argv); }
! 	inline void m_py_float(int argc,const t_atom *argv) { callwork(sym_float,argc,argv); }
! 	inline void m_py_int(int argc,const t_atom *argv) { callwork(sym_int,argc,argv); }
! 	inline void m_py_any(const t_symbol *s,int argc,const t_atom *argv) { callwork(s,argc,argv); }
  
  	const t_symbol *funname;
***************
*** 52,55 ****
--- 54,60 ----
  	void ResetFunction();
  
+     virtual bool thrcall(void *data);
+     virtual void DumpOut(const t_symbol *sym,int argc,const t_atom *argv);
+ 
  private:
  
***************
*** 58,61 ****
--- 63,67 ----
  	static void Setup(t_classid c);
  
+ 	FLEXT_CALLBACK(m_help)
  	FLEXT_CALLBACK(m_bang)
  	FLEXT_CALLBACK(m_reload)
***************
*** 70,77 ****
  	FLEXT_CALLBACK_A(m_py_any)
  
  #ifdef FLEXT_THREADS
! 	FLEXT_THREAD_A(work)
  #else
! 	FLEXT_CALLBACK_A(work)
  #endif
  };
--- 76,93 ----
  	FLEXT_CALLBACK_A(m_py_any)
  
+ 	// callbacks
+ 	FLEXT_ATTRVAR_I(detach)
+ 	FLEXT_ATTRVAR_B(respond)
+ 	FLEXT_CALLBACK_V(m_stop)
+ 	FLEXT_CALLBACK(m_dir)
+ 	FLEXT_CALLGET_V(mg_dir)
+ 	FLEXT_CALLBACK(m_doc)
+ 
  #ifdef FLEXT_THREADS
!     FLEXT_CALLBACK_T(tick)
!     FLEXT_THREAD(threadworker)
! 	FLEXT_THREAD_X(work_wrapper)
  #else
! 	FLEXT_CALLBACK_X(work_wrapper)
  #endif
  };
***************
*** 82,85 ****
--- 98,109 ----
  void pyobj::Setup(t_classid c)
  {
+ 	FLEXT_CADDMETHOD_(c,0,"doc",m_doc);
+ 	FLEXT_CADDMETHOD_(c,0,"dir",m_dir);
+ #ifdef FLEXT_THREADS
+ 	FLEXT_CADDATTR_VAR1(c,"detach",detach);
+ 	FLEXT_CADDMETHOD_(c,0,"stop",m_stop);
+ #endif
+ 
+ 	FLEXT_CADDMETHOD_(c,0,"help",m_help);
  	FLEXT_CADDMETHOD_(c,0,"reload",m_reload_);
      FLEXT_CADDMETHOD_(c,0,"reload.",m_reload);
***************
*** 101,109 ****
  	function(NULL),funname(NULL),withfunction(false)
  { 
- 	PyThreadState *state = PyLock();
- 
  	AddInAnything(2);  
  	AddOutAnything();  
  
  	if(argc > 2) 
  		SetArgs(argc-2,argv+2);
--- 125,139 ----
  	function(NULL),funname(NULL),withfunction(false)
  { 
  	AddInAnything(2);  
  	AddOutAnything();  
  
+ #ifdef FLEXT_THREADS
+     FLEXT_ADDTIMER(stoptmr,tick);
+     // launch thread worker
+     FLEXT_CALLMETHOD(threadworker);
+ #endif
+ 
+ 	PyThreadState *state = PyLock();
+ 
  	if(argc > 2) 
  		SetArgs(argc-2,argv+2);
***************
*** 164,171 ****
  }
  
  
! 
! 
! bool pyobj::m_method_(int n,const t_symbol *s,int argc,const t_atom *argv)
  {
  	if(n == 1)
--- 194,204 ----
  }
  
+ void pyobj::Exit() 
+ { 
+     pybase::Exit(); 
+     flext_base::Exit(); 
+ }
  
! bool pyobj::CbMethodResort(int n,const t_symbol *s,int argc,const t_atom *argv)
  {
  	if(n == 1)
***************
*** 347,348 ****
--- 380,393 ----
      Respond(ret);
  }
+ 
+ void pyobj::CbClick() { pybase::OpenEditor(); }
+ 
+ void pyobj::DumpOut(const t_symbol *sym,int argc,const t_atom *argv)
+ {
+     ToOutAnything(GetOutAttr(),sym?sym:thisTag(),argc,argv);
+ }
+ 
+ bool pyobj::thrcall(void *data)
+ { 
+     return FLEXT_CALLMETHOD_X(work_wrapper,data);
+ }

Index: register.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/py/source/register.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** register.cpp	9 Jan 2005 04:59:30 -0000	1.5
--- register.cpp	13 Mar 2005 04:59:47 -0000	1.6
***************
*** 12,16 ****
  
  
! void py::Register(const char *regnm)
  {
  	if(module) {
--- 12,16 ----
  
  
! void pybase::Register(const char *regnm)
  {
  	if(module) {
***************
*** 21,25 ****
  		if(!reg || !PyList_Check(reg)) {
  			if(PyDict_SetItemString(dict,(char *)regnm,add)) {
! 				post("%s - Could not set registry",thisName());
  			}
  		}
--- 21,25 ----
  		if(!reg || !PyList_Check(reg)) {
  			if(PyDict_SetItemString(dict,(char *)regnm,add)) {
! 				post("py/pyext - Could not set registry");
  			}
  		}
***************
*** 30,34 ****
  }
  
! void py::Unregister(const char *regnm)
  {
  	if(module) {
--- 30,34 ----
  }
  
! void pybase::Unregister(const char *regnm)
  {
  	if(module) {
***************
*** 38,46 ****
  		PyObject *add = Py_BuildValue("i",(int)this);
  		if(!reg || !PySequence_Check(reg)) 
! 			post("%s - Internal error: Registry not found!?",thisName());
  		else {
  			int ix = PySequence_Index(reg,add);
  			if(ix < 0) {
!                 post("%s - Internal error: object not found in registry?!",thisName());
  			}
  			else {	
--- 38,46 ----
  		PyObject *add = Py_BuildValue("i",(int)this);
  		if(!reg || !PySequence_Check(reg)) 
! 			post("py/pyext - Internal error: Registry not found!?");
  		else {
  			int ix = PySequence_Index(reg,add);
  			if(ix < 0) {
!                 post("py/pyext - Internal error: object not found in registry?!");
  			}
  			else {	
***************
*** 52,56 ****
  }
  
! void py::Reregister(const char *regnm)
  {
  	if(module) {
--- 52,56 ----
  }
  
! void pybase::Reregister(const char *regnm)
  {
  	if(module) {
***************
*** 60,64 ****
  
  		if(!reg || !PySequence_Check(reg)) 
! 			post("%s - Internal error: Registry not found!?",thisName());
  		else {
  			int cnt = PySequence_Size(reg);
--- 60,64 ----
  
  		if(!reg || !PySequence_Check(reg)) 
! 			post("py/pyext - Internal error: Registry not found!?");
  		else {
  			int cnt = PySequence_Size(reg);
***************
*** 66,73 ****
  				PyObject *it = PySequence_GetItem(reg,i); // new reference
  				if(!it || !PyInt_Check(it)) {
!                     post("%s - Internal error: Corrupt registry?!",thisName());
  				}
  				else {
! 					py *th = (py *)PyInt_AsLong(it);
  					th->module = module;
  					th->dict = dict;
--- 66,73 ----
  				PyObject *it = PySequence_GetItem(reg,i); // new reference
  				if(!it || !PyInt_Check(it)) {
!                     post("py/pyext - Internal error: Corrupt registry?!");
  				}
  				else {
! 					pybase *th = (pybase *)PyInt_AsLong(it);
  					th->module = module;
  					th->dict = dict;





More information about the Pd-cvs mailing list