class library: Reset has been renamed to OnError
[supercollider.git] / SCClassLibrary / JITLib / ProxySpace / NodeMap.sc
blob7a696471bf8cbba2b1d7fab961aad250c1becacd
1 // used to bundle and cache set, map, mapa, setn, mapn, mapna commands.
4 NodeMap {
5         var <>settings; // cache args:
6         var <>upToDate, <>setArgs, <>setnArgs, <>mapArgs, <>mapnArgs, <>mapaArgs, <>mapanArgs;
7         var controlNames;
9         *new {
10                 ^super.new.clear
11         }
13         settingClass {
14                 ^NodeMapSetting
15         }
18         clear {
19                 settings = IdentityDictionary.new;
20                 upToDate = false;
21         }
24         map { arg ... args;
25                 forBy(0, args.size-1, 2, { arg i;
26                         this.get(args.at(i)).map(args.at(i+1));
27                 });
28                 upToDate = false;
29         }
31         mapa { arg ... args;
32                 forBy(0, args.size-1, 2, { arg i;
33                         this.get(args.at(i)).mapa(args.at(i+1));
34                 });
35                 upToDate = false;
36         }
38         unmap { arg ... keys;
39                 keys.do { arg key;
40                         var setting;
41                         setting = settings.at(key);
42                         if(setting.notNil and: { setting.isMapped }) {
43                                 setting.map(nil, nil);
44                                 if(setting.isEmpty) { settings.removeAt(key) }
45                         };
46                 };
47                 upToDate = false;
49         }
51         set { arg ... args;
52                 forBy(0, args.size-1, 2, { arg i;
53                         this.get(args.at(i)).set(args.at(i+1));
54                 });
55                 upToDate = false;
56         }
58         setn { arg ... args; this.set(*args)  }
61         unset { arg ... keys;
62                 keys.do { arg key;
63                         var setting;
64                         setting = settings.at(key);
65                         if(setting.notNil and: { setting.isMapped.not }) {
66                                 setting.map(nil, nil);
67                                 if(setting.isEmpty) { settings.removeAt(key) }
68                         };
69                 };
70                 upToDate = false;
71         }
73         mapn { arg ... args;
74                 forBy(0, args.size-1, 3, { arg i;
75                         this.get(args.at(i)).mapn(args.at(i+1), args.at(i+2));
76                 });
77                 upToDate = false;
78         }
80         mapan { arg ... args;
81                 forBy(0, args.size-1, 3, { arg i;
82                         this.get(args.at(i)).mapan(args.at(i+1), args.at(i+2));
83                 });
84                 upToDate = false;
85         }
87         send { arg server, nodeID, latency;
88                 var bundle;
89                 bundle = List.new;
90                 this.addToBundle(bundle, nodeID);
91                 server.listSendBundle(latency, bundle);
92         }
94         sendToNode { arg node, latency;
95                 node = node.asTarget;
96                 this.send(node.server, node.nodeID, latency)
97         }
99         controlNames {
100                 this.updateBundle;
101                 ^controlNames
102         }
104         get { arg key;
105                 var setting;
106                 setting = settings.at(key);
107                 if(setting.isNil, {
108                         setting = this.settingClass.new(key);
109                         settings.put(key, setting)
110                 });
111                 ^setting
112         }
114         at { arg key;
115                 ^settings.at(key)
116         }
118         settingKeys {
119                 var res;
120                 settings.do { arg item; if(item.isMapped.not) { res = res.add(item.key) } };
121                 ^res
122         }
123         mappingKeys {
124                 var res;
125                 settings.do { arg item; if(item.isMapped) { res = res.add(item.key) } };
126                 ^res
127         }
129         updateBundle {
130                         if(upToDate.not) {
131                                 upToDate = true;
132                                 setArgs = setnArgs = mapArgs = mapnArgs = mapaArgs = mapanArgs = nil;
133                                 settings.do { arg item; item.updateNodeMap(this) };
134                                 controlNames = settings.values.collect { |setting|
135                                         ControlName(setting.key, nil, setting.mappedRate, setting.value)
136                                 }
137                         }
138         }
140         addToEvent { arg event;
141                 settings.do { |x| x.addToEvent(event) }
142         }
144         addToBundle { arg bundle, target;
145                         var msgs;
146                         target = target.asNodeID;
147                         this.updateBundle;
148                         if(setArgs.notNil) { bundle.add([15, target] ++ setArgs) };
149                         if(setnArgs.notNil) { bundle.add([16, target] ++ setnArgs) };
150                         if(mapArgs.notNil) { bundle.add([14, target] ++ mapArgs) };
151                         if(mapnArgs.notNil) { bundle.add([48, target] ++ mapnArgs) };
152                         if(mapaArgs.notNil) { bundle.add([60, target] ++ mapaArgs) };
153                         if(mapanArgs.notNil) { bundle.add([61, target] ++ mapanArgs) };
154         }
156         unsetArgsToBundle { arg bundle, target, keys;
157                 var args;
158                 if(settings.isEmpty) { ^this };
159                 (keys ?? { settings.keys }).do { arg key;
160                         var item;
161                         item = settings[key];
162                         if(item.notNil) { args = args ++ [key, -1] }
163                 };
164                 if(args.notNil) { bundle.add([15, target.asNodeID] ++ args) };
165         }
167         unmapArgsToBundle { arg bundle, target, keys;
168                 var args;
169                 if(settings.isEmpty) { ^this };
170                 (keys ?? { settings.keys }).do { arg key;
171                         var item;
172                         item = settings[key];
173                         if(item.notNil and: { item.isMapped }) {
174                                         args = args ++ [key, -1, item.busNumChannels];
175                         };
176                 };
177                 if(args.notNil) { bundle.add([48, target.asNodeID] ++ args) };
178         }
180         blend { arg another, frac;
181                 var res = this.copy;
182                 another.updateBundle;
183                 another.setArgs.pairsDo { |key, x|
184                         var s = settings[key], y;
185                         s !? { y = s.getValue };
186                         y !? { res.set(key, blend(y, x, frac)) }
187                 };
188                 ^res
189         }
192         copy {
193                 var res, nset;
194                 res = this.class.new;
195                 nset = res.settings;
196                 settings.keysValuesDo({ arg key, val; nset.put(key, val.copy) });
197                 ^res
198         }
200         printOn { arg stream;
201                 stream << this.class.name << "(";
202                 settings.printItemsOn(stream);
203                 stream << ")"
204         }
210 ProxyNodeMap : NodeMap {
212                 var <>parents, <>proxy;
213                 var hasRates=false;
215                 clear {
216                         super.clear;
217                         parents = IdentityDictionary.new;
218                 }
220                 settingClass {
221                         ^ProxyNodeMapSetting
222                 }
224                 wakeUpParentsToBundle { arg bundle, checkedAlready;
225                         parents.do({ arg item; item.wakeUpToBundle(bundle, checkedAlready) });
226                 }
228                 setRates { arg args;
229                         forBy(0, args.size-1, 2, { arg i;
230                                 var key, rate, setting;
231                                 key = args[i];
232                                 setting = this.get(key);
233                                 rate = args[i+1];
234                                 if(rate.isNil and: { setting.notNil } and: { setting.isEmpty })
235                                 { settings.removeAt(key) }
236                                 { setting.rate_(rate) };
237                         });
238                         hasRates = settings.any { arg item; item.rate.notNil };
239                 }
241                 ratesFor { arg keys;
242                         ^if(hasRates) {
243                                 keys.collect({ arg key;
244                                         var res;
245                                         res = settings.at(key);
246                                         if(res.notNil, { res.rate }, { nil })
247                                 })
248                         } { nil }
249                 }
251                 mapn { arg ... args;
252                         this.map(args) // for now, avoid errors.
253                 }
255                 map { arg ... args;
256                         var playing;
257                         playing = proxy.isPlaying;
258                         args.pairsDo { arg key, mapProxy;
259                                 var setting, numChannels;
260                                 if(mapProxy.isKindOf(BusPlug).not) { Error("map: not a node proxy").throw };
261                                 if(playing) { mapProxy.wakeUp };
262                                 setting = this.get(key);
263                                 setting.map(mapProxy);
264                                 parents = parents.put(key, mapProxy);
265                         };
266                         upToDate = false;
267                 }
269                 mapEnvir { arg ... keys;
270                         var args;
271                         keys = keys ? settings.keys;
272                         args = Array.new(keys.size*2);
273                         keys.do({ arg key; args.add(key); args.add(currentEnvironment.at(key)) });
274                         this.map(*args);
275                 }
277                 unmap { arg ... keys;
278                         var setting;
279                         if(keys.at(0).isNil, { keys = this.mappingKeys });
280                         keys.do({ arg key;
281                                 setting = settings.at(key);
282                                 if(setting.notNil, {
283                                         setting.map(nil, nil);
284                                         parents.removeAt(key);
285                                         if(setting.isEmpty, { settings.removeAt(key) })
286                                 });
287                         });
288                         upToDate = false;
289                 }