1 //watches a server address for node-related messages
5 var <server, <responders;
9 ^super.new.ninit(server)
12 ninit { arg argServer;
17 server.addr.asArray.do({ arg addrItem; //support for multiple addresses
18 this.cmds.do({ arg cmd;
20 method = cmd.copyToEnd(1).asSymbol;
21 responders = responders.add(
22 OSCFunc({ arg msg; this.respond(method, msg) }, cmd, addrItem).disable
32 respond { arg method, msg;
33 this.performList(method, msg.drop(1))
38 responders.do({ arg item; item.enable });
44 responders.do({ arg item; item.free });
54 BasicNodeWatcher : AbstractNodeWatcher {
57 nodeIsPlaying { arg nodeID;
58 ^nodes.includes(nodeID);
60 nodeIsPlaying_ { arg nodeID;
61 //sometimes it is needed to set this before the server reply
66 nodes = IdentitySet.new;
69 cmds { ^#["/n_go", "/n_end"] }
82 ///////////////////////////////////
83 //watches registered nodes and sets their isPlaying/isRunning flag.
84 //a node needs to be registered to be addressed, other nodes are ignored.
86 NodeWatcher : BasicNodeWatcher {
91 all = IdentityDictionary.new;
95 *cmdPeriod { all.do { arg item; item.clear } }
97 *newFrom { arg server;
99 res = all.at(server.name);
101 res = this.new(server);
103 all.put(server.name, res)
108 *register { arg node, assumePlaying=false;
110 watcher = this.newFrom(node.server);
111 watcher.register(node, assumePlaying);
114 *unregister { arg node;
116 watcher = this.newFrom(node.server);
117 watcher.unregister(node);
120 cmds { ^#["/n_go", "/n_end", "/n_off", "/n_on"] }
121 respond { arg method, msg;
123 node = nodes.at(msg.at(1));
125 group = nodes.at(msg.at(2));
126 this.performList(method, node, group)
132 node.isPlaying = false;
133 node.isRunning = false;
134 node.changed(\n_end);
136 nodes = IdentityDictionary.new
139 register { arg node, assumePlaying=false;
140 if(server.serverRunning.not) { nodes.removeAll; ^this };
142 if(assumePlaying and: { nodes.at(node.nodeID).isNil }) { node.isPlaying = true };
143 nodes.put(node.nodeID, node);
147 unregister { arg node;
148 nodes.removeAt(node.nodeID);
152 //////////////private implementation//////////////
155 node.isPlaying = true;
156 node.isRunning = true;
157 node.changed(\n_go); // notify all the node's dependents of the change
161 this.unregister(node);
162 node.isPlaying = false;
163 node.isRunning = false;
164 node.changed(\n_end);
168 node.isRunning = false;
169 node.changed(\n_off);
173 node.isRunning = true;
180 DebugNodeWatcher : BasicNodeWatcher {
182 cmds { ^#["/n_go", "/n_end", "/n_off", "/n_on"] }
184 //////////////private implementation//////////////
186 doPost { arg action, nodeID, groupID, prevID, nextID;
187 Post << ("[ server: " + server.name + "]" +
188 action + nodeID + "in group" + groupID + "between nodes" + prevID + "and" + nextID
192 n_go { arg nodeID, groupID, prevID, nextID;
193 this.doPost("started", nodeID, groupID, prevID, nextID);
197 n_end { arg nodeID, groupID, prevID, nextID;
198 nodes.remove(nodeID);
199 this.doPost("ended", nodeID, groupID, prevID, nextID);
202 n_off { arg nodeID, groupID, prevID, nextID;
203 this.doPost("turned off", nodeID, groupID, prevID, nextID);
206 n_on { arg nodeID, groupID, prevID, nextID;
207 this.doPost("turned on", nodeID, prevID, nextID);