supernova: c++11 compile fix
[supercollider.git] / bindings / PySCLang / PySCLang_Module.cpp
blob5286a68568c7fc1c650db7259c5ceb102a2b9d3e
1 /*
2 * File: PYSCLang_Module.cpp
3 * Project : Psycollider
5 * by:
6 * Benjamin Golinvaux
7 * benjamin.golinvaux@euresys.com
8 * messenger: bgolinvaux@hotmail.com
10 * currently maintained by:
11 * Christopher Frauenberger
12 * frauenberger@iem.at
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
27 * USA
31 #ifndef SC_WIN32
32 #include "CXX/Objects.hxx"
33 #include "CXX/Extensions.hxx"
34 #else
35 #include "stdafx.h"
36 #endif
38 #include "PySCLang_Module.h"
40 extern "C" {
41 void initPySCLang()
43 #if defined(PY_WIN32_DELAYLOAD_PYTHON_DLL)
44 Py::InitialisePythonIndirectInterface();
45 #endif
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);
59 void flushPostBuf();
60 // void SetupHomeDirectory();
61 double elapsedTime();
63 extern char *gHomePath;
65 #ifdef SC_WIN32
66 void PySCLang_InitNetwork( )
68 #ifdef SC_WIN32_STATIC_PTHREADS
69 // initialize statically linked pthreads library
70 pthread_win32_process_attach_np();
71 #endif
73 // initialize winsock
74 WSAData wsaData;
75 int nCode;
77 if ((nCode = WSAStartup(MAKEWORD(1, 1), &wsaData)) != 0) {
78 char msg[1024];
79 sprintf(msg, "WSAStartup() failed with error code %d.\n", nCode );
80 ::MessageBox(NULL,msg,"Error",MB_OK);
83 #endif
85 // triggered for app clock ticks
86 extern "C" void *appClockTimer(void * pymod) {
87 ((PySCLang_Module *)pymod)->appClock();
88 return NULL;
91 void PySCLang_Module::appClock() {
92 while(true) {
93 pthread_mutex_lock(&gLangMutex);
94 if (compiledOK) runLibrary(getsym("tick"));
95 pthread_mutex_unlock(&gLangMutex);
97 #ifdef SC_WIN32
98 Sleep(20); // Sleep (windows) takes a time in milliseconds
99 #else
100 usleep(20000); // usleep (posix) takes a time in microseconds
101 #endif
105 PySCLang_Module::PySCLang_Module() : ExtensionModule<PySCLang_Module>( "PySCLang" )
107 #ifdef SC_WIN32
108 PySCLang_InitNetwork( );
109 #endif
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
124 extern "C" {
125 void initPySCLang_d() {
126 initPySCLang();
130 Py::Object PySCLang_Module::sendMain(const Py::Tuple &a)
132 if(a.size() != 1) {
133 PyErr_SetString(PyExc_IndexError,"requires 1 string argument");
134 return Py::Object(Py::Null());
136 if (!compiledOK) {
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)
153 if(a.size() != 0) {
154 PyErr_SetString(PyExc_IndexError,"requires 0 args");
155 return Py::Object(Py::Null());
157 ::compileLibrary( );
158 return Py::Nothing();
161 Py::Object PySCLang_Module::setCmdLine(const Py::Tuple &a)
163 if(a.size() != 1) {
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);
171 if (!compiledOK) {
172 PyErr_SetString(PyExc_RuntimeError,"PySCLang: The library has not been compiled successfully");
173 return Py::Object(Py::Null());
175 pthread_mutex_lock(&gLangMutex);
177 if (compiledOK) {
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)
193 if(a.size() != 0) {
194 PyErr_SetString(PyExc_IndexError,"requires 0 args");
195 return Py::Object(Py::Null());
197 if( compiledOK )
198 return Py::Int(1);
199 else
200 return Py::Int(0);
203 Py::Object PySCLang_Module::start(const Py::Tuple &a)
205 if(a.size() != 0) {
206 PyErr_SetString(PyExc_IndexError,"requires 0 args");
207 return Py::Object(Py::Null());
209 pyr_init_mem_pools( 2*1024*1024, 256*1024 );
210 init_OSC(57120);
211 schedInit();
212 ::compileLibrary();
214 // appClock timer
215 pthread_t t;
216 pthread_create(&t, NULL, &appClockTimer, (void *)this);
218 // deferred task timer still missing... (cf, 16 May 2006)
220 //!!!
221 // Rendezvous is broken in a way that makes SC become unusable
222 // // CR ADDED
223 // [[RendezvousClient sharedClient] findOSCServices];
224 //!!!
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)
233 if(a.size() != 1) {
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");
240 else {
241 PyPrOpenWinTextFile_s = openTextFile;
242 Py_INCREF(openTextFile);
244 return Py::Nothing();
248 Py::Object PySCLang_Module::setSCLogSink(const Py::Tuple &a)
250 if(a.size() != 1) {
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");
257 else {
258 scLogSink_s = logSink;
259 Py_INCREF(logSink);
261 return Py::Nothing();