class library: Reset has been renamed to OnError
[supercollider.git] / SCClassLibrary / JITLib / ProxySpace / extStoreOn.sc
blob5f2351491f74515742e36fbdaa4258391e764fa1
1 + AbstractPlayControl {
3         storeOn { | stream |
4                 source.storeOn(stream)
5         }
8 +Symbol {
10         isBasicOperator {
11                 ^#['+', '-', '*', '/', '%', '==', '!=', '<', '<=', '>', '>=', '&&', '||', '@' ]
12                         .includes(this);
13         }
17 +Object {
19         // might need correction for literals.
20         envirKey { | envir |
21                 ^(envir ? currentEnvironment).findKeyForValue(this)
22         }
24         envirCompileString {
25                 var key = this.envirKey;
26                 ^if(key.notNil) { "~" ++ key } { this.asCompileString };
27         }
31 +NodeProxy {
33         key { | envir |
34                 ^super.envirKey(envir);
35         }
37         servStr {
38                 ^if (server != Server.default) { "(" ++ server.asCompileString ++")" } { "" }
39         }
41         // not ideal, but usable for now.
42         storeOn { | stream |
43                 var key = this.key;
45                 if (currentEnvironment.includes(this)) {
46                         stream << ("~" ++ key)
47                 } {
48                         if (key.isNil) {
49                                 stream << "a = NodeProxy.new" ++ this.servStr
50                         }
51                 };
52         }
54         playEditString { |usePlayN, dropDefaults = false, nameStr|
55                 var editString, outs, amps;
56                 nameStr = nameStr ?? { this.asCompileString };
58                 if (nameStr.beginsWith("a = ")) { // anon proxy
59                         nameStr = nameStr.keep(1);
60                 };
61                 usePlayN = usePlayN ?? { if (monitor.notNil) { monitor.usedPlayN } ? false };
63                 // if they are defaults, don't post them
64                 if (usePlayN) {
65                         editString = nameStr ++ this.playNString(dropDefaults)
66                 } {
67                         editString = nameStr ++ this.playString(dropDefaults)
68                 };
69                 ^editString;
70         }
72         playString { |dropDefaults = false|
73                 var defOut = 0, defVol = 1, defNumCh = this.numChannels ? 2;
74                 var out, numCh, vol, setStr = "";
76                 out = try { this.monitor.out } ? defOut;
77                 numCh = this.numChannels ? defNumCh;            // should be able to be different, or not?
78                 vol = try { this.monitor.vol } ? defVol;
80                 if (dropDefaults.not or: { out != defOut }) { setStr = setStr ++ "\tout:" + out };
82                 if (dropDefaults.not or: { numCh != defNumCh }) {
83                         if (setStr.size > 0) { setStr = setStr ++ ", \n" };
84                         setStr = setStr ++ "\tnumChannels:" + numCh;
85                 };
87                 if (dropDefaults.not or: { vol != defVol }) {
88                         if (setStr.size > 0) { setStr = setStr ++ ", \n" };
89                         setStr = setStr ++ "\tvol:" + vol ++ "\n";
90                 };
91                 if (setStr.size > 0) {
92                         setStr = "(\n" ++ setStr ++ "\n)";
93                 };
94                 ^(".play" ++ setStr ++ ";\n");
95         }
97         playNString { |dropDefaults = false|
98                 var numCh =  this.numChannels ? 2;
99                 var defOuts = { |i| i } ! numCh;
100                 var defAmps = 1 ! numCh;
101                 var defIns = { |i| i + this.index } ! numCh;
102                 var defVol = 1;
104                 var outs = try { this.monitor.outs } ? defOuts;
105                 var amps = try { this.monitor.amps } ? defAmps;
106                 var ins  = try { this.monitor.ins }  ? defIns;
107                 var vol  = try { this.monitor.vol }  ? defVol;
109                 var setStr = "";
111                 // [\o, defOuts, outs, \a, defAmps, amps, \i, defIns, ins].postcs;
113                 if (dropDefaults.not or: { outs != defOuts }) {
114                         setStr = setStr ++ "\touts:" + outs
115                 };
116                 if (dropDefaults.not or: { amps != defAmps }) {
117                         if (setStr.size > 0) { setStr = setStr ++ ", \n" };
118                         setStr = setStr ++ "\tamps:" + amps;
119                 };
120                 if (dropDefaults.not or: { ins != defIns }) {
121                         if (setStr.size > 0) { setStr = setStr ++ ", \n" };
122                         setStr = setStr ++ "\tins:" + ins;
123                 };
124                 if (dropDefaults.not or: { vol != defVol }) {
125                         if (setStr.size > 0) { setStr = setStr ++ ", \n" };
126                         setStr = setStr ++ "\tvol:" + vol ++ "\n";
127                 };
128                 if (setStr.size > 0) {
129                         setStr = "(\n" ++ setStr ++ "\n)";
130                 };
131                 ^(".playN" ++ setStr ++ ";\n");
132         }
134         playNDialog { | bounds, usePlayN |
135                 var doc = this.playEditString(usePlayN).newTextWindow("edit outs:");
136                 try { doc.bounds_(bounds) };    // swingosc safe
137         }
139         findInOpenDocuments { |index = 0|
140                 var src, str, startSel, doc;
141                 src = this.at(index);
142                 src ?? { "NodeProxy: no source at index %.\n".postf(index); ^this };
144                 str = src.asCompileString;
145                 doc = Document.allDocuments.detect { |doc|
146                         startSel = doc.string.find(str);
147                         startSel.notNil;
148                 };
149                 doc !? { doc.front.selectRange(startSel, 0); }
150         }
152         asCode { | includeSettings = true, includeMonitor = true, envir |
153                 var nameStr, srcStr, str, docStr, indexStr, key;
154                 var space, spaceCS;
156                 var isAnon, isSingle, isInCurrent, isOnDefault, isMultiline;
158                 envir = envir ? currentEnvironment;
160                 nameStr = envir.use { this.asCompileString };
161                 indexStr = nameStr;
163                 isAnon = nameStr.beginsWith("a = ");
164                 isSingle = this.objects.isEmpty or: { this.objects.size == 1 and: { this.objects.indices.first == 0 } };
165                 isInCurrent = envir.includes(this);
166                 isOnDefault = server === Server.default;
168         //      [\isAnon, isAnon, \isSingle, isSingle, \isInCurrent, isInCurrent, \isOnDefault, isOnDefault].postln;
170                 space = ProxySpace.findSpace(this);
171                 spaceCS = try { space.asCode } {
172                         inform("// <could not find a space for proxy: %!>".format(this.asCompileString));
173                         ""
174                 };
176                 docStr = String.streamContents { arg stream;
177                         if(isSingle) {
178                                 str = nameStr;
179                                 srcStr = if (this.source.notNil) { this.source.envirCompileString } { "" };
181                                 if ( isAnon ) {                 // "a = NodeProxy.new"
182                                         if (isOnDefault.not) { str = str ++ "(" ++ this.server.asCompileString ++ ")" };
183                                         if (srcStr.notEmpty) { str = str ++ ".source_(" ++ srcStr ++ ")" };
184                                 } {
185                                         if (isInCurrent) {      // ~out
186                                                 if (srcStr.notEmpty) { str = str + "=" + srcStr };
188                                         } {                                     // Ndef('a') - put sourceString before closing paren.
189                                                 if (srcStr.notEmpty) {
190                                                         str = str.copy.drop(-1) ++ ", " ++ srcStr ++ nameStr.last
191                                                 };
192                                         }
193                                 };
194                         } {
195                                 // multiple sources
196                                 if (isAnon) {
197                                         str = nameStr ++ ";\n";
198                                         indexStr = "a";
199                                 };
201                                 this.objects.keysValuesDo { arg index, item;
203                                         srcStr = item.source.envirCompileString ? "";
204                                         isMultiline = srcStr.includes(Char.nl);
205                                         if (isMultiline) { srcStr = "(" ++ srcStr ++ ")" };
206                                         srcStr = indexStr ++ "[" ++ index ++ "] = " ++ srcStr ++ ";\n";
207                                         str = str ++ srcStr;
208                                 };
209                         };
211                         stream << str << if (str.keep(-2).includes($;)) { "\n" } { ";\n" };
213                                 // add settings to compile string
214                         if(includeSettings) {
215                                         this.nodeMap.storeOn(stream, indexStr, true);
216                         };
217                                 // include play settings if playing ...
218                                 // hmmm - also keep them if not playing,
219                                 // but inited to something non-default?
220                         if (this.rate == \audio and: includeMonitor) {
221                                 if (this.monitor.notNil) {
222                                         if (this.isMonitoring) {
223                                                 stream << this.playEditString(this.monitor.usedPlayN, true)
224                                         }
225                                 };
226                         };
227                 };
229                 isMultiline = docStr.drop(-1).includes(Char.nl);
230                 if (isMultiline) { docStr = "(\n" ++ docStr ++ ");\n" };
232                 ^docStr
233         }
235         document { | includeSettings = true, includeMonitor = true |
236                 ^this.asCode(includeSettings, includeMonitor).newTextWindow("document :" + this.asCompileString)
237         }
242 +BinaryOpPlug {
244         envirCompileString {
245                 var astr, bstr, opstr, str = "";
246                 var basic = operator.isBasicOperator;
247                 astr = a.envirCompileString;
248                 bstr = b.envirCompileString;
250                 if(b.isKindOf(AbstractOpPlug)) { bstr = "(%)".format(bstr) };
251                 opstr = if(basic.not) { ".%(" } { " % " }.format(operator);
252                 str = str ++ astr ++ opstr ++ bstr;
253                 if(basic.not) { str = str ++ ")" };
254                 ^str
255         }
258 +UnaryOpPlug {
260         envirCompileString {
261                 ^(a.envirCompileString ? "") ++  " "  ++ operator
262         }
268 + ProxySpace {
270                         // where am I globally accessible?
271         asCode {
272                 var key;
273                 if (this == thisProcess.interpreter.p) { ^"p" };
274                 if (this == currentEnvironment) { ^"currentEnvironment" };
275                 if (Ndef.all.includes(this)) {
276                         key = Ndef.all.findKeyForValue(this);
277                         ^"Ndef.all[%]".format(key.asCompileString);
278                 };
279                 if (ProxySpace.all.includes(this)) {
280                         key = ProxySpace.all.findKeyForValue(this);
281                         ^"ProxySpace.all[%]".format(key.asCompileString);
282                 };
284                 ^"/***( cannot locate this proxyspace )***/"
285         }
287         storeOn { | stream, keys, includeSettings = true, includeMonitors = true |
288                 var proxies, hasGlobalClock;
290                 hasGlobalClock = clock.isKindOf(TempoBusClock);
292                 stream << "\n(\n"; // )
293                 if(hasGlobalClock) { stream <<< this.asCode << ".makeTempoClock(" << clock.tempo << ");\n\n"; };
294                 // find keys for all parents
295                 if(keys.notNil) {
296                         proxies = IdentitySet.new;
297                         keys.do { arg key; var p = envir[key]; p !? { p.getFamily(proxies) } };
298                         keys = proxies.collect { arg item; item.key(envir) };
299                 } { keys = envir.keys };
301                 if(hasGlobalClock) { keys.remove(\tempo) };
303                 // add all objects to compilestring
304                 keys.do { arg key;
305                         var proxy = envir.at(key);
306                         stream << proxy.asCode(includeSettings, includeMonitors, this.envir) << "\n";
307                 };
309                 stream << /*(*/ ");\n";
310         }
312         documentOutput {
313                 ^this.document(nil, true)
314         }
316         document { | keys, onlyAudibleOutput = false, includeSettings = true |
317                 var str;
318                 if(onlyAudibleOutput) {
319                         keys = this.monitors.collect { arg item; item.key(envir) };
320                 };
321                 str = String.streamContents { arg stream;
322                         stream << "// ( p = ProxySpace.new(s).push; ) \n\n";
323                         this.storeOn(stream, keys, includeSettings);
324 //                      this.do { arg px; if(px.monitorGroup.isPlaying) {
325 //                              stream << px.playEditString << ".play; \n"
326 //                              }
327 //                      };
328                 };
329                 ^str.newTextWindow((name ? "proxyspace").asString)
330         }
334 + ProxyNodeMap {
336         storeOn { | stream, namestring = "", dropOut = false |
337                 var strippedSetArgs, storedSetNArgs, rates, proxyMapKeys, proxyMapNKeys;
338                 this.updateBundle;
339                 if(dropOut) {
340                         forBy(0, setArgs.size - 1, 2, { arg i;
341                                 var item;
342                                 item = setArgs[i];
343                                 if(item !== 'out' and: { item !== 'i_out' })
344                                 {
345                                         strippedSetArgs = strippedSetArgs.add(item);
346                                         strippedSetArgs = strippedSetArgs.add(setArgs[i+1]);
347                                 }
348                         })
349                 } { strippedSetArgs = setArgs };
350                 if(strippedSetArgs.notNil) {
351                         stream << namestring << ".set(" <<<* strippedSetArgs << ");" << Char.nl;
352                 };
354                 if(mapArgs.notNil or: { mapnArgs.notNil }) {
355                         settings.keysValuesDo { arg key, setting;
356                                 var proxy;
357                                 if(setting.isMapped) {
358                                         proxy = setting.value;
359                                         if(proxy.notNil) {
360                                                 if(setting.isMultiChannel) {
361                                                         proxyMapNKeys = proxyMapNKeys.add(key);
362                                                         proxyMapNKeys = proxyMapNKeys.add(proxy);
363                                                 }{
364                                                         proxyMapKeys = proxyMapKeys.add(key);
365                                                         proxyMapKeys = proxyMapKeys.add(proxy);
366                                                 }
367                                         };
368                                 };
369                         };
370                         if(proxyMapKeys.notNil) {
371                                 stream << namestring << ".map(" <<<* proxyMapKeys << ");" << Char.nl;
372                         };
373                         if(proxyMapNKeys.notNil) {
374                                 stream << namestring << ".mapn(" <<<* proxyMapNKeys << ");" << Char.nl;
375                         };
376                 };
378                 if(setnArgs.notNil) {
379                         storedSetNArgs = Array.new;
380                         settings.keysValuesDo { arg key, setting;
381                                 if(setting.isMapped.not and: setting.isMultiChannel) {
382                                         storedSetNArgs = storedSetNArgs.add(key);
383                                         storedSetNArgs = storedSetNArgs.add(setting.value);
384                                 }
385                         };
386                         stream << namestring << ".setn(" <<<* storedSetNArgs << ");" << Char.nl;
387                 };
388                 settings.keysValuesDo { arg key, setting;
389                         if(setting.rate.notNil) { rates = rates.add(key); rates = rates.add(setting.rate) };
390                 };
391                 if(rates.notNil) {
392                         stream << namestring << ".setRates(" <<<* rates << ");" << Char.nl;
393                 }
395         }