Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / SCClassLibrary / Common / Control / OSCpathResponder.sc
blob9e1b30bf32521e9d13717158727752d852e40982
1 /*
2 OSCpathDispatcher dispatches OSC commands to OSCpathResponder 's.
3 It is also an OSCMultiResponder, so it distributes a command to
4 any OSCresponderNode's assigned to that command.
6 path: an array of the indices in the OSC message that are the path values
8 */
9 OSCpathDispatcher : OSCMultiResponder {
11         classvar <>cmdPathIndices;
13         var <>pathResponders;
14         var <>maxPathSize = 0;
16         *new {  arg addr, cmdName, action, pathSize;
17                 ^super.new(addr, cmdName, action).initPathSize(pathSize);
18         }
19         initPathSize { arg pathSize;
20                 maxPathSize = pathSize;
21                 pathResponders = Set.new;
22         }
23         value { arg time, msg;
24                 var cmdPath, match, responder;
25                 super.value(time, msg);
26                 if (maxPathSize.notNil, {
27                         cmdPath = [cmdName] ++ msg[1..maxPathSize];
28                         responder = OSCpathResponder(addr, cmdPath);
29                         match = pathResponders.findMatch(responder);
30                         if (match.notNil, {
31                                 match.value(time, msg);
32                         });
33                         (maxPathSize - 1).do({ arg i;
34                                 responder.path.removeAt(responder.path.size - 1);
35                                 match = pathResponders.findMatch(responder);
36                                 if (match.notNil, {
37                                         match.value(time, msg);
38                                 });
39                         });
40                 });
41         }
42         addChild { arg responder;
43                 var old;
44                 old = pathResponders.findMatch(responder);
45                 if(old.notNil,{ pathResponders.remove(old) });
46                 pathResponders.add(responder);
47                 if(responder.path.size > maxPathSize) { maxPathSize = responder.path.size };
48         }
49         removeChild { arg responder;
50                  pathResponders.remove(responder);
51                  if(responder.path.size == maxPathSize) {
52                         maxPathSize = pathResponders.maxValue({ |resp| resp.path.size }) ? 0;
53                  };
54                  if(this.isEmpty) { this.remove };
55         }
57         isEmpty { ^(nodes.size + pathResponders.size) == 0 }
60 OSCpathResponder : OSCresponder {
61         var <>path;
62         var <>dispatcher;
64         *new { arg addr, cmdPath, action;
65                 var cmdName, path;
66                 #cmdName ...path = cmdPath;
67                 ^super.new(addr, cmdName, action).path_(path);
68         }
70         findDispatcher {
71                 var responder, match, pathIndices;
72                 responder = OSCpathDispatcher(addr, cmdName, nil, path.size);
73                 match = OSCresponder.all.findMatch(responder);
74                 if(match.isNil, { ^responder.add });
75                 if (match.class === OSCresponder,  {
76                         match.remove;
77                         responder.nodes_([match]);
78                         ^responder.add
79                 });
80                 if (match.class === OSCMultiResponder, {
81                         match.remove;
82                         responder.nodes_(match.nodes);
83                         ^responder.add;
84                 });
85                 ^match;
86         }
87         add {
88                 dispatcher = this.findDispatcher;
89                 dispatcher.addChild(this);
90         }
92         remove {
93                 dispatcher.removeChild(this);
94         }
96         == { arg that;
97                 ^that respondsTo: \path and: { path == that.path }
98         }
99         hash { ^path.hash }
104         var s, commandpath, response, aSynth, nodeID, triggerID;
105         s = Server.local;
106         s.boot;
107         triggerID = 1;
108         aSynth = {arg freq = 1, triggerID = 1; SendTrig.kr(SinOsc.kr(freq), triggerID, 666); }.play;
109         nodeID = aSynth.nodeID;
110         commandpath = ['/tr', nodeID, triggerID];
111         response = { arg time, responder, message; message.postln };
113         o = OSCpathResponder(s.addr, commandpath, response);
114         o.add;
118 o.remove
121         var s, commandpath, response, aSynth, nodeID, triggerID;
122         s = Server.local;
123         commandpath = ['/tr', nil, triggerID];
124         response = { arg time, responder, message; message.postln };
126         o = OSCpathResponder(s.addr, commandpath, response);
127         o.add;