summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/src/m_pd.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/m_pd.c')
-rw-r--r--apps/plugins/pdbox/PDa/src/m_pd.c612
1 files changed, 612 insertions, 0 deletions
diff --git a/apps/plugins/pdbox/PDa/src/m_pd.c b/apps/plugins/pdbox/PDa/src/m_pd.c
new file mode 100644
index 0000000000..321574b5a2
--- /dev/null
+++ b/apps/plugins/pdbox/PDa/src/m_pd.c
@@ -0,0 +1,612 @@
1/* Copyright (c) 1997-1999 Miller Puckette.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5#include <stdlib.h>
6#include "m_pd.h"
7#include "m_imp.h"
8
9 /* FIXME no out-of-memory testing yet! */
10
11t_pd *pd_new(t_class *c)
12{
13 t_pd *x;
14 if (!c)
15 bug ("pd_new: apparently called before setup routine");
16 x = (t_pd *)t_getbytes(c->c_size);
17 *x = c;
18 if (c->c_patchable)
19 {
20 ((t_object *)x)->ob_inlet = 0;
21 ((t_object *)x)->ob_outlet = 0;
22 }
23 return (x);
24}
25
26void pd_free(t_pd *x)
27{
28 t_class *c = *x;
29 if (c->c_freemethod) (*(t_gotfn)(c->c_freemethod))(x);
30 if (c->c_patchable)
31 {
32 while (((t_object *)x)->ob_outlet)
33 outlet_free(((t_object *)x)->ob_outlet);
34 while (((t_object *)x)->ob_inlet)
35 inlet_free(((t_object *)x)->ob_inlet);
36 if (((t_object *)x)->ob_binbuf)
37 binbuf_free(((t_object *)x)->ob_binbuf);
38 }
39 if (c->c_size) t_freebytes(x, c->c_size);
40}
41
42void gobj_save(t_gobj *x, t_binbuf *b)
43{
44 t_class *c = x->g_pd;
45 if (c->c_savefn)
46 (c->c_savefn)(x, b);
47}
48
49/* deal with several objects bound to the same symbol. If more than one, we
50actually bind a collection object to the symbol, which forwards messages sent
51to the symbol. */
52
53static t_class *bindlist_class;
54
55typedef struct _bindelem
56{
57 t_pd *e_who;
58 struct _bindelem *e_next;
59} t_bindelem;
60
61typedef struct _bindlist
62{
63 t_pd b_pd;
64 t_bindelem *b_list;
65} t_bindlist;
66
67static void bindlist_bang(t_bindlist *x)
68{
69 t_bindelem *e;
70 for (e = x->b_list; e; e = e->e_next)
71 pd_bang(e->e_who);
72}
73
74static void bindlist_float(t_bindlist *x, t_float f)
75{
76 t_bindelem *e;
77 for (e = x->b_list; e; e = e->e_next) {
78 pd_float(e->e_who, f);
79 }
80}
81
82static void bindlist_symbol(t_bindlist *x, t_symbol *s)
83{
84 t_bindelem *e;
85 for (e = x->b_list; e; e = e->e_next)
86 pd_symbol(e->e_who, s);
87}
88
89static void bindlist_pointer(t_bindlist *x, t_gpointer *gp)
90{
91 t_bindelem *e;
92 for (e = x->b_list; e; e = e->e_next)
93 pd_pointer(e->e_who, gp);
94}
95
96static void bindlist_list(t_bindlist *x, t_symbol *s,
97 int argc, t_atom *argv)
98{
99 t_bindelem *e;
100 for (e = x->b_list; e; e = e->e_next)
101 pd_list(e->e_who, s, argc, argv);
102}
103
104static void bindlist_anything(t_bindlist *x, t_symbol *s,
105 int argc, t_atom *argv)
106{
107 t_bindelem *e;
108 for (e = x->b_list; e; e = e->e_next)
109 pd_typedmess(e->e_who, s, argc, argv);
110}
111
112void m_pd_setup(void)
113{
114 bindlist_class = class_new(gensym("bindlist"), 0, 0,
115 sizeof(t_bindlist), CLASS_PD, 0);
116 class_addbang(bindlist_class, bindlist_bang);
117 class_addfloat(bindlist_class, (t_method)bindlist_float);
118 class_addsymbol(bindlist_class, bindlist_symbol);
119 class_addpointer(bindlist_class, bindlist_pointer);
120 class_addlist(bindlist_class, bindlist_list);
121 class_addanything(bindlist_class, bindlist_anything);
122}
123
124void pd_bind(t_pd *x, t_symbol *s)
125{
126 pd_checkgui(x,s);
127 if (s->s_thing)
128 {
129 if (*s->s_thing == bindlist_class)
130 {
131 t_bindlist *b = (t_bindlist *)s->s_thing;
132 t_bindelem *e = (t_bindelem *)getbytes(sizeof(t_bindelem));
133 e->e_next = b->b_list;
134 e->e_who = x;
135 b->b_list = e;
136 }
137 else
138 {
139 t_bindlist *b = (t_bindlist *)pd_new(bindlist_class);
140 t_bindelem *e1 = (t_bindelem *)getbytes(sizeof(t_bindelem));
141 t_bindelem *e2 = (t_bindelem *)getbytes(sizeof(t_bindelem));
142 b->b_list = e1;
143 e1->e_who = x;
144 e1->e_next = e2;
145 e2->e_who = s->s_thing;
146 e2->e_next = 0;
147 s->s_thing = &b->b_pd;
148 }
149 }
150 else s->s_thing = x;
151}
152
153void pd_unbind(t_pd *x, t_symbol *s)
154{
155 if (s->s_thing == x) s->s_thing = 0;
156 else if (s->s_thing && *s->s_thing == bindlist_class)
157 {
158 /* bindlists always have at least two elements... if the number
159 goes down to one, get rid of the bindlist and bind the symbol
160 straight to the remaining element. */
161
162 t_bindlist *b = (t_bindlist *)s->s_thing;
163 t_bindelem *e, *e2;
164 if ((e = b->b_list)->e_who == x)
165 {
166 b->b_list = e->e_next;
167 freebytes(e, sizeof(t_bindelem));
168 }
169 else for (e = b->b_list; e2 = e->e_next; e = e2)
170 if (e2->e_who == x)
171 {
172 e->e_next = e2->e_next;
173 freebytes(e2, sizeof(t_bindelem));
174 break;
175 }
176 if (!b->b_list->e_next)
177 {
178 s->s_thing = b->b_list->e_who;
179 freebytes(b->b_list, sizeof(t_bindelem));
180 pd_free(&b->b_pd);
181 }
182 }
183 else pd_error(x, "%s: couldn't unbind", s->s_name);
184}
185
186void zz(void) {}
187
188t_pd *pd_findbyclass(t_symbol *s, t_class *c)
189{
190 t_pd *x = 0;
191
192 if (!s->s_thing) return (0);
193 if (*s->s_thing == c) return (s->s_thing);
194 if (*s->s_thing == bindlist_class)
195 {
196 t_bindlist *b = (t_bindlist *)s->s_thing;
197 t_bindelem *e, *e2;
198 int warned = 0;
199 for (e = b->b_list; e; e = e->e_next)
200 if (*e->e_who == c)
201 {
202 if (x && !warned)
203 {
204 zz();
205 post("warning: %s: multiply defined", s->s_name);
206 warned = 1;
207 }
208 x = e->e_who;
209 }
210 }
211 return x;
212}
213
214/* stack for maintaining bindings for the #X symbol during nestable loads.
215*/
216
217typedef struct _gstack
218{
219 t_pd *g_what;
220 t_symbol *g_loadingabstraction;
221 struct _gstack *g_next;
222} t_gstack;
223
224static t_gstack *gstack_head = 0;
225static t_pd *lastpopped;
226static t_symbol *pd_loadingabstraction;
227
228int pd_setloadingabstraction(t_symbol *sym)
229{
230 t_gstack *foo = gstack_head;
231 for (foo = gstack_head; foo; foo = foo->g_next)
232 if (foo->g_loadingabstraction == sym)
233 return (1);
234 pd_loadingabstraction = sym;
235 return (0);
236}
237
238void pd_pushsym(t_pd *x)
239{
240 t_gstack *y = (t_gstack *)t_getbytes(sizeof(*y));
241 y->g_what = s__X.s_thing;
242 y->g_next = gstack_head;
243 y->g_loadingabstraction = pd_loadingabstraction;
244 pd_loadingabstraction = 0;
245 gstack_head = y;
246 s__X.s_thing = x;
247}
248
249void pd_popsym(t_pd *x)
250{
251 if (!gstack_head || s__X.s_thing != x) bug("gstack_pop");
252 else
253 {
254 t_gstack *headwas = gstack_head;
255 s__X.s_thing = headwas->g_what;
256 gstack_head = headwas->g_next;
257 t_freebytes(headwas, sizeof(*headwas));
258 lastpopped = x;
259 }
260}
261
262void pd_doloadbang(void)
263{
264 if (lastpopped)
265 pd_vmess(lastpopped, gensym("loadbang"), "");
266 lastpopped = 0;
267}
268
269void pd_bang(t_pd *x)
270{
271 (*(*x)->c_bangmethod)(x);
272}
273
274void pd_float(t_pd *x, t_float f)
275{
276 (*(*x)->c_floatmethod)(x, f);
277}
278
279void pd_pointer(t_pd *x, t_gpointer *gp)
280{
281 (*(*x)->c_pointermethod)(x, gp);
282}
283
284void pd_symbol(t_pd *x, t_symbol *s)
285{
286 (*(*x)->c_symbolmethod)(x, s);
287}
288
289void pd_list(t_pd *x, t_symbol *s, int argc, t_atom *argv)
290{
291 (*(*x)->c_listmethod)(x, &s_list, argc, argv);
292}
293
294void mess_init(void);
295void obj_init(void);
296void conf_init(void);
297void glob_init(void);
298
299void pd_init(void)
300{
301 mess_init();
302 obj_init();
303 conf_init();
304 glob_init();
305}
306
307/* Copyright (c) 1997-1999 Miller Puckette.
308* For information on usage and redistribution, and for a DISCLAIMER OF ALL
309* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
310
311#include <stdlib.h>
312#include "m_pd.h"
313#include "m_imp.h"
314
315 /* FIXME no out-of-memory testing yet! */
316
317t_pd *pd_new(t_class *c)
318{
319 t_pd *x;
320 if (!c)
321 bug ("pd_new: apparently called before setup routine");
322 x = (t_pd *)t_getbytes(c->c_size);
323 *x = c;
324 if (c->c_patchable)
325 {
326 ((t_object *)x)->ob_inlet = 0;
327 ((t_object *)x)->ob_outlet = 0;
328 }
329 return (x);
330}
331
332void pd_free(t_pd *x)
333{
334 t_class *c = *x;
335 if (c->c_freemethod) (*(t_gotfn)(c->c_freemethod))(x);
336 if (c->c_patchable)
337 {
338 while (((t_object *)x)->ob_outlet)
339 outlet_free(((t_object *)x)->ob_outlet);
340 while (((t_object *)x)->ob_inlet)
341 inlet_free(((t_object *)x)->ob_inlet);
342 if (((t_object *)x)->ob_binbuf)
343 binbuf_free(((t_object *)x)->ob_binbuf);
344 }
345 if (c->c_size) t_freebytes(x, c->c_size);
346}
347
348void gobj_save(t_gobj *x, t_binbuf *b)
349{
350 t_class *c = x->g_pd;
351 if (c->c_savefn)
352 (c->c_savefn)(x, b);
353}
354
355/* deal with several objects bound to the same symbol. If more than one, we
356actually bind a collection object to the symbol, which forwards messages sent
357to the symbol. */
358
359static t_class *bindlist_class;
360
361typedef struct _bindelem
362{
363 t_pd *e_who;
364 struct _bindelem *e_next;
365} t_bindelem;
366
367typedef struct _bindlist
368{
369 t_pd b_pd;
370 t_bindelem *b_list;
371} t_bindlist;
372
373static void bindlist_bang(t_bindlist *x)
374{
375 t_bindelem *e;
376 for (e = x->b_list; e; e = e->e_next)
377 pd_bang(e->e_who);
378}
379
380static void bindlist_float(t_bindlist *x, t_float f)
381{
382 t_bindelem *e;
383 for (e = x->b_list; e; e = e->e_next) {
384 pd_float(e->e_who, f);
385 }
386}
387
388static void bindlist_symbol(t_bindlist *x, t_symbol *s)
389{
390 t_bindelem *e;
391 for (e = x->b_list; e; e = e->e_next)
392 pd_symbol(e->e_who, s);
393}
394
395static void bindlist_pointer(t_bindlist *x, t_gpointer *gp)
396{
397 t_bindelem *e;
398 for (e = x->b_list; e; e = e->e_next)
399 pd_pointer(e->e_who, gp);
400}
401
402static void bindlist_list(t_bindlist *x, t_symbol *s,
403 int argc, t_atom *argv)
404{
405 t_bindelem *e;
406 for (e = x->b_list; e; e = e->e_next)
407 pd_list(e->e_who, s, argc, argv);
408}
409
410static void bindlist_anything(t_bindlist *x, t_symbol *s,
411 int argc, t_atom *argv)
412{
413 t_bindelem *e;
414 for (e = x->b_list; e; e = e->e_next)
415 pd_typedmess(e->e_who, s, argc, argv);
416}
417
418void m_pd_setup(void)
419{
420 bindlist_class = class_new(gensym("bindlist"), 0, 0,
421 sizeof(t_bindlist), CLASS_PD, 0);
422 class_addbang(bindlist_class, bindlist_bang);
423 class_addfloat(bindlist_class, (t_method)bindlist_float);
424 class_addsymbol(bindlist_class, bindlist_symbol);
425 class_addpointer(bindlist_class, bindlist_pointer);
426 class_addlist(bindlist_class, bindlist_list);
427 class_addanything(bindlist_class, bindlist_anything);
428}
429
430void pd_bind(t_pd *x, t_symbol *s)
431{
432 pd_checkgui(x,s);
433 if (s->s_thing)
434 {
435 if (*s->s_thing == bindlist_class)
436 {
437 t_bindlist *b = (t_bindlist *)s->s_thing;
438 t_bindelem *e = (t_bindelem *)getbytes(sizeof(t_bindelem));
439 e->e_next = b->b_list;
440 e->e_who = x;
441 b->b_list = e;
442 }
443 else
444 {
445 t_bindlist *b = (t_bindlist *)pd_new(bindlist_class);
446 t_bindelem *e1 = (t_bindelem *)getbytes(sizeof(t_bindelem));
447 t_bindelem *e2 = (t_bindelem *)getbytes(sizeof(t_bindelem));
448 b->b_list = e1;
449 e1->e_who = x;
450 e1->e_next = e2;
451 e2->e_who = s->s_thing;
452 e2->e_next = 0;
453 s->s_thing = &b->b_pd;
454 }
455 }
456 else s->s_thing = x;
457}
458
459void pd_unbind(t_pd *x, t_symbol *s)
460{
461 if (s->s_thing == x) s->s_thing = 0;
462 else if (s->s_thing && *s->s_thing == bindlist_class)
463 {
464 /* bindlists always have at least two elements... if the number
465 goes down to one, get rid of the bindlist and bind the symbol
466 straight to the remaining element. */
467
468 t_bindlist *b = (t_bindlist *)s->s_thing;
469 t_bindelem *e, *e2;
470 if ((e = b->b_list)->e_who == x)
471 {
472 b->b_list = e->e_next;
473 freebytes(e, sizeof(t_bindelem));
474 }
475 else for (e = b->b_list; e2 = e->e_next; e = e2)
476 if (e2->e_who == x)
477 {
478 e->e_next = e2->e_next;
479 freebytes(e2, sizeof(t_bindelem));
480 break;
481 }
482 if (!b->b_list->e_next)
483 {
484 s->s_thing = b->b_list->e_who;
485 freebytes(b->b_list, sizeof(t_bindelem));
486 pd_free(&b->b_pd);
487 }
488 }
489 else pd_error(x, "%s: couldn't unbind", s->s_name);
490}
491
492void zz(void) {}
493
494t_pd *pd_findbyclass(t_symbol *s, t_class *c)
495{
496 t_pd *x = 0;
497
498 if (!s->s_thing) return (0);
499 if (*s->s_thing == c) return (s->s_thing);
500 if (*s->s_thing == bindlist_class)
501 {
502 t_bindlist *b = (t_bindlist *)s->s_thing;
503 t_bindelem *e, *e2;
504 int warned = 0;
505 for (e = b->b_list; e; e = e->e_next)
506 if (*e->e_who == c)
507 {
508 if (x && !warned)
509 {
510 zz();
511 post("warning: %s: multiply defined", s->s_name);
512 warned = 1;
513 }
514 x = e->e_who;
515 }
516 }
517 return x;
518}
519
520/* stack for maintaining bindings for the #X symbol during nestable loads.
521*/
522
523typedef struct _gstack
524{
525 t_pd *g_what;
526 t_symbol *g_loadingabstraction;
527 struct _gstack *g_next;
528} t_gstack;
529
530static t_gstack *gstack_head = 0;
531static t_pd *lastpopped;
532static t_symbol *pd_loadingabstraction;
533
534int pd_setloadingabstraction(t_symbol *sym)
535{
536 t_gstack *foo = gstack_head;
537 for (foo = gstack_head; foo; foo = foo->g_next)
538 if (foo->g_loadingabstraction == sym)
539 return (1);
540 pd_loadingabstraction = sym;
541 return (0);
542}
543
544void pd_pushsym(t_pd *x)
545{
546 t_gstack *y = (t_gstack *)t_getbytes(sizeof(*y));
547 y->g_what = s__X.s_thing;
548 y->g_next = gstack_head;
549 y->g_loadingabstraction = pd_loadingabstraction;
550 pd_loadingabstraction = 0;
551 gstack_head = y;
552 s__X.s_thing = x;
553}
554
555void pd_popsym(t_pd *x)
556{
557 if (!gstack_head || s__X.s_thing != x) bug("gstack_pop");
558 else
559 {
560 t_gstack *headwas = gstack_head;
561 s__X.s_thing = headwas->g_what;
562 gstack_head = headwas->g_next;
563 t_freebytes(headwas, sizeof(*headwas));
564 lastpopped = x;
565 }
566}
567
568void pd_doloadbang(void)
569{
570 if (lastpopped)
571 pd_vmess(lastpopped, gensym("loadbang"), "");
572 lastpopped = 0;
573}
574
575void pd_bang(t_pd *x)
576{
577 (*(*x)->c_bangmethod)(x);
578}
579
580void pd_float(t_pd *x, t_float f)
581{
582 (*(*x)->c_floatmethod)(x, f);
583}
584
585void pd_pointer(t_pd *x, t_gpointer *gp)
586{
587 (*(*x)->c_pointermethod)(x, gp);
588}
589
590void pd_symbol(t_pd *x, t_symbol *s)
591{
592 (*(*x)->c_symbolmethod)(x, s);
593}
594
595void pd_list(t_pd *x, t_symbol *s, int argc, t_atom *argv)
596{
597 (*(*x)->c_listmethod)(x, &s_list, argc, argv);
598}
599
600void mess_init(void);
601void obj_init(void);
602void conf_init(void);
603void glob_init(void);
604
605void pd_init(void)
606{
607 mess_init();
608 obj_init();
609 conf_init();
610 glob_init();
611}
612