2 * File: PYSCLang_Module.cpp
3 * Project : Psycollider
7 * benjamin.golinvaux@euresys.com
8 * messenger: bgolinvaux@hotmail.com
10 * currently maintained by:
11 * Christopher Frauenberger
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
32 #include "CXX/Objects.hxx"
33 #include "CXX/Extensions.hxx"
38 #include "PySCLang_Module.h"
43 #if defined(PY_WIN32_DELAYLOAD_PYTHON_DLL)
44 Py::InitialisePythonIndirectInterface();
46 static PySCLang_Module
* thePySCLang_Module
= new PySCLang_Module
;
50 ChangeCounter gUIChangeCounter
;
52 extern bool compiledOK
;
53 extern pthread_mutex_t gLangMutex
;
54 extern PyrSymbol
*s_tick
;
56 PyrString
* newPyrStringN(class PyrGC
*gc
, long length
, long flags
, bool collect
);
57 void dumpByteCodes(PyrBlock
*theBlock
);
60 // void SetupHomeDirectory();
63 extern char *gHomePath
;
66 void PySCLang_InitNetwork( )
68 #ifdef SC_WIN32_STATIC_PTHREADS
69 // initialize statically linked pthreads library
70 pthread_win32_process_attach_np();
77 if ((nCode
= WSAStartup(MAKEWORD(1, 1), &wsaData
)) != 0) {
79 sprintf(msg
, "WSAStartup() failed with error code %d.\n", nCode
);
80 ::MessageBox(NULL
,msg
,"Error",MB_OK
);
85 // triggered for app clock ticks
86 extern "C" void *appClockTimer(void * pymod
) {
87 ((PySCLang_Module
*)pymod
)->appClock();
91 void PySCLang_Module::appClock() {
93 pthread_mutex_lock(&gLangMutex
);
94 if (compiledOK
) runLibrary(getsym("tick"));
95 pthread_mutex_unlock(&gLangMutex
);
98 Sleep(20); // Sleep (windows) takes a time in milliseconds
100 usleep(20000); // usleep (posix) takes a time in microseconds
105 PySCLang_Module::PySCLang_Module() : ExtensionModule
<PySCLang_Module
>( "PySCLang" )
108 PySCLang_InitNetwork( );
110 add_varargs_method("sendMain", &PySCLang_Module::sendMain
, "sendMain");
111 add_varargs_method("compileLibrary", &PySCLang_Module::compileLibrary
, "compileLibrary");
112 add_varargs_method("setCmdLine", &PySCLang_Module::setCmdLine
, "setCmdLine");
113 add_varargs_method("start", &PySCLang_Module::start
, "start");
114 add_varargs_method("setSCLogSink", &PySCLang_Module::setSCLogSink
, "setSCLogSink");
115 add_varargs_method("compiledOK", &PySCLang_Module::compiledOK__
, "compiledOK");
116 add_varargs_method("setPyPrOpenWinTextFile", &PySCLang_Module::setPyPrOpenWinTextFile
, "setPyPrOpenWinTextFile callable with (path,startRange,rangeSize)");
118 initialize( "<documentation for the PySCLang_Module forthcoming>" );
123 // symbol required for the debug version
125 void initPySCLang_d() {
130 Py::Object
PySCLang_Module::sendMain(const Py::Tuple
&a
)
133 PyErr_SetString(PyExc_IndexError
,"requires 1 string argument");
134 return Py::Object(Py::Null());
137 PyErr_SetString(PyExc_RuntimeError
,"PySCLang: The library has not been compiled successfully");
138 return Py::Object(Py::Null());
140 Py::String
pystr(a
[0]);
141 std::string str
= pystr
;
142 const char* methodName
= str
.c_str();
143 pthread_mutex_lock(&gLangMutex
);
144 runLibrary(getsym(methodName
));
145 pthread_mutex_unlock(&gLangMutex
);
146 if (PyErr_Occurred( ) != NULL
) // there might be python calls from within sclang
147 return Py::Object(Py::Null());
148 return Py::Nothing();
151 Py::Object
PySCLang_Module::compileLibrary(const Py::Tuple
&a
)
154 PyErr_SetString(PyExc_IndexError
,"requires 0 args");
155 return Py::Object(Py::Null());
158 return Py::Nothing();
161 Py::Object
PySCLang_Module::setCmdLine(const Py::Tuple
&a
)
164 PyErr_SetString(PyExc_IndexError
,"requires 1 string argument");
165 return Py::Object(Py::Null());
167 Py::String
pystr(a
[0]);
168 const char* text
= ::PyString_AsString(pystr
.ptr());
169 int length
= strlen(text
);
172 PyErr_SetString(PyExc_RuntimeError
,"PySCLang: The library has not been compiled successfully");
173 return Py::Object(Py::Null());
175 pthread_mutex_lock(&gLangMutex
);
178 VMGlobals
*g
= gMainVMGlobals
;
180 int textlen
= length
;
181 PyrString
* strobj
= newPyrStringN(g
->gc
, textlen
, 0, true);
182 memcpy(strobj
->s
, (char*)text
, textlen
);
184 SetObject(&slotRawInterpreter(&g
->process
->interpreter
)->cmdLine
, strobj
);
185 g
->gc
->GCWrite(slotRawObject(&g
->process
->interpreter
), strobj
);
187 pthread_mutex_unlock(&gLangMutex
);
188 return Py::Nothing();
191 Py::Object
PySCLang_Module::compiledOK__(const Py::Tuple
&a
)
194 PyErr_SetString(PyExc_IndexError
,"requires 0 args");
195 return Py::Object(Py::Null());
203 Py::Object
PySCLang_Module::start(const Py::Tuple
&a
)
206 PyErr_SetString(PyExc_IndexError
,"requires 0 args");
207 return Py::Object(Py::Null());
209 pyr_init_mem_pools( 2*1024*1024, 256*1024 );
216 pthread_create(&t
, NULL
, &appClockTimer
, (void *)this);
218 // deferred task timer still missing... (cf, 16 May 2006)
221 // Rendezvous is broken in a way that makes SC become unusable
223 // [[RendezvousClient sharedClient] findOSCServices];
225 return Py::Nothing();
228 PyObject
* PySCLang_Module::scLogSink_s
= NULL
;
229 PyObject
* PySCLang_Module::PyPrOpenWinTextFile_s
= NULL
;
231 Py::Object
PySCLang_Module::setPyPrOpenWinTextFile(const Py::Tuple
&a
)
234 PyErr_SetString(PyExc_IndexError
,"requires 1 callable argument");
235 return Py::Object(Py::Null());
237 PyObject
* openTextFile
= a
[0].ptr();
238 if( PyCallable_Check( openTextFile
) == 0)
239 PyErr_SetString(PyExc_TypeError
,"object must be callable");
241 PyPrOpenWinTextFile_s
= openTextFile
;
242 Py_INCREF(openTextFile
);
244 return Py::Nothing();
248 Py::Object
PySCLang_Module::setSCLogSink(const Py::Tuple
&a
)
251 PyErr_SetString(PyExc_IndexError
,"requires 1 callable argument");
252 return Py::Object(Py::Null());
254 PyObject
* logSink
= a
[0].ptr();
255 if( PyCallable_Check( logSink
) == 0)
256 PyErr_SetString(PyExc_TypeError
,"object must be callable");
258 scLogSink_s
= logSink
;
261 return Py::Nothing();