2 Abstract interpreter interface.
3 Copyright (c) 2003 2004 stefan kersten.
5 ====================================================================
7 SuperCollider real time audio synthesis system
8 Copyright (c) 2002 James McCartney. All rights reserved.
9 http://www.audiosynth.com
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 #ifndef SC_LANGUAGECLIENT_H_INCLUDED
27 #define SC_LANGUAGECLIENT_H_INCLUDED
29 #include "SC_StringBuffer.h"
30 #include "SC_Export.h"
32 #include "SC_Win32Utils.h"
39 // =====================================================================
40 // SC_LanguageClient - abstract sclang client.
41 // =====================================================================
46 extern bool compiledOK
;
48 extern pthread_mutex_t gLangMutex
;
49 extern VMGlobals
* gMainVMGlobals
;
53 // if shouldBeRunning == false, return EINTR
54 // if language has been locked, return 0
55 template <typename FlagType
>
56 static inline int lockLanguageOrQuit(FlagType
const & shouldBeRunning
)
59 // we have pthread_mutex_timedlock
61 int status
= pthread_mutex_trylock(&gLangMutex
);
63 if (shouldBeRunning
== false) {
64 pthread_mutex_unlock(&gLangMutex
);
67 } else if (status
== EBUSY
) {
70 clock_gettime(CLOCK_REALTIME
, &now
);
73 status
= pthread_mutex_timedlock(&gLangMutex
, &now
);
74 if (shouldBeRunning
== false) {
76 pthread_mutex_unlock(&gLangMutex
);
79 } while (status
== ETIMEDOUT
);
85 status
= pthread_mutex_trylock (&gLangMutex
);
86 if (shouldBeRunning
== false) {
88 pthread_mutex_unlock(&gLangMutex
);
91 if (status
== EBUSY
) {
92 struct timespec sleepTime
, remain
;
94 sleepTime
.tv_nsec
= 100000;
95 nanosleep(&sleepTime
, &remain
);
103 class SC_DLLEXPORT SC_LanguageClient
109 : mMemSpace(2*1024*1024),
115 int mMemSpace
; // memory space in bytes
116 int mMemGrow
; // memory growth in bytes
117 int mPort
; // network port number
118 char* mRuntimeDir
; // runtime directory
122 // create singleton instance
123 SC_LanguageClient(const char* name
);
124 virtual ~SC_LanguageClient();
126 // singleton instance access locking
127 static void lockInstance() { gInstanceMutex
.Lock(); }
128 static void unlockInstance() { gInstanceMutex
.Unlock(); }
130 // return the singleton instance
131 static SC_LanguageClient
* instance() { return gInstance
; }
132 static SC_LanguageClient
* lockedInstance() { lockInstance(); return gInstance
; }
134 // initialize language runtime
135 void initRuntime(const Options
& opt
=Options());
136 void shutdownRuntime();
138 // return application name
139 const char* getName() const { return mName
; }
141 // library startup/shutdown
142 bool isLibraryCompiled() { return compiledOK
; }
143 void compileLibrary();
144 void shutdownLibrary();
145 void recompileLibrary();
147 // interpreter access
148 void lock() { pthread_mutex_lock(&gLangMutex
); }
149 bool trylock() { return pthread_mutex_trylock(&gLangMutex
) == 0; }
150 void unlock() { pthread_mutex_unlock(&gLangMutex
); }
152 VMGlobals
* getVMGlobals() { return gMainVMGlobals
; }
154 void setCmdLine(const char* buf
, size_t size
);
155 void setCmdLine(const char* str
);
156 void setCmdLine(const SC_StringBuffer
& strBuf
);
157 void setCmdLinef(const char* fmt
, ...);
158 void runLibrary(PyrSymbol
* pyrSymbol
);
159 void runLibrary(const char* methodName
);
160 void interpretCmdLine() { runLibrary(s_interpretCmdLine
); }
161 void interpretPrintCmdLine() { runLibrary(s_interpretPrintCmdLine
); }
162 void executeFile(const char* fileName
);
163 void runMain() { runLibrary(s_run
); }
164 void stopMain() { runLibrary(s_stop
); }
167 FILE* getPostFile() { return mPostFile
; }
168 void setPostFile(FILE* file
) { mPostFile
= file
; }
170 // post buffer output (subclass responsibility)
171 // should be thread-save.
172 virtual void postText(const char* str
, size_t len
) = 0;
173 virtual void postFlush(const char* str
, size_t len
) = 0;
174 virtual void postError(const char* str
, size_t len
) = 0;
175 // flush post buffer contents to screen.
176 // only called from the main language thread.
177 virtual void flush() = 0;
180 // only valid after the library has been compiled.
181 static PyrSymbol
* s_interpretCmdLine
;
182 static PyrSymbol
* s_interpretPrintCmdLine
;
183 static PyrSymbol
* s_run
;
184 static PyrSymbol
* s_stop
;
186 // command line argument handling utilities
187 static void snprintMemArg(char* dst
, size_t size
, int arg
);
188 static bool parseMemArg(const char* arg
, int* res
);
189 static bool parsePortArg(const char* arg
, int* res
);
192 // to be called from client mainloop.
194 // AppClock driver. WARNING: Must be called locked!
195 // Returns whether there is anything scheduled,
196 // and writes the scheduled absolute time, if any, into nextTime.
197 bool tickLocked( double * nextTime
);
200 // language notifications, subclasses can override
202 // called after language runtime has been initialized
203 virtual void onInitRuntime();
204 // called after the library has been compiled
205 virtual void onLibraryStartup();
206 // called before the library is shut down
207 virtual void onLibraryShutdown();
208 // called after the interpreter has been started
209 virtual void onInterpStartup();
212 friend void closeAllGUIScreens();
213 friend void initGUIPrimitives();
214 friend void initGUI();
219 SC_StringBuffer mScratch
;
221 static SC_LanguageClient
* gInstance
;
222 static SC_Lock gInstanceMutex
;
225 // =====================================================================
227 // =====================================================================
229 extern void setPostFile(FILE* file
);
230 extern "C" int vpost(const char *fmt
, va_list vargs
);
231 extern void post(const char *fmt
, ...);
232 extern void postfl(const char *fmt
, ...);
233 extern void postText(const char *text
, long length
);
234 extern void postChar(char c
);
235 extern void error(const char *fmt
, ...);
236 extern void flushPostBuf();
238 #endif // SC_LANGUAGECLIENT_H_INCLUDED