class library: DUGen - the server now handles audio-rate inputs correctly
[supercollider.git] / SCClassLibrary / Platform / Platform.sc
blob6b07eec2d9cba5f62fc86f76417b1d1ea2d444ba
1 Platform
3         classvar defaultStartupFile;
5         // IDE actions
6         classvar <>makeServerWindowAction, <>makeSynthDescWindowAction, <>openHelpFileAction, <>openHTMLFileAction;
8         var <classLibraryDir, <helpDir, <>recordingsDir, features;
9         var <>devpath;
11         *initClass {
12                 defaultStartupFile = this.userConfigDir +/+ "startup.scd"
13         }
15         initPlatform {
16                 classLibraryDir = thisMethod.filenameSymbol.asString.dirname.dirname;
17                 helpDir = thisMethod.filenameSymbol.asString.dirname.dirname.dirname ++ "/Help";
18                 features = IdentityDictionary.new;
19                 recordingsDir = this.userAppSupportDir +/+ "Recordings";
20         }
22         name { ^this.subclassResponsibility }
24         recompile { _Recompile }
25         *case { | ... cases |
26                 ^thisProcess.platform.name.switch(*cases)
27         }
29         // directories
30         *classLibraryDir { ^thisProcess.platform.classLibraryDir }
31         *helpDir { ^thisProcess.platform.helpDir }
33         systemAppSupportDir { _Platform_systemAppSupportDir }
34         *systemAppSupportDir { ^thisProcess.platform.systemAppSupportDir }
36         userAppSupportDir { _Platform_userAppSupportDir }
37         *userAppSupportDir { ^thisProcess.platform.userAppSupportDir }
39         systemExtensionDir { _Platform_systemExtensionDir }
40         *systemExtensionDir { ^thisProcess.platform.systemExtensionDir }
42         userExtensionDir { _Platform_userExtensionDir }
43         *userExtensionDir { ^thisProcess.platform.userExtensionDir }
45         userConfigDir { _Platform_userConfigDir }
46         *userConfigDir { ^thisProcess.platform.userConfigDir }
48         defaultTempDir { ^this.subclassResponsibility() }
49         *defaultTempDir { ^thisProcess.platform.defaultTempDir }
51         // The "ideName" is for ide-dependent compilation.
52         // From SC.app, the value is "scapp" meaning "scide_scapp" folders will be compiled and other "scide_*" ignored.
53         ideName { _Platform_ideName }
54         *ideName { ^thisProcess.platform.ideName }
56         platformDir { ^this.name.asString }
57         *platformDir { ^thisProcess.platform.platformDir }
59         pathSeparator { ^this.subclassResponsibility }
60         *pathSeparator { ^thisProcess.platform.pathSeparator }
62         isPathSeparator { |char| ^this.subclassResponsibility }
63         *isPathSeparator { |char| ^thisProcess.platform.isPathSeparator(char) }
65         clearMetadata { |path| ^this.subclassResponsibility }
66         *clearMetadata { |path| ^thisProcess.platform.clearMetadata(path) }
68         getMouseCoords { ^this.subclassResponsibility }
69         *getMouseCoords { ^thisProcess.platform.getMouseCoords }
71         // startup/shutdown hooks
72         startup { }
73         shutdown { }
75         startupFiles {
76                 ^[defaultStartupFile];
77         }
79         *deprecatedStartupFiles {|paths|
80                 var postWarning = false;
81                 paths.do {|path|
82                         if (File.exists(path.standardizePath)) {
83                                 warn("Deprecated startup file found: %\n".format(path));
84                                 postWarning = true;
85                         }
86                 };
87                 if (postWarning) {
88                         postln("Please use % as startup file.\nDeprecated startup files will be ignored in future versions.\n".format(defaultStartupFile));
89                 }
90         }
92         loadStartupFiles { this.startupFiles.do{|afile|
93                 afile = afile.standardizePath;
94                 if(File.exists(afile), {afile.load})
95                 }
96         }
98         // features
99         declareFeature { | aFeature |
100                 var str = aFeature.asString;
101                 if (str.first.isUpper) {
102                         Error("cannot declare class name features").throw;
103                 };
104                 if (str.first == $_) {
105                         Error("cannot declare primitive name features").throw;
106                 };
107                 features.put(aFeature, true);
108         }
109         hasFeature { | symbol |
110                 if (features.includesKey(symbol).not) {
111                         features.put(
112                                 symbol,
113                                 symbol.asSymbol.asClass.notNil or: { symbol.isPrimitive }
114                         )
115                 };
116                 ^features.at(symbol)
117         }
118         when { | features, ifFunction, elseFunction |
119                 ^features.asArray.inject(true, { |v,x|
120                         v and: { this.hasFeature(x) }
121                 }).if(ifFunction, elseFunction)
122         }
123         *when {  | features, ifFunction, elseFunction |
124                 ^thisProcess.platform.when(features, ifFunction, elseFunction)
125         }
127         // Prefer qt but fall back to swing if qt not installed.
128         defaultGUIScheme { if (GUI.get(\qt).notNil) {^\qt} {^\swing} }
129         defaultHIDScheme { ^\none }
131         isSleeping { ^false } // unless defined otherwise
133         // used on systems to deduce a svn directory path, if system wide location is used for installed version. (tested on Linux).
134         devLoc{ |inpath|
135                 var outpath;
136                 if ( devpath.isNil ){ ^inpath };
137                 outpath = inpath.copyToEnd( inpath.find( "SuperCollider") );
138                 outpath = outpath.replace( "SuperCollider", devpath );
139                 ^outpath;
140         }
142         // hook for clients to write frontend.css
143         writeClientCSS {}
145         killAll { |cmdLineArgs|
146                 ^this.subclassResponsibility(\killAll)
147         }
150 UnixPlatform : Platform
152         pathSeparator { ^$/ }
154         isPathSeparator { |char|
155                 ^(char === this.pathSeparator)
156         }
158         clearMetadata { |path|
159                 "rm -f %\.*meta".format(path.splitext[0].escapeChar($ )).systemCmd;
160         }
162         arch {
163                 var pipe, arch;
164                 pipe = Pipe("arch", "r");
165                 arch = pipe.getLine;
166                 pipe.close;
167                 ^arch.asSymbol;
168         }
170         killAll { |cmdLineArgs|
171                 ("killall -9 " ++ cmdLineArgs).unixCmd;
172         }
174         defaultTempDir {
175                 // +/+ "" looks funny but ensures trailing slash
176                 ^["/tmp/", this.userAppSupportDir +/+ ""].detect({ |path|
177                         File.exists(path);
178                 });
179         }