1 + AbstractPlayControl {
11 ^#['+', '-', '*', '/', '%', '==', '!=', '<', '<=', '>', '>=', '&&', '||', '@' ]
19 // might need correction for literals.
21 ^(envir ? currentEnvironment).findKeyForValue(this)
25 var key = this.envirKey;
26 ^if(key.notNil) { "~" ++ key } { this.asCompileString };
34 ^super.envirKey(envir);
38 ^if (server != Server.default) { "(" ++ server.asCompileString ++")" } { "" }
41 // not ideal, but usable for now.
45 if (currentEnvironment.includes(this)) {
46 stream << ("~" ++ key)
49 stream << "a = NodeProxy.new" ++ this.servStr
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);
61 usePlayN = usePlayN ?? { if (monitor.notNil) { monitor.usedPlayN } ? false };
63 // if they are defaults, don't post them
65 editString = nameStr ++ this.playNString(dropDefaults)
67 editString = nameStr ++ this.playString(dropDefaults)
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;
87 if (dropDefaults.not or: { vol != defVol }) {
88 if (setStr.size > 0) { setStr = setStr ++ ", \n" };
89 setStr = setStr ++ "\tvol:" + vol ++ "\n";
91 if (setStr.size > 0) {
92 setStr = "(\n" ++ setStr ++ "\n)";
94 ^(".play" ++ setStr ++ ";\n");
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;
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;
111 // [\o, defOuts, outs, \a, defAmps, amps, \i, defIns, ins].postcs;
113 if (dropDefaults.not or: { outs != defOuts }) {
114 setStr = setStr ++ "\touts:" + outs
116 if (dropDefaults.not or: { amps != defAmps }) {
117 if (setStr.size > 0) { setStr = setStr ++ ", \n" };
118 setStr = setStr ++ "\tamps:" + amps;
120 if (dropDefaults.not or: { ins != defIns }) {
121 if (setStr.size > 0) { setStr = setStr ++ ", \n" };
122 setStr = setStr ++ "\tins:" + ins;
124 if (dropDefaults.not or: { vol != defVol }) {
125 if (setStr.size > 0) { setStr = setStr ++ ", \n" };
126 setStr = setStr ++ "\tvol:" + vol ++ "\n";
128 if (setStr.size > 0) {
129 setStr = "(\n" ++ setStr ++ "\n)";
131 ^(".playN" ++ setStr ++ ";\n");
134 playNDialog { | bounds, usePlayN |
135 var doc = this.playEditString(usePlayN).newTextWindow("edit outs:");
136 try { doc.bounds_(bounds) }; // swingosc safe
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);
149 doc !? { doc.front.selectRange(startSel, 0); }
152 asCode { | includeSettings = true, includeMonitor = true, envir |
153 var nameStr, srcStr, str, docStr, indexStr, key;
156 var isAnon, isSingle, isInCurrent, isOnDefault, isMultiline;
158 envir = envir ? currentEnvironment;
160 nameStr = envir.use { this.asCompileString };
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));
176 docStr = String.streamContents { arg stream;
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 ++ ")" };
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
197 str = nameStr ++ ";\n";
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";
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);
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)
229 isMultiline = docStr.drop(-1).includes(Char.nl);
230 if (isMultiline) { docStr = "(\n" ++ docStr ++ ");\n" };
235 document { | includeSettings = true, includeMonitor = true |
236 ^this.asCode(includeSettings, includeMonitor).newTextWindow("document :" + this.asCompileString)
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 ++ ")" };
261 ^(a.envirCompileString ? "") ++ " " ++ operator
270 // where am I globally accessible?
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);
279 if (ProxySpace.all.includes(this)) {
280 key = ProxySpace.all.findKeyForValue(this);
281 ^"ProxySpace.all[%]".format(key.asCompileString);
284 ^"/***( cannot locate this proxyspace )***/"
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
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
305 var proxy = envir.at(key);
306 stream << proxy.asCode(includeSettings, includeMonitors, this.envir) << "\n";
309 stream << /*(*/ ");\n";
313 ^this.document(nil, true)
316 document { | keys, onlyAudibleOutput = false, includeSettings = true |
318 if(onlyAudibleOutput) {
319 keys = this.monitors.collect { arg item; item.key(envir) };
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"
329 ^str.newTextWindow((name ? "proxyspace").asString)
336 storeOn { | stream, namestring = "", dropOut = false |
337 var strippedSetArgs, storedSetNArgs, rates, proxyMapKeys, proxyMapNKeys;
340 forBy(0, setArgs.size - 1, 2, { arg i;
343 if(item !== 'out' and: { item !== 'i_out' })
345 strippedSetArgs = strippedSetArgs.add(item);
346 strippedSetArgs = strippedSetArgs.add(setArgs[i+1]);
349 } { strippedSetArgs = setArgs };
350 if(strippedSetArgs.notNil) {
351 stream << namestring << ".set(" <<<* strippedSetArgs << ");" << Char.nl;
354 if(mapArgs.notNil or: { mapnArgs.notNil }) {
355 settings.keysValuesDo { arg key, setting;
357 if(setting.isMapped) {
358 proxy = setting.value;
360 if(setting.isMultiChannel) {
361 proxyMapNKeys = proxyMapNKeys.add(key);
362 proxyMapNKeys = proxyMapNKeys.add(proxy);
364 proxyMapKeys = proxyMapKeys.add(key);
365 proxyMapKeys = proxyMapKeys.add(proxy);
370 if(proxyMapKeys.notNil) {
371 stream << namestring << ".map(" <<<* proxyMapKeys << ");" << Char.nl;
373 if(proxyMapNKeys.notNil) {
374 stream << namestring << ".mapn(" <<<* proxyMapNKeys << ");" << Char.nl;
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);
386 stream << namestring << ".setn(" <<<* storedSetNArgs << ");" << Char.nl;
388 settings.keysValuesDo { arg key, setting;
389 if(setting.rate.notNil) { rates = rates.add(key); rates = rates.add(setting.rate) };
392 stream << namestring << ".setRates(" <<<* rates << ");" << Char.nl;