cmake build system: visiblity support for clang
[supercollider.git] / SCClassLibrary / Common / Control / OSCresponder.sc
blobf3c9319e8d3ea141ff26d73dc0e7d0e90e86e17e
1 OSCresponder {
2         classvar <>all;
3         var <>addr, <cmdName, <>action;
4         var <cmdNameWithoutSlash;
6         *new { arg addr, cmdName, action;
7                 ^super.new.init(addr, cmdName, action);
8         }
10         *initClass {
11                 all = Set.new;
12         }
14         init { arg argAddr, argCmdName, argAction;
15                 addr = argAddr;
16                 action = argAction;
17                 this.cmdName = argCmdName;
18         }
20         cmdName_ { arg string;
21                 string = string.asString;
22                 if(string[0] == $/) { string = string.drop(1) };
23                 cmdNameWithoutSlash = string.asSymbol;
24                 cmdName = ("/" ++ string).asSymbol;
25         }
28         *respond { arg time, addr, msg;
29                 var cmdName, hit = false;
30                 #cmdName = msg;
31                 all.do { |resp|
32                         if(
33                                 (resp.cmdName === cmdName)
34                                 or:
35                                 { resp.cmdNameWithoutSlash === cmdName }
36                                 and: { addr.matches(resp.addr) }
37                         ) {
38                                 resp.value(time, msg, addr);
39                                 hit = true;
40                         };
41                 };
42                 ^hit
43         }
45         *add { arg responder;
46                 var old;
47                 old = all.findMatch(responder);
48                 if(old.notNil,{ all.remove(old) });
49                 all.add(responder);
50         }
51         *remove { arg responder;
52                 all.remove(responder);
53         }
54         *removeAddr { arg addr;
55                 all = all.reject({ arg item;
56                         item.addr == addr
57                 });
58         }
60         value { arg time, msg, addr;
61                 action.value(time, this, msg, addr);
62         }
63         == { arg that;
64                 ^that respondsTo: #[\cmdName, \addr]
65                         and: { cmdName == that.cmdName and: { addr == that.addr }}
66         }
67         hash {
68                 ^addr.hash bitXor: cmdName.hash
69         }
70         add { this.class.add(this); }
71         remove { all.remove(this) }
72         removeWhenDone {
73                 var func;
74                 func = action;
75                 action = { arg time, responder, msg, addr;
76                         func.value(time, responder, msg, addr);
77                         this.remove;
78                 }
79         }
83 //used to manage OSCresponderNodes. do not use directly.
85 OSCMultiResponder : OSCresponder {
86         var <>nodes;
88         value { arg time, msg, addr;
89                 var iterlist;
90                 iterlist = nodes.copy;
91                 iterlist.do({ arg node; node.value(time, msg, addr) });
92         }
93         isEmpty { ^nodes.size == 0 }
98 OSCresponderNode : OSCresponder {
100         var <added = false;
102         add {
103                 var made, found;
104                 if(added.not, {
105                         made = OSCMultiResponder(addr, cmdName);
106                         found = all.findMatch(made);
107                         if(found.isNil, { made.nodes = [this]; made.add; added = true; ^this });
108                         if (found.class === OSCresponder, {
109                                 found.remove;
110                                 made.nodes = [found, this];
111                                 made.add;
112                         },{
113                                 found.nodes = found.nodes.add(this)
114                         });
115                         added = true;
116                 })
117         }
119         removeWhenDone {
120                 var func;
121                 func = action;
122                 action = { arg time, responder, msg, addr;
123                         func.value(time, responder, msg, addr);
124                         this.remove;
125                 }
126         }
128         remove {
129                 var resp, alreadyThere;
130                 resp = OSCMultiResponder(addr, cmdName);
131                 alreadyThere = all.findMatch(resp);
132                 if(alreadyThere.notNil)
133                 {
134                         alreadyThere.nodes.remove(this);
135                         if(alreadyThere.isEmpty, { alreadyThere.remove });
136                         added = false;
137                 };
138         }
140         value { arg time, msg, addr;
141                 action.value(time, this, msg, addr);
142         }