29#ifndef RTOSC_PORT_SUGAR
30#define RTOSC_PORT_SUGAR
35#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ <= 7)
37struct rtosc_hack_decltype_t
42#define decltype(expr) rtosc_hack_decltype_t<decltype(expr)>::type
48#define STRINGIFY2(a) #a
49#define STRINGIFY(a) STRINGIFY2(a)
52#define IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,N, ...) N
53#define LAST_IMP(...) IMPL(__VA_ARGS__,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
54#define DOC_IMP24(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x) \
55 a b c d e f g h i j k l m n o p q r s t u v w rDoc(x)
56#define DOC_IMP23(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w) \
57 a b c d e f g h i j k l m n o p q r s t u v rDoc(w)
58#define DOC_IMP22(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v) \
59 a b c d e f g h i j k l m n o p q r s t u rDoc(v)
60#define DOC_IMP21(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u) \
61 a b c d e f g h i j k l m n o p q r s t rDoc(u)
62#define DOC_IMP20(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t) \
63 a b c d e f g h i j k l m n o p q r s rDoc(t)
64#define DOC_IMP19(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s) \
65 a b c d e f g h i j k l m n o p q r rDoc(s)
66#define DOC_IMP18(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r) \
67 a b c d e f g h i j k l m n o p q rDoc(r)
68#define DOC_IMP17(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q) \
69 a b c d e f g h i j k l m n o p rDoc(q)
70#define DOC_IMP16(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
71 a b c d e f g h i j k l m n o rDoc(p)
72#define DOC_IMP15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) \
73 a b c d e f g h i j k l m n rDoc(o)
74#define DOC_IMP14(a,b,c,d,e,f,g,h,i,j,k,l,m,n) \
75 a b c d e f g h i j k l m rDoc(n)
76#define DOC_IMP13(a,b,c,d,e,f,g,h,i,j,k,l,m) \
77 a b c d e f g h i j k l rDoc(m)
78#define DOC_IMP12(a,b,c,d,e,f,g,h,i,j,k,l) a b c d e f g h i j k rDoc(l)
79#define DOC_IMP11(a,b,c,d,e,f,g,h,i,j,k) a b c d e f g h i j rDoc(k)
80#define DOC_IMP10(a,b,c,d,e,f,g,h,i,j) a b c d e f g h i rDoc(j)
81#define DOC_IMP9(a,b,c,d,e,f,g,h,i) a b c d e f g h rDoc(i)
82#define DOC_IMP8(a,b,c,d,e,f,g,h) a b c d e f g rDoc(h)
83#define DOC_IMP7(a,b,c,d,e,f,g) a b c d e f rDoc(g)
84#define DOC_IMP6(a,b,c,d,e,f) a b c d e rDoc(f)
85#define DOC_IMP5(a,b,c,d,e) a b c d rDoc(e)
86#define DOC_IMP4(a,b,c,d) a b c rDoc(d)
87#define DOC_IMP3(a,b,c) a b rDoc(c)
88#define DOC_IMP2(a,b) a rDoc(b)
89#define DOC_IMP1(a) rDoc(a)
90#define DOC_IMP0() YOU_MUST_DOCUMENT_YOUR_PORTS
91#define DOC_IMP(count, ...) DOC_IMP ##count(__VA_ARGS__)
92#define DOC_I(count, ...) DOC_IMP(count,__VA_ARGS__)
93#define DOC(...) DOC_I(LAST_IMP(__VA_ARGS__), __VA_ARGS__)
96#define rINC(x) rINC_ ## x
117#define MAC_EACH_0(o,m,d,x, ...) INSUFFICIENT_ARGUMENTS_PROVIDED_TO_MAC_EACH
118#define MAC_EACH_1(o,m,d,x, ...) m(o,d,x)
119#define MAC_EACH_2(o,m,d,x, ...) m(o,d,x) MAC_EACH_1(rINC(o),m,d, __VA_ARGS__)
120#define MAC_EACH_3(o,m,d,x, ...) m(o,d,x) MAC_EACH_2(rINC(o),m,d, __VA_ARGS__)
121#define MAC_EACH_4(o,m,d,x, ...) m(o,d,x) MAC_EACH_3(rINC(o),m,d, __VA_ARGS__)
122#define MAC_EACH_5(o,m,d,x, ...) m(o,d,x) MAC_EACH_4(rINC(o),m,d, __VA_ARGS__)
123#define MAC_EACH_6(o,m,d,x, ...) m(o,d,x) MAC_EACH_5(rINC(o),m,d, __VA_ARGS__)
124#define MAC_EACH_7(o,m,d,x, ...) m(o,d,x) MAC_EACH_6(rINC(o),m,d, __VA_ARGS__)
125#define MAC_EACH_8(o,m,d,x, ...) m(o,d,x) MAC_EACH_7(rINC(o),m,d, __VA_ARGS__)
126#define MAC_EACH_9(o,m,d,x, ...) m(o,d,x) MAC_EACH_8(rINC(o),m,d, __VA_ARGS__)
127#define MAC_EACH_10(o,m,d,x, ...) m(o,d,x) MAC_EACH_9(rINC(o),m,d, __VA_ARGS__)
128#define MAC_EACH_11(o,m,d,x, ...) m(o,d,x) MAC_EACH_10(rINC(o),m,d, __VA_ARGS__)
129#define MAC_EACH_12(o,m,d,x, ...) m(o,d,x) MAC_EACH_11(rINC(o),m,d, __VA_ARGS__)
130#define MAC_EACH_13(o,m,d,x, ...) m(o,d,x) MAC_EACH_12(rINC(o),m,d, __VA_ARGS__)
131#define MAC_EACH_14(o,m,d,x, ...) m(o,d,x) MAC_EACH_13(rINC(o),m,d, __VA_ARGS__)
132#define MAC_EACH_15(o,m,d,x, ...) m(o,d,x) MAC_EACH_14(rINC(o),m,d, __VA_ARGS__)
133#define MAC_EACH_16(o,m,d,x, ...) m(o,d,x) MAC_EACH_15(rINC(o),m,d, __VA_ARGS__)
135#define MAC_EACH_IMP(off, mac, data, count, ...) \
136 MAC_EACH_ ##count(off, mac, data, __VA_ARGS__)
137#define MAC_EACH_I(off, mac, data, count, ...) \
138 MAC_EACH_IMP(off, mac, data, count, __VA_ARGS__)
139#define MAC_EACH_OFF(off, mac, data, ...) \
140 MAC_EACH_I(off, mac, data, LAST_IMP(__VA_ARGS__), __VA_ARGS__)
141#define MAC_EACH(mac, data, ...) MAC_EACH_OFF(0, mac, data, __VA_ARGS__)
144#define OPTIONS_IMP24(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x) \
145 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
146 rOpt(7,h) rOpt(8,i) rOpt(9,j) rOpt(10,k)rOpt(11,l)rOpt(12,m)rOpt(13,n)\
147 rOpt(14,o)rOpt(15,p)rOpt(16,q)rOpt(17,r)rOpt(18,s)rOpt(19,t)rOpt(20,u)\
148 rOpt(21,v)rOpt(22,w)rOpt(23,x)
150#define OPTIONS_IMP23(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w) \
151 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
152 rOpt(7,h) rOpt(8,i) rOpt(9,j) rOpt(10,k)rOpt(11,l)rOpt(12,m)rOpt(13,n)\
153 rOpt(14,o)rOpt(15,p)rOpt(16,q)rOpt(17,r)rOpt(18,s)rOpt(19,t)rOpt(20,u)\
156#define OPTIONS_IMP22(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v) \
157 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
158 rOpt(7,h) rOpt(8,i) rOpt(9,j) rOpt(10,k)rOpt(11,l)rOpt(12,m)rOpt(13,n)\
159 rOpt(14,o)rOpt(15,p)rOpt(16,q)rOpt(17,r)rOpt(18,s)rOpt(19,t)rOpt(20,u)\
162#define OPTIONS_IMP21(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u) \
163 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
164 rOpt(7,h) rOpt(8,i) rOpt(9,j) rOpt(10,k)rOpt(11,l)rOpt(12,m)rOpt(13,n)\
165 rOpt(14,o)rOpt(15,p)rOpt(16,q)rOpt(17,r)rOpt(18,s)rOpt(19,t)rOpt(20,u)
167#define OPTIONS_IMP20(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t) \
168 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
169 rOpt(7,h) rOpt(8,i) rOpt(9,j) rOpt(10,k)rOpt(11,l)rOpt(12,m)rOpt(13,n)\
170 rOpt(14,o)rOpt(15,p)rOpt(16,q)rOpt(17,r)rOpt(18,s)rOpt(19,t)
172#define OPTIONS_IMP19(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s) \
173 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
174 rOpt(7,h) rOpt(8,i) rOpt(9,j) rOpt(10,k)rOpt(11,l)rOpt(12,m)rOpt(13,n)\
175 rOpt(14,o)rOpt(15,p)rOpt(16,q)rOpt(17,r)rOpt(18,s)
177#define OPTIONS_IMP18(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r) \
178 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
179 rOpt(7,h) rOpt(8,i) rOpt(9,j) rOpt(10,k)rOpt(11,l)rOpt(12,m)rOpt(13,n)\
180 rOpt(14,o)rOpt(15,p)rOpt(16,q)rOpt(17,r)
181#define OPTIONS_IMP17(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q) \
182 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
183 rOpt(7,h) rOpt(8,i) rOpt(9,j) rOpt(10,k)rOpt(11,l)rOpt(12,m)rOpt(13,n)\
184 rOpt(14,o)rOpt(15,p)rOpt(16,q)
185#define OPTIONS_IMP16(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
186 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
187 rOpt(7,h) rOpt(8,i) rOpt(9,j) rOpt(10,k)rOpt(11,l)rOpt(12,m)rOpt(13,n)\
189#define OPTIONS_IMP15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) \
190 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
191 rOpt(7,h) rOpt(8,i) rOpt(9,j) rOpt(10,k)rOpt(11,l)rOpt(12,m)rOpt(13,n)\
193#define OPTIONS_IMP14(a,b,c,d,e,f,g,h,i,j,k,l,m,n) \
194 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
195 rOpt(7,h) rOpt(8,i) rOpt(9,j) rOpt(10,k)rOpt(11,l)rOpt(12,m)rOpt(13,n)
196#define OPTIONS_IMP13(a,b,c,d,e,f,g,h,i,j,k,l,m) \
197 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
198 rOpt(7,h) rOpt(8,i) rOpt(9,j) rOpt(10,k)rOpt(11,l)rOpt(12,m)
199#define OPTIONS_IMP12(a,b,c,d,e,f,g,h,i,j,k,l) \
200 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
201 rOpt(7,h) rOpt(8,i) rOpt(9,j) rOpt(10,k)rOpt(11,l)
202#define OPTIONS_IMP11(a,b,c,d,e,f,g,h,i,j,k) \
203 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
204 rOpt(7,h) rOpt(8,i) rOpt(9,j) rOpt(10,k)
205#define OPTIONS_IMP10(a,b,c,d,e,f,g,h,i,j) \
206 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
207 rOpt(7,h) rOpt(8,i) rOpt(9,j)
208#define OPTIONS_IMP9(a,b,c,d,e,f,g,h,i) \
209 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
211#define OPTIONS_IMP8(a,b,c,d,e,f,g,h) \
212 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
214#define OPTIONS_IMP7(a,b,c,d,e,f,g) \
215 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g)
216#define OPTIONS_IMP6(a,b,c,d,e,f) \
217 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f)
218#define OPTIONS_IMP5(a,b,c,d,e) \
219 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e)
220#define OPTIONS_IMP4(a,b,c,d) \
221 rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d)
222#define OPTIONS_IMP3(a,b,c) \
223 rOpt(0,a) rOpt(1,b) rOpt(2,c)
224#define OPTIONS_IMP2(a,b) \
226#define OPTIONS_IMP1(a) \
228#define OPTIONS_IMP0() YOU_MUST_PROVIDE_OPTIONS
229#define OPTIONS_IMP(count, ...) OPTIONS_IMP ##count(__VA_ARGS__)
230#define OPTIONS_I(count, ...) OPTIONS_IMP(count, __VA_ARGS__)
231#define OPTIONS(...) OPTIONS_I(LAST_IMP(__VA_ARGS__), __VA_ARGS__)
237#define rCrossBroadcast(loc, cross) \
238 char part_loc[128]; \
239 strncpy(part_loc, loc, sizeof(part_loc)); \
240 part_loc[sizeof(part_loc) - 1] = '\0'; \
241 char *end = strrchr(part_loc, '/'); \
243 strcpy(&end[1], STRINGIFY(cross)); \
244 data.broadcast(part_loc, "f", obj->cross); \
248#define rParam(name, ...) \
249 {STRINGIFY(name) "::c", rProp(parameter) rMap(min, 0) rMap(max, 127) DOC(__VA_ARGS__), NULL, rParamCb(name)}
250#define rParamF(name, ...) \
251 {STRINGIFY(name) "::f", rProp(parameter) DOC(__VA_ARGS__), NULL, rParamFCb(name)}
252#define rParamI(name, ...) \
253 {STRINGIFY(name) "::i", rProp(parameter) DOC(__VA_ARGS__), NULL, rParamICb(name)}
254#define rToggle(name, ...) \
255 {STRINGIFY(name) "::T:F",rProp(parameter) DOC(__VA_ARGS__), NULL, rToggleCb(name)}
256#define rOption(name, ...) \
257 {STRINGIFY(name) "::i:c:S",rProp(parameter) rProp(enumerated) DOC(__VA_ARGS__), NULL, rOptionCb(name)}
260#define rArrayF(name, length, ...) \
261{STRINGIFY(name) "#" STRINGIFY(length) "::f", rProp(parameter) DOC(__VA_ARGS__), NULL, rArrayFCb(name)}
262#define rArrayT(name, length, ...) \
263{STRINGIFY(name) "#" STRINGIFY(length) "::T:F", rProp(parameter) DOC(__VA_ARGS__), NULL, rArrayTCb(name)}
264#define rArrayI(name, length, ...) \
265{STRINGIFY(name) "#" STRINGIFY(length) "::i", rProp(parameter) DOC(__VA_ARGS__), NULL, rArrayICb(name)}
266#define rArrayOption(name, length, ...) \
267{STRINGIFY(name) "#" STRINGIFY(length) "::i:c:S", rProp(parameter) DOC(__VA_ARGS__), NULL, rArrayOptionCb(name)}
268#define rArray rArrayI
271#define rAction(name, ...) \
272{STRINGIFY(name) ":", DOC(__VA_ARGS__), NULL, rActionCb(name)}
273#define rActioni(name, ...) \
274{STRINGIFY(name) ":i", DOC(__VA_ARGS__), NULL, rActioniCb(name)}
278#define rParams(name, length, ...) \
279rArray(name, length, __VA_ARGS__), \
280{STRINGIFY(name) ":", rProp(alias) rDoc("get all data from aliased array"), NULL, rParamsCb(name, length)}
283template<
class T>
constexpr T spice(T*t) {
return *t;}
286#define rRecur(name, ...) \
287 {STRINGIFY(name) "/", DOC(__VA_ARGS__), &decltype(rObject::name)::ports, rRecurCb(name)}, \
288 {STRINGIFY(name) ":", rProp(internal) rDoc("get obj pointer"), NULL, rRecurPtrCb(name)}
290#define rRecurp(name, ...) \
291 {STRINGIFY(name) "/", DOC(__VA_ARGS__), \
292 &decltype(spice(rObject::name))::ports, \
295#define rRecurs(name, length, ...) \
296 {STRINGIFY(name) "#" STRINGIFY(length)"/", DOC(__VA_ARGS__), \
297 &decltype(spice(&rObject::name[0]))::ports, \
298 rRecursCb(name, length)}
301#define rRecursp(name, length, ...) \
302 {STRINGIFY(name)"#" STRINGIFY(length) "/", DOC(__VA_ARGS__), \
303 &decltype(spice(rObject::name[0]))::ports, \
310#define rEnabledBy(portname) rMap(enabled by, portname)
311#define rEnabledByCondition(cond_name) rEnabledBy(cond_name)
312#define rEnabledCondition(cond_name, condition) \
313 {STRINGIFY(cond_name) ":", rProp(internal), NULL, rEnabledIfCb(condition)}
314#define rEnabledIfCb(condition) rBOIL_BEGIN \
315 assert(!rtosc_narguments(msg)); \
316 data.reply(loc, (condition)?"T":"F"); \
319#define rSelf(type, ...) \
320{"self:", rProp(internal) rMap(class, type) __VA_ARGS__ rDoc("port metadata"), 0, \
321 [](const char *, rtosc::RtData &d){ \
322 d.reply(d.loc, "b", sizeof(d.obj), &d.obj);}}\
325#define rDummy(name, ...) {STRINGIFY(name), rProp(dummy), NULL, [](msg_t, rtosc::RtData &){}}
326#define rString(name, len, ...) \
327 {STRINGIFY(name) "::s", rMap(length, len) rProp(parameter) DOC(__VA_ARGS__), NULL, rStringCb(name,len)}
330#define rMap(name, value) ":" STRINGIFY(name) "\0=" STRINGIFY(value) "\0"
331#define rProp(name) ":" STRINGIFY(name) "\0"
337#define rLinear(min_, max_) rMap(min, min_) rMap(max, max_) rMap(scale, linear)
338#define rLog(min_, max_) rMap(min, min_) rMap(max, max_) rMap(scale, logarithmic)
341#define rSpecial(doc) ":special\0" STRINGIFY(doc) "\0"
342#define rCentered ":centered\0"
345#define rDefault(default_value_) rMap(default, default_value_)
346#define rDefaultId(default_value_) ":default\0=\"" STRINGIFY(default_value_) "\"S\0"
348#define rPreset(no, default_value) \
349 ":default " STRINGIFY(no) "\0=" STRINGIFY(default_value) "\0"
350#define _rPreset(no, data, default_value) rPreset(no, default_value)
351#define rPresetsAt(offs, ...) MAC_EACH_OFF(offs, _rPreset, offs, __VA_ARGS__)
352#define _rPreset2(offs, data, preset_no) rPreset(preset_no, data)
353#define rPresetAtMulti(val, ...) MAC_EACH_OFF(0, _rPreset2, val, __VA_ARGS__)
354#define rPresets(...) rPresetsAt(0, __VA_ARGS__)
355#define rDefaultDepends(dep_path_) rMap(default depends, dep_path_)
356#define rDefaultMissing ""
358#define rNoDefaults ":no defaults\0"
361#define rDoc(doc) ":documentation\0=" doc "\0"
362#define rOpt(numeric,symbolic) rMap(map numeric, symbolic)
363#define rOptions(...) OPTIONS(__VA_ARGS__)
364#define rOptionsBound(...) rOptions(__VA_ARGS__), rLinear(0,LAST_IMP(__VA_ARGS__))
367#define rShort(name) ":shortname\0=" name "\0"
371#define rBOIL_BEGIN [](const char *msg, rtosc::RtData &data) { \
372 (void) msg; (void) data; \
373 rObject *obj = (rObject*) data.obj;(void) obj; \
374 const char *args = rtosc_argument_string(msg); (void) args;\
375 const char *loc = data.loc; (void) loc;\
376 auto prop = data.port->meta(); (void) prop;
380#define rLIMIT(var, convert) \
381 if(prop["min"] && var < (decltype(var)) convert(prop["min"])) \
382 var = (decltype(var)) convert(prop["min"]);\
383 if(prop["max"] && var > (decltype(var)) convert(prop["max"])) \
384 var = (decltype(var)) convert(prop["max"]);
386#define rTYPE(n) decltype(obj->n)
388#define rCAPPLY(getcode, t, setcode) if((decltype(var))(getcode) != var) data.reply("/undo_change", "s" #t #t, data.loc, static_cast<int>(getcode), var); setcode;
389#define rAPPLY(n,t) rCAPPLY(obj->n, t, obj->n = var)
391#define rParamCb(name) rBOIL_BEGIN \
392 if(!strcmp("", args)) {\
393 data.reply(loc, "c", obj->name); \
395 rTYPE(name) var = rtosc_argument(msg, 0).i; \
398 data.broadcast(loc, "c", obj->name);\
402#define rParamFCb(name) rBOIL_BEGIN \
403 if(!strcmp("", args)) {\
404 data.reply(loc, "f", obj->name); \
406 rTYPE(name) var = rtosc_argument(msg, 0).f; \
409 data.broadcast(loc, "f", obj->name);\
413#define rParamICb(name) rBOIL_BEGIN \
414 if(!strcmp("", args)) {\
415 data.reply(loc, "i", obj->name); \
417 rTYPE(name) var = rtosc_argument(msg, 0).i; \
420 data.broadcast(loc, "i", obj->name);\
424#define rCOptionCb_(getcode, setcode) { \
425 if(!strcmp("", args)) {\
426 data.reply(loc, "i", static_cast<int>(getcode)); \
427 } else if(!strcmp("s", args) || !strcmp("S", args)) { \
429 enum_key(prop, rtosc_argument(msg, 0).s); \
431 assert(!prop["min"] || \
432 var >= atoi(prop["min"])); \
433 assert(!prop["max"] || \
434 var <= atoi(prop["max"])); \
435 rCAPPLY(getcode, i, setcode) \
436 data.broadcast(loc, "i", getcode); \
440 rtosc_argument(msg, 0).i; \
442 rCAPPLY(getcode, i, setcode) \
443 data.broadcast(loc, rtosc_argument_string(msg), getcode);\
448#define rOptionCb_(name) rCOptionCb_(obj->name, obj->name = static_cast<std::remove_reference<decltype(obj->name)>::type>(var))
450#define rOptionCb(name) rBOIL_BEGIN \
454#define rCOptionCb(getcode, setcode) rBOIL_BEGIN \
455 rCOptionCb_(getcode, setcode) \
459#define rToggleCb(name) rBOIL_BEGIN \
460 if(!strcmp("", args)) {\
461 data.reply(loc, obj->name ? "T" : "F"); \
463 if(obj->name != rtosc_argument(msg, 0).T) { \
464 data.broadcast(loc, args);\
465 obj->name = rtosc_argument(msg, 0).T; \
471 while(*msg && *msg!='/') ++msg; \
472 msg = *msg ? msg+1 : msg;
474#define rRecurCb(name) rBOIL_BEGIN \
475 data.obj = &obj->name; \
477 decltype(obj->name)::ports.dispatch(msg, data); \
480#define rRecurPtrCb(name) rBOIL_BEGIN \
481 void *ptr = &obj->name; \
482 data.reply(loc, "b", sizeof(void*), &ptr); \
485#define rRecurpCb(name) rBOIL_BEGIN \
486 data.obj = obj->name; \
487 if(obj->name == NULL) return; \
489 decltype(spice(rObject::name))::ports.dispatch(msg, data); \
492#define rRecursCb(name, length) rBOILS_BEGIN \
493 data.obj = &obj->name[idx]; \
495 decltype(spice(rObject::name))::ports.dispatch(msg, data); \
498#define rRecurspCb(name) rBOILS_BEGIN \
499 data.obj = obj->name[idx]; \
501 decltype(spice(rObject::name[0]))::ports.dispatch(msg, data); \
504#define rActionCb(name) rBOIL_BEGIN obj->name(); rBOIL_END
505#define rActioniCb(name) rBOIL_BEGIN \
506 obj->name(rtosc_argument(msg,0).i); rBOIL_END
510#define rBOILS_BEGIN rBOIL_BEGIN \
511 const char *mm = msg; \
512 while(*mm && !isdigit(*mm)) ++mm; \
513 unsigned idx = atoi(mm);
515#define rBOILS_END rBOIL_END
518#define rArrayFCb(name) rBOILS_BEGIN \
519 if(!strcmp("", args)) {\
520 data.reply(loc, "f", obj->name[idx]); \
522 float var = rtosc_argument(msg, 0).f; \
524 rAPPLY(name[idx], f) \
525 data.broadcast(loc, "f", obj->name[idx]);\
528#define rArrayTCb(name) rBOILS_BEGIN \
529 if(!strcmp("", args)) {\
530 data.reply(loc, obj->name[idx] ? "T" : "F"); \
532 if(obj->name[idx] != rtosc_argument(msg, 0).T) { \
533 data.broadcast(loc, args);\
536 obj->name[idx] = rtosc_argument(msg, 0).T; \
539#define rArrayTCbMember(name, member) rBOILS_BEGIN \
540 if(!strcmp("", args)) {\
541 data.reply(loc, obj->name[idx].member ? "T" : "F"); \
543 if(obj->name[idx].member != rtosc_argument(msg, 0).T) { \
544 data.broadcast(loc, args);\
547 obj->name[idx].member = rtosc_argument(msg, 0).T; \
551#define rArrayICb(name) rBOILS_BEGIN \
552 if(!strcmp("", args)) {\
553 data.reply(loc, "i", obj->name[idx]); \
555 char var = rtosc_argument(msg, 0).i; \
557 rAPPLY(name[idx], i) \
558 data.broadcast(loc, "i", obj->name[idx]);\
563#define rArrayOptionCb(name) rBOILS_BEGIN \
564 rOptionCb_(name[idx]) \
567#define rParamsCb(name, length) rBOIL_BEGIN \
568 data.reply(loc, "b", length, obj->name); rBOIL_END
570#define rStringCb(name, length) rBOIL_BEGIN \
571 if(!strcmp("", args)) {\
572 data.reply(loc, "s", obj->name); \
574 strncpy(obj->name, rtosc_argument(msg, 0).s, length-1); \
575 obj->name[length-1] = '\0'; \
576 data.broadcast(loc, "s", obj->name);\