1 /*  -*- c++ -*-
2     Abstract interpreter interface.
3     Copyright (c) 2003 2004 stefan kersten.
4     Copyright (c) 2013 tim blechmann.
5 
6     ====================================================================
7 
8     SuperCollider real time audio synthesis system
9     Copyright (c) 2002 James McCartney. All rights reserved.
10     http://www.audiosynth.com
11 
12     This program is free software; you can redistribute it and/or modify
13     it under the terms of the GNU General Public License as published by
14     the Free Software Foundation; either version 2 of the License, or
15     (at your option) any later version.
16 
17     This program is distributed in the hope that it will be useful,
18     but WITHOUT ANY WARRANTY; without even the implied warranty of
19     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20     GNU General Public License for more details.
21 
22     You should have received a copy of the GNU General Public License
23     along with this program; if not, write to the Free Software
24     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
25 */
26 
27 #pragma once
28 
29 #include "SC_Export.h"
30 #include <cstdio>
31 #include <cstdarg>
32 
33 // =====================================================================
34 // SC_LanguageClient - abstract sclang client.
35 // =====================================================================
36 
37 SCLANG_DLLEXPORT class SC_LanguageClient* createLanguageClient(const char* name);
38 SCLANG_DLLEXPORT void destroyLanguageClient(class SC_LanguageClient*);
39 
40 class SCLANG_DLLEXPORT SC_LanguageClient {
41 public:
42     struct Options {
OptionsOptions43         Options(): mMemSpace(2 * 1024 * 1024), mMemGrow(256 * 1024), mPort(57120), mRuntimeDir(0) {}
44 
45         int mMemSpace; // memory space in bytes
46         int mMemGrow; // memory growth in bytes
47         int mPort; // network port number
48         char* mRuntimeDir; // runtime directory
49     };
50 
51 protected:
52     // create singleton instance
53     SC_LanguageClient(const char* name);
54     virtual ~SC_LanguageClient();
55     friend void destroyLanguageClient(class SC_LanguageClient*);
56 
57 public:
58     // singleton instance access locking
59     static void lockInstance();
60     static void unlockInstance();
61 
62     // return the singleton instance
63     static SC_LanguageClient* instance();
lockedInstance()64     static SC_LanguageClient* lockedInstance() {
65         lockInstance();
66         return instance();
67     }
68 
69     // initialize language runtime
70     void initRuntime(const Options& opt = Options());
71     void shutdownRuntime();
72 
73     // return application name
74     const char* getName() const;
75 
76     // library startup/shutdown
77     bool isLibraryCompiled();
78     void compileLibrary(bool standalone);
79     void shutdownLibrary();
80     void recompileLibrary(bool standalone);
81 
82     // interpreter access
83     void lock();
84     bool trylock();
85     void unlock();
86 
87     struct VMGlobals* getVMGlobals();
88 
89     void setCmdLine(const char* buf, size_t size);
90     void setCmdLine(const char* str);
91     void setCmdLinef(const char* fmt, ...);
92     void runLibrary(const char* methodName);
93     void interpretCmdLine();
94     void interpretPrintCmdLine();
95     void executeFile(const char* fileName);
96     void runMain();
97     void stopMain();
98 
99     // post file access
100     FILE* getPostFile();
101     void setPostFile(FILE* file);
102 
103     // run (in case of a terminal client)
104     virtual int run(int argc, char** argv);
105 
106     // post buffer output (subclass responsibility)
107     //     should be thread-save.
108     virtual void postText(const char* str, size_t len) = 0;
109     virtual void postFlush(const char* str, size_t len) = 0;
110     virtual void postError(const char* str, size_t len) = 0;
111     // flush post buffer contents to screen.
112     //     only called from the main language thread.
113     virtual void flush() = 0;
114 
115     // command line argument handling utilities
116     static void snprintMemArg(char* dst, size_t size, int arg);
117     static bool parseMemArg(const char* arg, int* res);
118     static bool parsePortArg(const char* arg, int* res);
119 
120     // AppClock driver
121     //    to be called from client mainloop.
122     void tick();
123     // AppClock driver. WARNING: Must be called locked!
124     // Returns whether there is anything scheduled,
125     // and writes the scheduled absolute time, if any, into nextTime.
126     bool tickLocked(double* nextTime);
127 
128 protected:
129     // language notifications, subclasses can override
130 
131     // called after language runtime has been initialized
132     virtual void onInitRuntime();
133     // called after the library has been compiled
134     virtual void onLibraryStartup();
135     // called before the library is shut down
136     virtual void onLibraryShutdown();
137     // called after the interpreter has been started
138     virtual void onInterpStartup();
139 
140     void runLibrary(struct PyrSymbol* pyrSymbol);
141 
142 private:
143     friend void closeAllGUIScreens();
144     friend void initGUIPrimitives();
145     friend void initGUI();
146 
147 private:
148     class HiddenLanguageClient* mHiddenClient;
149 };
150 
151 // =====================================================================
152 // library functions
153 // =====================================================================
154 
155 extern void setPostFile(FILE* file);
156 extern "C" int vpost(const char* fmt, va_list vargs);
157 extern void post(const char* fmt, ...);
158 extern void postfl(const char* fmt, ...);
159 extern void postText(const char* text, long length);
160 extern void postChar(char c);
161 extern void error(const char* fmt, ...);
162 extern void flushPostBuf();
163