LMMS
Loading...
Searching...
No Matches
plugins
CarlaBase
carla
source
native-plugins
external
zynaddsubfx
rtosc
port-sugar.h
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2016 Mark McCurry
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
* DEALINGS IN THE SOFTWARE.
23
*/
24
25
#include <
assert.h
>
26
#include <type_traits>
27
28
#ifndef RTOSC_PORT_SUGAR
29
#define RTOSC_PORT_SUGAR
30
31
//Hack to workaround old incomplete decltype implementations
32
#ifdef __GNUC__
33
#ifndef __clang__
34
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ <= 7)
35
template
<
typename
T>
36
struct
rtosc_hack_decltype_t
37
{
38
typedef
T
type
;
39
};
40
41
#define decltype(expr) rtosc_hack_decltype_t<decltype(expr)>::type
42
#endif
43
#endif
44
#endif
45
46
//General macro utilities
47
#define STRINGIFY2(a) #a
48
#define STRINGIFY(a) STRINGIFY2(a)
49
50
//Helper for documenting varargs
51
#define IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,N, ...) N
52
#define LAST_IMP(...) IMPL(__VA_ARGS__,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0,0,0)
53
#define DOC_IMP9(a,b,c,d,e,f,g,h,i) a b c d e f g h rDoc(i)
54
#define DOC_IMP8(a,b,c,d,e,f,g,h) a b c d e f g rDoc(h)
55
#define DOC_IMP7(a,b,c,d,e,f,g) a b c d e f rDoc(g)
56
#define DOC_IMP6(a,b,c,d,e,f) a b c d e rDoc(f)
57
#define DOC_IMP5(a,b,c,d,e) a b c d rDoc(e)
58
#define DOC_IMP4(a,b,c,d) a b c rDoc(d)
59
#define DOC_IMP3(a,b,c) a b rDoc(c)
60
#define DOC_IMP2(a,b) a rDoc(b)
61
#define DOC_IMP1(a) rDoc(a)
62
#define DOC_IMP0() YOU_MUST_DOCUMENT_YOUR_PORTS
63
#define DOC_IMP(count, ...) DOC_IMP ##count(__VA_ARGS__)
64
#define DOC_I(count, ...) DOC_IMP(count,__VA_ARGS__)
65
#define DOC(...) DOC_I(LAST_IMP(__VA_ARGS__), __VA_ARGS__)
66
67
68
#define rINC(x) rINC_ ## x
69
#define rINC_0 1
70
#define rINC_1 2
71
#define rINC_2 3
72
#define rINC_3 4
73
#define rINC_4 5
74
#define rINC_5 6
75
#define rINC_6 7
76
#define rINC_7 8
77
#define rINC_8 9
78
#define rINC_9 10
79
#define rINC_10 11
80
#define rINC_11 12
81
#define rINC_12 13
82
#define rINC_13 14
83
#define rINC_14 15
84
#define rINC_15 16
85
86
//Helper for applying macro on varargs
87
//arguments: counting offset, macro, macro args
88
#define MAC_EACH_0(o, m, x, ...) INSUFFICIENT_ARGUMENTS_PROVIDED_TO_MAC_EACH
89
#define MAC_EACH_1(o, m, x, ...) m(o, x)
90
#define MAC_EACH_2(o, m, x, ...) m(o, x) MAC_EACH_1(rINC(o), m, __VA_ARGS__)
91
#define MAC_EACH_3(o, m, x, ...) m(o, x) MAC_EACH_2(rINC(o), m, __VA_ARGS__)
92
#define MAC_EACH_4(o, m, x, ...) m(o, x) MAC_EACH_3(rINC(o), m, __VA_ARGS__)
93
#define MAC_EACH_5(o, m, x, ...) m(o, x) MAC_EACH_4(rINC(o), m, __VA_ARGS__)
94
#define MAC_EACH_6(o, m, x, ...) m(o, x) MAC_EACH_5(rINC(o), m, __VA_ARGS__)
95
#define MAC_EACH_7(o, m, x, ...) m(o, x) MAC_EACH_6(rINC(o), m, __VA_ARGS__)
96
#define MAC_EACH_8(o, m, x, ...) m(o, x) MAC_EACH_7(rINC(o), m, __VA_ARGS__)
97
#define MAC_EACH_9(o, m, x, ...) m(o, x) MAC_EACH_8(rINC(o), m, __VA_ARGS__)
98
#define MAC_EACH_10(o, m, x, ...) m(o, x) MAC_EACH_9(rINC(o), m, __VA_ARGS__)
99
#define MAC_EACH_11(o, m, x, ...) m(o, x) MAC_EACH_10(rINC(o), m, __VA_ARGS__)
100
#define MAC_EACH_12(o, m, x, ...) m(o, x) MAC_EACH_11(rINC(o), m, __VA_ARGS__)
101
#define MAC_EACH_13(o, m, x, ...) m(o, x) MAC_EACH_12(rINC(o), m, __VA_ARGS__)
102
#define MAC_EACH_14(o, m, x, ...) m(o, x) MAC_EACH_13(rINC(o), m, __VA_ARGS__)
103
#define MAC_EACH_15(o, m, x, ...) m(o, x) MAC_EACH_14(rINC(o), m, __VA_ARGS__)
104
#define MAC_EACH_16(o, m, x, ...) m(o, x) MAC_EACH_15(rINC(o), m, __VA_ARGS__)
105
106
#define MAC_EACH_IMP(off, mac, count, ...) \
107
MAC_EACH_ ##count(off, mac,__VA_ARGS__)
108
#define MAC_EACH_I(off, mac, count, ...) \
109
MAC_EACH_IMP(off, mac, count, __VA_ARGS__)
110
#define MAC_EACH_OFF(off, mac, ...) \
111
MAC_EACH_I(off, mac, LAST_IMP(__VA_ARGS__), __VA_ARGS__)
112
#define MAC_EACH(mac, ...) MAC_EACH_OFF(0, mac, __VA_ARGS__)
113
114
// 1 2 3 4 5 6 7 8 910111213141516
115
#define OPTIONS_IMP16(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
116
rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
117
rOpt(7,h) rOpt(8,i) rOpt(9,j) rOpt(10,k)rOpt(11,l)rOpt(12,m)rOpt(13,n)\
118
rOpt(14,o)rOpt(15,p)
119
#define OPTIONS_IMP15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) \
120
rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
121
rOpt(7,h) rOpt(8,i) rOpt(9,j) rOpt(10,k)rOpt(11,l)rOpt(12,m)rOpt(13,n)\
122
rOpt(14,o)
123
#define OPTIONS_IMP14(a,b,c,d,e,f,g,h,i,j,k,l,m,n) \
124
rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
125
rOpt(7,h) rOpt(8,i) rOpt(9,j) rOpt(10,k)rOpt(11,l)rOpt(12,m)rOpt(13,n)
126
#define OPTIONS_IMP13(a,b,c,d,e,f,g,h,i,j,k,l,m) \
127
rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
128
rOpt(7,h) rOpt(8,i) rOpt(9,j) rOpt(10,k)rOpt(11,l)rOpt(12,m)
129
#define OPTIONS_IMP12(a,b,c,d,e,f,g,h,i,j,k,l) \
130
rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
131
rOpt(7,h) rOpt(8,i) rOpt(9,j) rOpt(10,k)rOpt(11,l)
132
#define OPTIONS_IMP11(a,b,c,d,e,f,g,h,i,j,k) \
133
rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
134
rOpt(7,h) rOpt(8,i) rOpt(9,j) rOpt(10,k)
135
#define OPTIONS_IMP10(a,b,c,d,e,f,g,h,i,j) \
136
rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
137
rOpt(7,h) rOpt(8,i) rOpt(9,j)
138
#define OPTIONS_IMP9(a,b,c,d,e,f,g,h,i) \
139
rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
140
rOpt(7,h) rOpt(8,i)
141
#define OPTIONS_IMP8(a,b,c,d,e,f,g,h) \
142
rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g) \
143
rOpt(7,h)
144
#define OPTIONS_IMP7(a,b,c,d,e,f,g) \
145
rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f) rOpt(6,g)
146
#define OPTIONS_IMP6(a,b,c,d,e,f) \
147
rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e) rOpt(5,f)
148
#define OPTIONS_IMP5(a,b,c,d,e) \
149
rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d) rOpt(4,e)
150
#define OPTIONS_IMP4(a,b,c,d) \
151
rOpt(0,a) rOpt(1,b) rOpt(2,c) rOpt(3,d)
152
#define OPTIONS_IMP3(a,b,c) \
153
rOpt(0,a) rOpt(1,b) rOpt(2,c)
154
#define OPTIONS_IMP2(a,b) \
155
rOpt(0,a) rOpt(1,b)
156
#define OPTIONS_IMP1(a) \
157
rOpt(0,a)
158
#define OPTIONS_IMP0() YOU_MUST_PROVIDE_OPTIONS
159
#define OPTIONS_IMP(count, ...) OPTIONS_IMP ##count(__VA_ARGS__)
160
#define OPTIONS_I(count, ...) OPTIONS_IMP(count, __VA_ARGS__)
161
#define OPTIONS(...) OPTIONS_I(LAST_IMP(__VA_ARGS__), __VA_ARGS__)
162
163
//Additional Change Callback (after parameters have been changed)
164
//This can be used to queue up interpolation or parameter regen
165
#define rChangeCb
166
167
//Normal parameters
168
#define rParam(name, ...) \
169
{STRINGIFY(name) "::c", rProp(parameter) rMap(min, 0) rMap(max, 127) DOC(__VA_ARGS__), NULL, rParamCb(name)}
170
#define rParamF(name, ...) \
171
{STRINGIFY(name) "::f", rProp(parameter) DOC(__VA_ARGS__), NULL, rParamFCb(name)}
172
#define rParamI(name, ...) \
173
{STRINGIFY(name) "::i", rProp(parameter) DOC(__VA_ARGS__), NULL, rParamICb(name)}
174
#define rToggle(name, ...) \
175
{STRINGIFY(name) "::T:F",rProp(parameter) DOC(__VA_ARGS__), NULL, rToggleCb(name)}
176
#define rOption(name, ...) \
177
{STRINGIFY(name) "::i:c:S",rProp(parameter) rProp(enumerated) DOC(__VA_ARGS__), NULL, rOptionCb(name)}
178
179
//Array operators
180
#define rArrayF(name, length, ...) \
181
{STRINGIFY(name) "#" STRINGIFY(length) "::f", rProp(parameter) DOC(__VA_ARGS__), NULL, rArrayFCb(name)}
182
#define rArray(name, length, ...) \
183
{STRINGIFY(name) "#" STRINGIFY(length) "::c:i", rProp(parameter) DOC(__VA_ARGS__), NULL, rArrayCb(name)}
184
#define rArrayT(name, length, ...) \
185
{STRINGIFY(name) "#" STRINGIFY(length) "::T:F", rProp(parameter) DOC(__VA_ARGS__), NULL, rArrayTCb(name)}
186
#define rArrayI(name, length, ...) \
187
{STRINGIFY(name) "#" STRINGIFY(length) "::i", rProp(parameter) DOC(__VA_ARGS__), NULL, rArrayICb(name)}
188
#define rArrayOption(name, length, ...) \
189
{STRINGIFY(name) "#" STRINGIFY(length) "::i:c:S", rProp(parameter) DOC(__VA_ARGS__), NULL, rArrayOptionCb(name)}
190
191
192
//Method callback Actions
193
#define rAction(name, ...) \
194
{STRINGIFY(name) ":", DOC(__VA_ARGS__), NULL, rActionCb(name)}
195
#define rActioni(name, ...) \
196
{STRINGIFY(name) ":i", DOC(__VA_ARGS__), NULL, rActioniCb(name)}
197
198
199
//Alias operators
200
#define rParams(name, length, ...) \
201
rArray(name, length, __VA_ARGS__), \
202
{STRINGIFY(name) ":", rProp(alias) rDoc("get all data from aliased array"), NULL, rParamsCb(name, length)}
203
204
205
template
<
class
T>
constexpr
T
spice
(T*
t
) {
return
*
t
;}
206
207
//Recursion [two ports in one for pointer manipulation]
208
#define rRecur(name, ...) \
209
{STRINGIFY(name) "/", DOC(__VA_ARGS__), &decltype(rObject::name)::ports, rRecurCb(name)}, \
210
{STRINGIFY(name) ":", rProp(internal) rDoc("get obj pointer"), NULL, rRecurPtrCb(name)}
211
212
#define rRecurp(name, ...) \
213
{STRINGIFY(name) "/", DOC(__VA_ARGS__), \
214
&decltype(spice(rObject::name))::ports, \
215
rRecurpCb(name)}
216
217
#define rRecurs(name, length, ...) \
218
{STRINGIFY(name) "#" STRINGIFY(length)"/", DOC(__VA_ARGS__), \
219
&decltype(spice(&rObject::name[0]))::ports, \
220
rRecursCb(name, length)}
221
222
//Technically this is a pointer pointer method...
223
#define rRecursp(name, length, ...) \
224
{STRINGIFY(name)"#" STRINGIFY(length) "/", DOC(__VA_ARGS__), \
225
&decltype(spice(rObject::name[0]))::ports, \
226
rRecurspCb(name)}
227
228
//{STRINGIFY(name) ":", rProp(internal), NULL, rRecurPtrCb(name)}
229
230
//let this recurring parameter depend on another port
231
#define rEnabledBy(portname) rMap(enabled by, portname)
232
#define rEnabledByCondition(cond_name) rEnabledBy(cond_name)
233
#define rEnabledCondition(cond_name, condition) \
234
{STRINGIFY(cond_name) ":", rProp(internal), NULL, rEnabledIfCb(condition)}
235
#define rEnabledIfCb(condition) rBOIL_BEGIN \
236
assert(!rtosc_narguments(msg)); \
237
data.reply(loc, (condition)?"T":"F"); \
238
rBOIL_END \
239
240
#define rSelf(type, ...) \
241
{"self:", rProp(internal) rMap(class, type) __VA_ARGS__ rDoc("port metadata"), 0, \
242
[](const char *, rtosc::RtData &d){ \
243
d.reply(d.loc, "b", sizeof(d.obj), &d.obj);}}\
244
245
//Misc
246
#define rDummy(name, ...) {STRINGIFY(name), rProp(dummy), NULL, [](msg_t, rtosc::RtData &){}}
247
#define rString(name, len, ...) \
248
{STRINGIFY(name) "::s", rMap(length, len) rProp(parameter) DOC(__VA_ARGS__), NULL, rStringCb(name,len)}
249
250
//General property operators
251
#define rMap(name, value) ":" STRINGIFY(name) "\0=" STRINGIFY(value) "\0"
252
#define rProp(name) ":" STRINGIFY(name) "\0"
253
254
//Scaling property
255
#define rLinear(min_, max_) rMap(min, min_) rMap(max, max_) rMap(scale, linear)
256
#define rLog(min_, max_) rMap(min, min_) rMap(max, max_) rMap(scale, logarithmic)
257
258
//Special values
259
#define rSpecial(doc) ":special\0" STRINGIFY(doc) "\0"
260
#define rCentered ":centered\0"
261
262
//Default values
263
#define rDefault(default_value_) rMap(default, default_value_)
264
#define rDefaultId(default_value_) ":default\0=\"" STRINGIFY(default_value_) "\"S\0"
265
//#define rDefaultArr(default_value_, idx_) rMap(default[idx_], default_value_)
266
#define rPreset(no, default_value) \
267
":default " STRINGIFY(no) "\0=" STRINGIFY(default_value) "\0"
268
#define rPresetsAt(offs, ...) MAC_EACH_OFF(offs, rPreset, __VA_ARGS__)
269
#define rPresets(...) rPresetsAt(0, __VA_ARGS__)
270
#define rDefaultDepends(dep_path_) rMap(default depends, dep_path_)
271
#define rDefaultMissing ""
// macro to denote yet missing default values
272
//#define rNoDefaults() ":no defaults\0" //!< this port (and all children) have no defaults
275
#define rNoWalk rProp(no walk)
276
277
//Misc properties
278
#define rDoc(doc) ":documentation\0=" doc "\0"
279
#define rOpt(numeric,symbolic) rMap(map numeric, symbolic)
280
#define rOptions(...) OPTIONS(__VA_ARGS__)
281
282
//Zest Metadata
283
#define rShort(name) ":shortname\0=" name "\0"
284
285
286
//Callback Implementations
287
#define rBOIL_BEGIN [](const char *msg, rtosc::RtData &data) { \
288
(void) msg; (void) data; \
289
rObject *obj = (rObject*) data.obj;(void) obj; \
290
const char *args = rtosc_argument_string(msg); (void) args;\
291
const char *loc = data.loc; (void) loc;\
292
auto prop = data.port->meta(); (void) prop;
293
294
#define rBOIL_END }
295
296
#define rLIMIT(var, convert) \
297
if(prop["min"] && var < (decltype(var)) convert(prop["min"])) \
298
var = convert(prop["min"]);\
299
if(prop["max"] && var > (decltype(var)) convert(prop["max"])) \
300
var = convert(prop["max"]);
301
302
#define rTYPE(n) decltype(obj->n)
303
304
//#define rAPPLY(n,t) if(obj->n != var) data.reply("undo_change", "s" #t #t, data.loc, obj->n, var); obj->n = var;
305
#define rCAPPLY(getcode, t, setcode) if(getcode != var) data.reply("undo_change", "s" #t #t, data.loc, getcode, var); setcode;
306
#define rAPPLY(n,t) rCAPPLY(obj->n, t, obj->n = var)
307
308
#define rParamCb(name) rBOIL_BEGIN \
309
if(!strcmp("", args)) {\
310
data.reply(loc, "c", obj->name); \
311
} else { \
312
rTYPE(name) var = rtosc_argument(msg, 0).i; \
313
rLIMIT(var, atoi) \
314
rAPPLY(name, c) \
315
data.broadcast(loc, "c", obj->name);\
316
rChangeCb \
317
} rBOIL_END
318
319
#define rParamFCb(name) rBOIL_BEGIN \
320
if(!strcmp("", args)) {\
321
data.reply(loc, "f", obj->name); \
322
} else { \
323
rTYPE(name) var = rtosc_argument(msg, 0).f; \
324
rLIMIT(var, atof) \
325
rAPPLY(name, f) \
326
data.broadcast(loc, "f", obj->name);\
327
rChangeCb \
328
} rBOIL_END
329
330
#define rParamICb(name) rBOIL_BEGIN \
331
if(!strcmp("", args)) {\
332
data.reply(loc, "i", obj->name); \
333
} else { \
334
rTYPE(name) var = rtosc_argument(msg, 0).i; \
335
rLIMIT(var, atoi) \
336
rAPPLY(name, i) \
337
data.broadcast(loc, "i", obj->name);\
338
rChangeCb \
339
} rBOIL_END
340
341
#define rCOptionCb_(getcode, setcode) { \
342
if(!strcmp("", args)) {\
343
data.reply(loc, "i", getcode); \
344
} else if(!strcmp("s", args) || !strcmp("S", args)) { \
345
auto var = \
346
enum_key(prop, rtosc_argument(msg, 0).s); \
347
/* make sure we have no out-of-bound options */
\
348
assert(!prop["min"] || \
349
var >= atoi(prop["min"])); \
350
assert(!prop["max"] || \
351
var <= atoi(prop["max"])); \
352
rCAPPLY(getcode, i, setcode) \
353
data.broadcast(loc, "i", getcode); \
354
rChangeCb \
355
} else {\
356
auto var = \
357
rtosc_argument(msg, 0).i; \
358
rLIMIT(var, atoi) \
359
rCAPPLY(getcode, i, setcode) \
360
data.broadcast(loc, rtosc_argument_string(msg), getcode);\
361
rChangeCb \
362
} \
363
}
364
365
#define rOptionCb_(name) rCOptionCb_(obj->name, obj->name = var)
366
367
#define rOptionCb(name) rBOIL_BEGIN \
368
rOptionCb_(name) \
369
rBOIL_END
370
371
#define rCOptionCb(getcode, setcode) rBOIL_BEGIN \
372
rCOptionCb_(getcode, setcode) \
373
rBOIL_END
374
375
376
#define rToggleCb(name) rBOIL_BEGIN \
377
if(!strcmp("", args)) {\
378
data.reply(loc, obj->name ? "T" : "F"); \
379
} else { \
380
if(obj->name != rtosc_argument(msg, 0).T) { \
381
data.broadcast(loc, args);\
382
obj->name = rtosc_argument(msg, 0).T; \
383
rChangeCb \
384
} \
385
} rBOIL_END
386
387
#define SNIP \
388
while(*msg && *msg!='/') ++msg; \
389
msg = *msg ? msg+1 : msg;
390
391
#define rRecurCb(name) rBOIL_BEGIN \
392
data.obj = &obj->name; \
393
SNIP \
394
decltype(obj->name)::ports.dispatch(msg, data); \
395
rBOIL_END
396
397
#define rRecurPtrCb(name) rBOIL_BEGIN \
398
void *ptr = &obj->name; \
399
data.reply(loc, "b", sizeof(void*), &ptr); \
400
rBOIL_END
401
402
#define rRecurpCb(name) rBOIL_BEGIN \
403
data.obj = obj->name; \
404
if(obj->name == NULL) return; \
405
SNIP \
406
decltype(spice(rObject::name))::ports.dispatch(msg, data); \
407
rBOIL_END
408
409
#define rRecursCb(name, length) rBOILS_BEGIN \
410
data.obj = &obj->name[idx]; \
411
SNIP \
412
decltype(spice(rObject::name))::ports.dispatch(msg, data); \
413
rBOILS_END
414
415
#define rRecurspCb(name) rBOILS_BEGIN \
416
data.obj = obj->name[idx]; \
417
SNIP \
418
decltype(spice(rObject::name[0]))::ports.dispatch(msg, data); \
419
rBOILS_END
420
421
#define rActionCb(name) rBOIL_BEGIN obj->name(); rBOIL_END
422
#define rActioniCb(name) rBOIL_BEGIN \
423
obj->name(rtosc_argument(msg,0).i); rBOIL_END
424
425
//Array ops
426
427
#define rBOILS_BEGIN rBOIL_BEGIN \
428
const char *mm = msg; \
429
while(*mm && !isdigit(*mm)) ++mm; \
430
unsigned idx = atoi(mm);
431
432
#define rBOILS_END rBOIL_END
433
434
435
#define rArrayCb(name) rBOILS_BEGIN \
436
if(!strcmp("", args)) {\
437
data.reply(loc, "c", obj->name[idx]); \
438
} else { \
439
char var = rtosc_argument(msg, 0).i; \
440
rLIMIT(var, atoi) \
441
rAPPLY(name[idx], c) \
442
data.broadcast(loc, "c", obj->name[idx]);\
443
rChangeCb \
444
} rBOILS_END
445
446
#define rArrayFCb(name) rBOILS_BEGIN \
447
if(!strcmp("", args)) {\
448
data.reply(loc, "f", obj->name[idx]); \
449
} else { \
450
float var = rtosc_argument(msg, 0).f; \
451
rLIMIT(var, atof) \
452
rAPPLY(name[idx], f) \
453
data.broadcast(loc, "f", obj->name[idx]);\
454
} rBOILS_END
455
456
#define rArrayTCb(name) rBOILS_BEGIN \
457
if(!strcmp("", args)) {\
458
data.reply(loc, obj->name[idx] ? "T" : "F"); \
459
} else { \
460
if(obj->name[idx] != rtosc_argument(msg, 0).T) { \
461
data.broadcast(loc, args);\
462
rChangeCb \
463
} \
464
obj->name[idx] = rtosc_argument(msg, 0).T; \
465
} rBOILS_END
466
467
#define rArrayTCbMember(name, member) rBOILS_BEGIN \
468
if(!strcmp("", args)) {\
469
data.reply(loc, obj->name[idx].member ? "T" : "F"); \
470
} else { \
471
if(obj->name[idx].member != rtosc_argument(msg, 0).T) { \
472
data.broadcast(loc, args);\
473
rChangeCb \
474
} \
475
obj->name[idx].member = rtosc_argument(msg, 0).T; \
476
} rBOILS_END
477
478
479
#define rArrayICb(name) rBOILS_BEGIN \
480
if(!strcmp("", args)) {\
481
data.reply(loc, "i", obj->name[idx]); \
482
} else { \
483
char var = rtosc_argument(msg, 0).i; \
484
rLIMIT(var, atoi) \
485
rAPPLY(name[idx], i) \
486
data.broadcast(loc, "i", obj->name[idx]);\
487
rChangeCb \
488
} rBOILS_END
489
490
491
#define rArrayOptionCb(name) rBOILS_BEGIN \
492
rOptionCb_(name[idx]) \
493
rBOILS_END
494
495
#define rParamsCb(name, length) rBOIL_BEGIN \
496
data.reply(loc, "b", length, obj->name); rBOIL_END
497
498
#define rStringCb(name, length) rBOIL_BEGIN \
499
if(!strcmp("", args)) {\
500
data.reply(loc, "s", obj->name); \
501
} else { \
502
strncpy(obj->name, rtosc_argument(msg, 0).s, length-1); \
503
obj->name[length-1] = '\0'; \
504
data.broadcast(loc, "s", obj->name);\
505
rChangeCb \
506
} rBOIL_END
507
508
509
#endif
type
CAdPlugDatabase::CRecord::RecordType type
Definition
adplugdb.cpp:93
assert.h
t
struct huft * t
Definition
inflate.c:943
spice
constexpr T spice(T *t)
Definition
port-sugar.h:205
Generated on
for LMMS by
1.16.1