summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/src/x_connective.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/x_connective.c')
-rw-r--r--apps/plugins/pdbox/PDa/src/x_connective.c2904
1 files changed, 2904 insertions, 0 deletions
diff --git a/apps/plugins/pdbox/PDa/src/x_connective.c b/apps/plugins/pdbox/PDa/src/x_connective.c
new file mode 100644
index 0000000000..d68192ea9a
--- /dev/null
+++ b/apps/plugins/pdbox/PDa/src/x_connective.c
@@ -0,0 +1,2904 @@
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/* connective objects */
6
7#include "m_pd.h"
8
9#include <string.h>
10#include <stdio.h>
11extern t_pd *newest;
12
13/* -------------------------- int ------------------------------ */
14static t_class *pdint_class;
15
16typedef struct _pdint
17{
18 t_object x_obj;
19 t_float x_f;
20} t_pdint;
21
22static void *pdint_new(t_floatarg f)
23{
24 t_pdint *x = (t_pdint *)pd_new(pdint_class);
25 x->x_f = f;
26 outlet_new(&x->x_obj, &s_float);
27 floatinlet_new(&x->x_obj, &x->x_f);
28 return (x);
29}
30
31static void pdint_bang(t_pdint *x)
32{
33 outlet_float(x->x_obj.ob_outlet, (t_float)(int)(x->x_f));
34}
35
36static void pdint_float(t_pdint *x, t_float f)
37{
38 outlet_float(x->x_obj.ob_outlet, (t_float)(int)(x->x_f = f));
39}
40
41void pdint_setup(void)
42{
43 pdint_class = class_new(gensym("int"), (t_newmethod)pdint_new, 0,
44 sizeof(t_pdint), 0, A_DEFFLOAT, 0);
45 class_addcreator((t_newmethod)pdint_new, gensym("i"), A_DEFFLOAT, 0);
46 class_addbang(pdint_class, pdint_bang);
47 class_addfloat(pdint_class, pdint_float);
48}
49
50/* -------------------------- float ------------------------------ */
51static t_class *pdfloat_class;
52
53typedef struct _pdfloat
54{
55 t_object x_obj;
56 t_float x_f;
57} t_pdfloat;
58
59 /* "float," "symbol," and "bang" are special because
60 they're created by short-circuited messages to the "new"
61 object which are handled specially in pd_typedmess(). */
62
63static void *pdfloat_new(t_pd *dummy, t_float f)
64{
65 t_pdfloat *x = (t_pdfloat *)pd_new(pdfloat_class);
66 x->x_f = f;
67 outlet_new(&x->x_obj, &s_float);
68 floatinlet_new(&x->x_obj, &x->x_f);
69 newest = &x->x_obj.ob_pd;
70 return (x);
71}
72
73static void *pdfloat_new2(t_floatarg f)
74{
75 return (pdfloat_new(0, f));
76}
77
78static void pdfloat_bang(t_pdfloat *x)
79{
80 outlet_float(x->x_obj.ob_outlet, x->x_f);
81}
82
83static void pdfloat_float(t_pdfloat *x, t_float f)
84{
85 outlet_float(x->x_obj.ob_outlet, x->x_f = f);
86}
87
88void pdfloat_setup(void)
89{
90 pdfloat_class = class_new(gensym("float"), (t_newmethod)pdfloat_new, 0,
91 sizeof(t_pdfloat), 0, A_FLOAT, 0);
92 class_addcreator((t_newmethod)pdfloat_new2, gensym("f"), A_DEFFLOAT, 0);
93 class_addbang(pdfloat_class, pdfloat_bang);
94 class_addfloat(pdfloat_class, (t_method)pdfloat_float);
95}
96
97/* -------------------------- symbol ------------------------------ */
98static t_class *pdsymbol_class;
99
100typedef struct _pdsymbol
101{
102 t_object x_obj;
103 t_symbol *x_s;
104} t_pdsymbol;
105
106static void *pdsymbol_new(t_pd *dummy, t_symbol *s)
107{
108 t_pdsymbol *x = (t_pdsymbol *)pd_new(pdsymbol_class);
109 x->x_s = s;
110 outlet_new(&x->x_obj, &s_symbol);
111 symbolinlet_new(&x->x_obj, &x->x_s);
112 newest = &x->x_obj.ob_pd;
113 return (x);
114}
115
116static void pdsymbol_bang(t_pdsymbol *x)
117{
118 outlet_symbol(x->x_obj.ob_outlet, x->x_s);
119}
120
121static void pdsymbol_symbol(t_pdsymbol *x, t_symbol *s)
122{
123 outlet_symbol(x->x_obj.ob_outlet, x->x_s = s);
124}
125
126static void pdsymbol_anything(t_pdsymbol *x, t_symbol *s, int ac, t_atom *av)
127{
128 outlet_symbol(x->x_obj.ob_outlet, x->x_s = s);
129}
130
131void pdsymbol_setup(void)
132{
133 pdsymbol_class = class_new(gensym("symbol"), (t_newmethod)pdsymbol_new, 0,
134 sizeof(t_pdsymbol), 0, A_SYMBOL, 0);
135 class_addbang(pdsymbol_class, pdsymbol_bang);
136 class_addsymbol(pdsymbol_class, pdsymbol_symbol);
137 class_addanything(pdsymbol_class, pdsymbol_anything);
138}
139
140/* -------------------------- bang ------------------------------ */
141static t_class *bang_class;
142
143typedef struct _bang
144{
145 t_object x_obj;
146} t_bang;
147
148static void *bang_new(t_pd *dummy)
149{
150 t_bang *x = (t_bang *)pd_new(bang_class);
151 outlet_new(&x->x_obj, &s_bang);
152 newest = &x->x_obj.ob_pd;
153 return (x);
154}
155
156static void *bang_new2(t_bang f)
157{
158 return (bang_new(0));
159}
160
161static void bang_bang(t_bang *x)
162{
163 outlet_bang(x->x_obj.ob_outlet);
164}
165
166void bang_setup(void)
167{
168 bang_class = class_new(gensym("bang"), (t_newmethod)bang_new, 0,
169 sizeof(t_bang), 0, 0);
170 class_addcreator((t_newmethod)bang_new2, gensym("b"), 0);
171 class_addbang(bang_class, bang_bang);
172 class_addfloat(bang_class, bang_bang);
173 class_addsymbol(bang_class, bang_bang);
174 class_addlist(bang_class, bang_bang);
175 class_addanything(bang_class, bang_bang);
176}
177
178/* -------------------- send ------------------------------ */
179
180static t_class *send_class;
181
182typedef struct _send
183{
184 t_object x_obj;
185 t_symbol *x_sym;
186} t_send;
187
188static void send_bang(t_send *x)
189{
190 if (x->x_sym->s_thing) pd_bang(x->x_sym->s_thing);
191}
192
193static void send_float(t_send *x, t_float f)
194{
195 if (x->x_sym->s_thing) pd_float(x->x_sym->s_thing, f);
196}
197
198static void send_symbol(t_send *x, t_symbol *s)
199{
200 if (x->x_sym->s_thing) pd_symbol(x->x_sym->s_thing, s);
201}
202
203static void send_pointer(t_send *x, t_gpointer *gp)
204{
205 if (x->x_sym->s_thing) pd_pointer(x->x_sym->s_thing, gp);
206}
207
208static void send_list(t_send *x, t_symbol *s, int argc, t_atom *argv)
209{
210 if (x->x_sym->s_thing) pd_list(x->x_sym->s_thing, s, argc, argv);
211}
212
213static void send_anything(t_send *x, t_symbol *s, int argc, t_atom *argv)
214{
215 if (x->x_sym->s_thing) typedmess(x->x_sym->s_thing, s, argc, argv);
216}
217
218static void *send_new(t_symbol *s)
219{
220 t_send *x = (t_send *)pd_new(send_class);
221 x->x_sym = s;
222 return (x);
223}
224
225static void send_setup(void)
226{
227 send_class = class_new(gensym("send"), (t_newmethod)send_new, 0,
228 sizeof(t_send), 0, A_DEFSYM, 0);
229 class_addcreator((t_newmethod)send_new, gensym("s"), A_DEFSYM, 0);
230 class_addbang(send_class, send_bang);
231 class_addfloat(send_class, send_float);
232 class_addsymbol(send_class, send_symbol);
233 class_addpointer(send_class, send_pointer);
234 class_addlist(send_class, send_list);
235 class_addanything(send_class, send_anything);
236}
237/* -------------------- receive ------------------------------ */
238
239static t_class *receive_class;
240
241typedef struct _receive
242{
243 t_object x_obj;
244 t_symbol *x_sym;
245} t_receive;
246
247static void receive_bang(t_receive *x)
248{
249 outlet_bang(x->x_obj.ob_outlet);
250}
251
252static void receive_float(t_receive *x, t_float f)
253{
254 outlet_float(x->x_obj.ob_outlet, f);
255}
256
257static void receive_symbol(t_receive *x, t_symbol *s)
258{
259 outlet_symbol(x->x_obj.ob_outlet, s);
260}
261
262static void receive_pointer(t_receive *x, t_gpointer *gp)
263{
264 outlet_pointer(x->x_obj.ob_outlet, gp);
265}
266
267static void receive_list(t_receive *x, t_symbol *s, int argc, t_atom *argv)
268{
269 outlet_list(x->x_obj.ob_outlet, s, argc, argv);
270}
271
272static void receive_anything(t_receive *x, t_symbol *s, int argc, t_atom *argv)
273{
274 outlet_anything(x->x_obj.ob_outlet, s, argc, argv);
275}
276
277static void *receive_new(t_symbol *s)
278{
279 t_receive *x = (t_receive *)pd_new(receive_class);
280 x->x_sym = s;
281 pd_bind(&x->x_obj.ob_pd, s);
282 outlet_new(&x->x_obj, 0);
283 return (x);
284}
285
286static void receive_free(t_receive *x)
287{
288 pd_unbind(&x->x_obj.ob_pd, x->x_sym);
289}
290
291static void receive_setup(void)
292{
293 receive_class = class_new(gensym("receive"), (t_newmethod)receive_new,
294 (t_method)receive_free, sizeof(t_receive), CLASS_NOINLET, A_DEFSYM, 0);
295 class_addcreator((t_newmethod)receive_new, gensym("r"), A_DEFSYM, 0);
296 class_addbang(receive_class, receive_bang);
297 class_addfloat(receive_class, (t_method)receive_float);
298 class_addsymbol(receive_class, receive_symbol);
299 class_addpointer(receive_class, receive_pointer);
300 class_addlist(receive_class, receive_list);
301 class_addanything(receive_class, receive_anything);
302}
303
304/* -------------------------- select ------------------------------ */
305
306static t_class *sel1_class;
307
308typedef struct _sel1
309{
310 t_object x_obj;
311 t_atom x_atom;
312 t_outlet *x_outlet1;
313 t_outlet *x_outlet2;
314} t_sel1;
315
316static void sel1_float(t_sel1 *x, t_float f)
317{
318 if (x->x_atom.a_type == A_FLOAT && f == x->x_atom.a_w.w_float)
319 outlet_bang(x->x_outlet1);
320 else outlet_float(x->x_outlet2, f);
321}
322
323static void sel1_symbol(t_sel1 *x, t_symbol *s)
324{
325 if (x->x_atom.a_type == A_SYMBOL && s == x->x_atom.a_w.w_symbol)
326 outlet_bang(x->x_outlet1);
327 else outlet_symbol(x->x_outlet2, s);
328}
329
330static t_class *sel2_class;
331
332typedef struct _selectelement
333{
334 t_word e_w;
335 t_outlet *e_outlet;
336} t_selectelement;
337
338typedef struct _sel2
339{
340 t_object x_obj;
341 t_atomtype x_type;
342 t_int x_nelement;
343 t_selectelement *x_vec;
344 t_outlet *x_rejectout;
345} t_sel2;
346
347static void sel2_float(t_sel2 *x, t_float f)
348{
349 t_selectelement *e;
350 int nelement;
351 if (x->x_type == A_FLOAT)
352 {
353 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
354 if (e->e_w.w_float == f)
355 {
356 outlet_bang(e->e_outlet);
357 return;
358 }
359 }
360 outlet_float(x->x_rejectout, f);
361}
362
363static void sel2_symbol(t_sel2 *x, t_symbol *s)
364{
365 t_selectelement *e;
366 int nelement;
367 if (x->x_type == A_SYMBOL)
368 {
369 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
370 if (e->e_w.w_symbol == s)
371 {
372 outlet_bang(e->e_outlet);
373 return;
374 }
375 }
376 outlet_symbol(x->x_rejectout, s);
377}
378
379static void sel2_free(t_sel2 *x)
380{
381 freebytes(x->x_vec, x->x_nelement * sizeof(*x->x_vec));
382}
383
384static void *select_new(t_symbol *s, int argc, t_atom *argv)
385{
386 t_atom a;
387 if (argc == 0)
388 {
389 argc = 1;
390 SETFLOAT(&a, 0);
391 argv = &a;
392 }
393 if (argc == 1)
394 {
395 t_sel1 *x = (t_sel1 *)pd_new(sel1_class);
396 x->x_atom = *argv;
397 x->x_outlet1 = outlet_new(&x->x_obj, &s_bang);
398 if (argv->a_type == A_FLOAT)
399 {
400 floatinlet_new(&x->x_obj, &x->x_atom.a_w.w_float);
401 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
402 }
403 else
404 {
405 symbolinlet_new(&x->x_obj, &x->x_atom.a_w.w_symbol);
406 x->x_outlet2 = outlet_new(&x->x_obj, &s_symbol);
407 }
408 return (x);
409 }
410 else
411 {
412 int n;
413 t_selectelement *e;
414 t_sel2 *x = (t_sel2 *)pd_new(sel2_class);
415 x->x_nelement = argc;
416 x->x_vec = (t_selectelement *)getbytes(argc * sizeof(*x->x_vec));
417 x->x_type = argv[0].a_type;
418 for (n = 0, e = x->x_vec; n < argc; n++, e++)
419 {
420 e->e_outlet = outlet_new(&x->x_obj, &s_bang);
421 if ((x->x_type = argv->a_type) == A_FLOAT)
422 e->e_w.w_float = atom_getfloatarg(n, argc, argv);
423 else e->e_w.w_symbol = atom_getsymbolarg(n, argc, argv);
424 }
425 x->x_rejectout = outlet_new(&x->x_obj, &s_float);
426 return (x);
427 }
428
429}
430
431void select_setup(void)
432{
433 sel1_class = class_new(gensym("select"), 0, 0,
434 sizeof(t_sel1), 0, 0);
435 class_addfloat(sel1_class, sel1_float);
436 class_addsymbol(sel1_class, sel1_symbol);
437
438 sel2_class = class_new(gensym("select"), 0, (t_method)sel2_free,
439 sizeof(t_sel2), 0, 0);
440 class_addfloat(sel2_class, sel2_float);
441 class_addsymbol(sel2_class, sel2_symbol);
442
443 class_addcreator((t_newmethod)select_new, gensym("select"), A_GIMME, 0);
444 class_addcreator((t_newmethod)select_new, gensym("sel"), A_GIMME, 0);
445}
446
447/* -------------------------- route ------------------------------ */
448
449static t_class *route_class;
450
451typedef struct _routeelement
452{
453 t_word e_w;
454 t_outlet *e_outlet;
455} t_routeelement;
456
457typedef struct _route
458{
459 t_object x_obj;
460 t_atomtype x_type;
461 t_int x_nelement;
462 t_routeelement *x_vec;
463 t_outlet *x_rejectout;
464} t_route;
465
466static void route_anything(t_route *x, t_symbol *sel, int argc, t_atom *argv)
467{
468 t_routeelement *e;
469 int nelement;
470 if (x->x_type == A_SYMBOL)
471 {
472 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
473 if (e->e_w.w_symbol == sel)
474 {
475 if (argc > 0 && argv[0].a_type == A_SYMBOL)
476 outlet_anything(e->e_outlet, argv[0].a_w.w_symbol,
477 argc-1, argv+1);
478 else outlet_list(e->e_outlet, 0, argc, argv);
479 return;
480 }
481 }
482 outlet_anything(x->x_rejectout, sel, argc, argv);
483}
484
485static void route_list(t_route *x, t_symbol *sel, int argc, t_atom *argv)
486{
487 t_routeelement *e;
488 int nelement;
489 if (x->x_type == A_FLOAT)
490 {
491 float f;
492 if (!argc) return;
493 f = atom_getfloat(argv);
494 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
495 if (e->e_w.w_float == f)
496 {
497 if (argc > 1 && argv[1].a_type == A_SYMBOL)
498 outlet_anything(e->e_outlet, argv[1].a_w.w_symbol,
499 argc-2, argv+2);
500 else outlet_list(e->e_outlet, 0, argc-1, argv+1);
501 return;
502 }
503 }
504 else /* symbol arguments */
505 {
506 if (argc > 1) /* 2 or more args: treat as "list" */
507 {
508 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
509 {
510 if (e->e_w.w_symbol == &s_list)
511 {
512 if (argc > 0 && argv[0].a_type == A_SYMBOL)
513 outlet_anything(e->e_outlet, argv[0].a_w.w_symbol,
514 argc-1, argv+1);
515 else outlet_list(e->e_outlet, 0, argc, argv);
516 return;
517 }
518 }
519 }
520 else if (argc == 0) /* no args: treat as "bang" */
521 {
522 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
523 {
524 if (e->e_w.w_symbol == &s_bang)
525 {
526 outlet_bang(e->e_outlet);
527 return;
528 }
529 }
530 }
531 else if (argv[0].a_type == A_FLOAT) /* one float arg */
532 {
533 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
534 {
535 if (e->e_w.w_symbol == &s_float)
536 {
537 outlet_float(e->e_outlet, argv[0].a_w.w_float);
538 return;
539 }
540 }
541 }
542 else
543 {
544 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
545 {
546 if (e->e_w.w_symbol == &s_symbol)
547 {
548 outlet_symbol(e->e_outlet, argv[0].a_w.w_symbol);
549 return;
550 }
551 }
552 }
553 }
554 outlet_list(x->x_rejectout, 0, argc, argv);
555}
556
557
558static void route_free(t_route *x)
559{
560 freebytes(x->x_vec, x->x_nelement * sizeof(*x->x_vec));
561}
562
563static void *route_new(t_symbol *s, int argc, t_atom *argv)
564{
565 int n;
566 t_routeelement *e;
567 t_route *x = (t_route *)pd_new(route_class);
568 t_atom a;
569 if (argc == 0)
570 {
571 argc = 1;
572 SETFLOAT(&a, 0);
573 argv = &a;
574 }
575 x->x_type = argv[0].a_type;
576 x->x_nelement = argc;
577 x->x_vec = (t_routeelement *)getbytes(argc * sizeof(*x->x_vec));
578 for (n = 0, e = x->x_vec; n < argc; n++, e++)
579 {
580 e->e_outlet = outlet_new(&x->x_obj, &s_list);
581 if (x->x_type == A_FLOAT)
582 e->e_w.w_float = atom_getfloatarg(n, argc, argv);
583 else e->e_w.w_symbol = atom_getsymbolarg(n, argc, argv);
584 }
585 x->x_rejectout = outlet_new(&x->x_obj, &s_list);
586 return (x);
587}
588
589void route_setup(void)
590{
591 route_class = class_new(gensym("route"), (t_newmethod)route_new,
592 (t_method)route_free, sizeof(t_route), 0, A_GIMME, 0);
593 class_addlist(route_class, route_list);
594 class_addanything(route_class, route_anything);
595}
596
597/* -------------------------- pack ------------------------------ */
598
599static t_class *pack_class;
600
601typedef struct _pack
602{
603 t_object x_obj;
604 t_int x_n; /* number of args */
605 t_atom *x_vec; /* input values */
606 t_int x_nptr; /* number of pointers */
607 t_gpointer *x_gpointer; /* the pointers */
608 t_atom *x_outvec; /* space for output values */
609} t_pack;
610
611static void *pack_new(t_symbol *s, int argc, t_atom *argv)
612{
613 t_pack *x = (t_pack *)pd_new(pack_class);
614 t_atom defarg[2], *ap, *vec, *vp;
615 t_gpointer *gp;
616 int nptr = 0;
617 int i;
618 if (!argc)
619 {
620 argv = defarg;
621 argc = 2;
622 SETFLOAT(&defarg[0], 0);
623 SETFLOAT(&defarg[1], 0);
624 }
625
626 x->x_n = argc;
627 vec = x->x_vec = (t_atom *)getbytes(argc * sizeof(*x->x_vec));
628 x->x_outvec = (t_atom *)getbytes(argc * sizeof(*x->x_outvec));
629
630 for (i = argc, ap = argv; i--; ap++)
631 if (ap->a_type == A_SYMBOL && *ap->a_w.w_symbol->s_name == 'p')
632 nptr++;
633
634 gp = x->x_gpointer = (t_gpointer *)t_getbytes(nptr * sizeof (*gp));
635 x->x_nptr = nptr;
636
637 for (i = 0, vp = x->x_vec, ap = argv; i < argc; i++, ap++, vp++)
638 {
639 if (ap->a_type == A_FLOAT)
640 {
641 *vp = *ap;
642 if (i) floatinlet_new(&x->x_obj, &vp->a_w.w_float);
643 }
644 else if (ap->a_type == A_SYMBOL)
645 {
646 char c = *ap->a_w.w_symbol->s_name;
647 if (c == 's')
648 {
649 SETSYMBOL(vp, &s_symbol);
650 if (i) symbolinlet_new(&x->x_obj, &vp->a_w.w_symbol);
651 }
652 else if (c == 'p')
653 {
654 vp->a_type = A_POINTER;
655 vp->a_w.w_gpointer = gp;
656 gpointer_init(gp);
657 if (i) pointerinlet_new(&x->x_obj, gp);
658 gp++;
659 }
660 else
661 {
662 if (c != 'f') pd_error(x, "pack: %s: bad type",
663 ap->a_w.w_symbol->s_name);
664 SETFLOAT(vp, 0);
665 if (i) floatinlet_new(&x->x_obj, &vp->a_w.w_float);
666 }
667 }
668 }
669 outlet_new(&x->x_obj, &s_list);
670 return (x);
671}
672
673static void pack_bang(t_pack *x)
674{
675 int i, reentered = 0, size = x->x_n * sizeof (t_atom);
676 t_gpointer *gp;
677 t_atom *outvec;
678 for (i = x->x_nptr, gp = x->x_gpointer; i--; gp++)
679 if (!gpointer_check(gp, 1))
680 {
681 pd_error(x, "pack: stale pointer");
682 return;
683 }
684 /* reentrancy protection. The first time through use the pre-allocated
685 x_outvec; if we're reentered we have to allocate new memory. */
686 if (!x->x_outvec)
687 {
688 /* LATER figure out how to deal with reentrancy and pointers... */
689 if (x->x_nptr)
690 post("pack_bang: warning: reentry with pointers unprotected");
691 outvec = t_getbytes(size);
692 reentered = 1;
693 }
694 else
695 {
696 outvec = x->x_outvec;
697 x->x_outvec = 0;
698 }
699 memcpy(outvec, x->x_vec, size);
700 outlet_list(x->x_obj.ob_outlet, &s_list, x->x_n, outvec);
701 if (reentered)
702 t_freebytes(outvec, size);
703 else x->x_outvec = outvec;
704}
705
706static void pack_pointer(t_pack *x, t_gpointer *gp)
707{
708 if (x->x_vec->a_type == A_POINTER)
709 {
710 gpointer_unset(x->x_gpointer);
711 *x->x_gpointer = *gp;
712 if (gp->gp_stub) gp->gp_stub->gs_refcount++;
713 pack_bang(x);
714 }
715 else pd_error(x, "pack_pointer: wrong type");
716}
717
718static void pack_float(t_pack *x, t_float f)
719{
720 if (x->x_vec->a_type == A_FLOAT)
721 {
722 x->x_vec->a_w.w_float = f;
723 pack_bang(x);
724 }
725 else pd_error(x, "pack_float: wrong type");
726}
727
728static void pack_symbol(t_pack *x, t_symbol *s)
729{
730 if (x->x_vec->a_type == A_SYMBOL)
731 {
732 x->x_vec->a_w.w_symbol = s;
733 pack_bang(x);
734 }
735 else pd_error(x, "pack_symbol: wrong type");
736}
737
738static void pack_list(t_pack *x, t_symbol *s, int ac, t_atom *av)
739{
740 obj_list(&x->x_obj, 0, ac, av);
741}
742
743static void pack_anything(t_pack *x, t_symbol *s, int ac, t_atom *av)
744{
745 t_atom *av2 = (t_atom *)getbytes((ac + 1) * sizeof(t_atom));
746 int i;
747 for (i = 0; i < ac; i++)
748 av2[i + 1] = av[i];
749 SETSYMBOL(av2, s);
750 obj_list(&x->x_obj, 0, ac+1, av2);
751 freebytes(av2, (ac + 1) * sizeof(t_atom));
752}
753
754static void pack_free(t_pack *x)
755{
756 t_gpointer *gp;
757 int i;
758 for (gp = x->x_gpointer, i = x->x_nptr; i--; gp++)
759 gpointer_unset(gp);
760 freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
761 freebytes(x->x_outvec, x->x_n * sizeof(*x->x_outvec));
762 freebytes(x->x_gpointer, x->x_nptr * sizeof(*x->x_gpointer));
763}
764
765static void pack_setup(void)
766{
767 pack_class = class_new(gensym("pack"), (t_newmethod)pack_new,
768 (t_method)pack_free, sizeof(t_pack), 0, A_GIMME, 0);
769 class_addbang(pack_class, pack_bang);
770 class_addpointer(pack_class, pack_pointer);
771 class_addfloat(pack_class, pack_float);
772 class_addsymbol(pack_class, pack_symbol);
773 class_addlist(pack_class, pack_list);
774 class_addanything(pack_class, pack_anything);
775}
776
777/* -------------------------- unpack ------------------------------ */
778
779static t_class *unpack_class;
780
781typedef struct unpackout
782{
783 t_atomtype u_type;
784 t_outlet *u_outlet;
785} t_unpackout;
786
787typedef struct _unpack
788{
789 t_object x_obj;
790 t_int x_n;
791 t_unpackout *x_vec;
792} t_unpack;
793
794static void *unpack_new(t_symbol *s, int argc, t_atom *argv)
795{
796 t_unpack *x = (t_unpack *)pd_new(unpack_class);
797 t_atom defarg[2], *ap;
798 t_unpackout *u;
799 int i;
800 if (!argc)
801 {
802 argv = defarg;
803 argc = 2;
804 SETFLOAT(&defarg[0], 0);
805 SETFLOAT(&defarg[1], 0);
806 }
807 x->x_n = argc;
808 x->x_vec = (t_unpackout *)getbytes(argc * sizeof(*x->x_vec));
809 for (i = 0, ap = argv, u = x->x_vec; i < argc; u++, ap++, i++)
810 {
811 t_atomtype type = ap->a_type;
812 if (type == A_SYMBOL)
813 {
814 char c = *ap->a_w.w_symbol->s_name;
815 if (c == 's')
816 {
817 u->u_type = A_SYMBOL;
818 u->u_outlet = outlet_new(&x->x_obj, &s_symbol);
819 }
820 else if (c == 'p')
821 {
822 u->u_type = A_POINTER;
823 u->u_outlet = outlet_new(&x->x_obj, &s_pointer);
824 }
825 else
826 {
827 if (c != 'f') pd_error(x, "unpack: %s: bad type",
828 ap->a_w.w_symbol->s_name);
829 u->u_type = A_FLOAT;
830 u->u_outlet = outlet_new(&x->x_obj, &s_float);
831 }
832 }
833 else
834 {
835 u->u_type = A_FLOAT;
836 u->u_outlet = outlet_new(&x->x_obj, &s_float);
837 }
838 }
839 return (x);
840}
841
842static void unpack_list(t_unpack *x, t_symbol *s, int argc, t_atom *argv)
843{
844 t_atom *ap;
845 t_unpackout *u;
846 int i;
847 if (argc > x->x_n) argc = x->x_n;
848 for (i = argc, u = x->x_vec + i, ap = argv + i; u--, ap--, i--;)
849 {
850 t_atomtype type = u->u_type;
851 if (type != ap->a_type)
852 pd_error(x, "unpack: type mismatch");
853 else if (type == A_FLOAT)
854 outlet_float(u->u_outlet, ap->a_w.w_float);
855 else if (type == A_SYMBOL)
856 outlet_symbol(u->u_outlet, ap->a_w.w_symbol);
857 else outlet_pointer(u->u_outlet, ap->a_w.w_gpointer);
858 }
859}
860
861static void unpack_anything(t_unpack *x, t_symbol *s, int ac, t_atom *av)
862{
863 t_atom *av2 = (t_atom *)getbytes((ac + 1) * sizeof(t_atom));
864 int i;
865 for (i = 0; i < ac; i++)
866 av2[i + 1] = av[i];
867 SETSYMBOL(av2, s);
868 unpack_list(x, 0, ac+1, av2);
869 freebytes(av2, (ac + 1) * sizeof(t_atom));
870}
871
872static void unpack_free(t_unpack *x)
873{
874 freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
875}
876
877static void unpack_setup(void)
878{
879 unpack_class = class_new(gensym("unpack"), (t_newmethod)unpack_new,
880 (t_method)unpack_free, sizeof(t_unpack), 0, A_GIMME, 0);
881 class_addlist(unpack_class, unpack_list);
882 class_addanything(unpack_class, unpack_anything);
883}
884
885/* -------------------------- trigger ------------------------------ */
886
887static t_class *trigger_class;
888#define TR_BANG 0
889#define TR_FLOAT 1
890#define TR_SYMBOL 2
891#define TR_POINTER 3
892#define TR_LIST 4
893#define TR_ANYTHING 5
894
895typedef struct triggerout
896{
897 int u_type; /* outlet type from above */
898 t_outlet *u_outlet;
899} t_triggerout;
900
901typedef struct _trigger
902{
903 t_object x_obj;
904 t_int x_n;
905 t_triggerout *x_vec;
906} t_trigger;
907
908static void *trigger_new(t_symbol *s, int argc, t_atom *argv)
909{
910 t_trigger *x = (t_trigger *)pd_new(trigger_class);
911 t_atom defarg[2], *ap;
912 t_triggerout *u;
913 int i;
914 if (!argc)
915 {
916 argv = defarg;
917 argc = 2;
918 SETSYMBOL(&defarg[0], &s_bang);
919 SETSYMBOL(&defarg[1], &s_bang);
920 }
921 x->x_n = argc;
922 x->x_vec = (t_triggerout *)getbytes(argc * sizeof(*x->x_vec));
923 for (i = 0, ap = argv, u = x->x_vec; i < argc; u++, ap++, i++)
924 {
925 t_atomtype thistype = ap->a_type;
926 char c;
927 if (thistype == TR_SYMBOL) c = ap->a_w.w_symbol->s_name[0];
928 else if (thistype == TR_FLOAT) c = 'f';
929 else c = 0;
930 if (c == 'p')
931 u->u_type = TR_POINTER,
932 u->u_outlet = outlet_new(&x->x_obj, &s_pointer);
933 else if (c == 'f')
934 u->u_type = TR_FLOAT, u->u_outlet = outlet_new(&x->x_obj, &s_float);
935 else if (c == 'b')
936 u->u_type = TR_BANG, u->u_outlet = outlet_new(&x->x_obj, &s_bang);
937 else if (c == 'l')
938 u->u_type = TR_LIST, u->u_outlet = outlet_new(&x->x_obj, &s_list);
939 else if (c == 's')
940 u->u_type = TR_SYMBOL,
941 u->u_outlet = outlet_new(&x->x_obj, &s_symbol);
942 else if (c == 'a')
943 u->u_type = TR_ANYTHING,
944 u->u_outlet = outlet_new(&x->x_obj, &s_symbol);
945 else
946 {
947 pd_error(x, "trigger: %s: bad type", ap->a_w.w_symbol->s_name);
948 u->u_type = TR_FLOAT, u->u_outlet = outlet_new(&x->x_obj, &s_float);
949 }
950 }
951 return (x);
952}
953
954static void trigger_list(t_trigger *x, t_symbol *s, int argc, t_atom *argv)
955{
956 t_triggerout *u;
957 int i;
958 t_atom at;
959 if (!argc)
960 {
961 argc = 1;
962 SETFLOAT(&at, 0);
963 argv = &at;
964 }
965 for (i = x->x_n, u = x->x_vec + i; u--, i--;)
966 {
967 if (u->u_type == TR_FLOAT)
968 outlet_float(u->u_outlet, atom_getfloat(argv));
969 else if (u->u_type == TR_BANG)
970 outlet_bang(u->u_outlet);
971 else if (u->u_type == TR_SYMBOL)
972 outlet_symbol(u->u_outlet, atom_getsymbol(argv));
973 else if (u->u_type == TR_POINTER)
974 {
975 if (argv->a_type != TR_POINTER)
976 pd_error(x, "unpack: bad pointer");
977 else outlet_pointer(u->u_outlet, argv->a_w.w_gpointer);
978 }
979 else outlet_list(u->u_outlet, &s_list, argc, argv);
980 }
981}
982
983static void trigger_anything(t_trigger *x, t_symbol *s, int argc, t_atom *argv)
984{
985 t_triggerout *u;
986 int i;
987 for (i = x->x_n, u = x->x_vec + i; u--, i--;)
988 {
989 if (u->u_type == TR_BANG)
990 outlet_bang(u->u_outlet);
991 else if (u->u_type == TR_ANYTHING)
992 outlet_anything(u->u_outlet, s, argc, argv);
993 else pd_error(x, "trigger: can only convert 's' to 'b' or 'a'",
994 s->s_name);
995 }
996}
997
998static void trigger_bang(t_trigger *x)
999{
1000 trigger_list(x, 0, 0, 0);
1001}
1002
1003static void trigger_pointer(t_trigger *x, t_gpointer *gp)
1004{
1005 t_atom at;
1006 SETPOINTER(&at, gp);
1007 trigger_list(x, 0, 1, &at);
1008}
1009
1010static void trigger_float(t_trigger *x, t_float f)
1011{
1012 t_atom at;
1013 SETFLOAT(&at, f);
1014 trigger_list(x, 0, 1, &at);
1015}
1016
1017static void trigger_symbol(t_trigger *x, t_symbol *s)
1018{
1019 t_atom at;
1020 SETSYMBOL(&at, s);
1021 trigger_list(x, 0, 1, &at);
1022}
1023
1024static void trigger_free(t_trigger *x)
1025{
1026 freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
1027}
1028
1029static void trigger_setup(void)
1030{
1031 trigger_class = class_new(gensym("trigger"), (t_newmethod)trigger_new,
1032 (t_method)trigger_free, sizeof(t_trigger), 0, A_GIMME, 0);
1033 class_addcreator((t_newmethod)trigger_new, gensym("t"), A_GIMME, 0);
1034 class_addlist(trigger_class, trigger_list);
1035 class_addbang(trigger_class, trigger_bang);
1036 class_addpointer(trigger_class, trigger_pointer);
1037 class_addfloat(trigger_class, (t_method)trigger_float);
1038 class_addsymbol(trigger_class, trigger_symbol);
1039 class_addanything(trigger_class, trigger_anything);
1040}
1041
1042/* -------------------------- spigot ------------------------------ */
1043static t_class *spigot_class;
1044
1045typedef struct _spigot
1046{
1047 t_object x_obj;
1048 float x_state;
1049} t_spigot;
1050
1051static void *spigot_new(void)
1052{
1053 t_spigot *x = (t_spigot *)pd_new(spigot_class);
1054 floatinlet_new(&x->x_obj, &x->x_state);
1055 outlet_new(&x->x_obj, 0);
1056 x->x_state = 0;
1057 return (x);
1058}
1059
1060static void spigot_bang(t_spigot *x)
1061{
1062 if (x->x_state != 0) outlet_bang(x->x_obj.ob_outlet);
1063}
1064
1065static void spigot_pointer(t_spigot *x, t_gpointer *gp)
1066{
1067 if (x->x_state != 0) outlet_pointer(x->x_obj.ob_outlet, gp);
1068}
1069
1070static void spigot_float(t_spigot *x, t_float f)
1071{
1072 if (x->x_state != 0) outlet_float(x->x_obj.ob_outlet, f);
1073}
1074
1075static void spigot_symbol(t_spigot *x, t_symbol *s)
1076{
1077 if (x->x_state != 0) outlet_symbol(x->x_obj.ob_outlet, s);
1078}
1079
1080static void spigot_list(t_spigot *x, t_symbol *s, int argc, t_atom *argv)
1081{
1082 if (x->x_state != 0) outlet_list(x->x_obj.ob_outlet, s, argc, argv);
1083}
1084
1085static void spigot_anything(t_spigot *x, t_symbol *s, int argc, t_atom *argv)
1086{
1087 if (x->x_state != 0) outlet_anything(x->x_obj.ob_outlet, s, argc, argv);
1088}
1089
1090static void spigot_setup(void)
1091{
1092 spigot_class = class_new(gensym("spigot"), (t_newmethod)spigot_new, 0,
1093 sizeof(t_spigot), 0, A_DEFSYM, 0);
1094 class_addbang(spigot_class, spigot_bang);
1095 class_addpointer(spigot_class, spigot_pointer);
1096 class_addfloat(spigot_class, spigot_float);
1097 class_addsymbol(spigot_class, spigot_symbol);
1098 class_addlist(spigot_class, spigot_list);
1099 class_addanything(spigot_class, spigot_anything);
1100}
1101
1102/* --------------------------- moses ----------------------------- */
1103static t_class *moses_class;
1104
1105typedef struct _moses
1106{
1107 t_object x_ob;
1108 t_outlet *x_out2;
1109 float x_y;
1110} t_moses;
1111
1112static void *moses_new(t_floatarg f)
1113{
1114 t_moses *x = (t_moses *)pd_new(moses_class);
1115 floatinlet_new(&x->x_ob, &x->x_y);
1116 outlet_new(&x->x_ob, &s_float);
1117 x->x_out2 = outlet_new(&x->x_ob, &s_float);
1118 x->x_y = f;
1119 return (x);
1120}
1121
1122static void moses_float(t_moses *x, t_float f)
1123{
1124 if (f < x->x_y) outlet_float(x->x_ob.ob_outlet, f);
1125 else outlet_float(x->x_out2, f);
1126}
1127
1128static void moses_setup(void)
1129{
1130 moses_class = class_new(gensym("moses"), (t_newmethod)moses_new, 0,
1131 sizeof(t_moses), 0, A_DEFFLOAT, 0);
1132 class_addfloat(moses_class, moses_float);
1133}
1134
1135/* ----------------------- until --------------------- */
1136
1137static t_class *until_class;
1138
1139typedef struct _until
1140{
1141 t_object x_obj;
1142 int x_run;
1143 int x_count;
1144} t_until;
1145
1146static void *until_new(void)
1147{
1148 t_until *x = (t_until *)pd_new(until_class);
1149 inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("bang"), gensym("bang2"));
1150 outlet_new(&x->x_obj, &s_bang);
1151 x->x_run = 0;
1152 return (x);
1153}
1154
1155static void until_bang(t_until *x)
1156{
1157 x->x_run = 1;
1158 x->x_count = -1;
1159 while (x->x_run && x->x_count)
1160 x->x_count--, outlet_bang(x->x_obj.ob_outlet);
1161}
1162
1163static void until_float(t_until *x, t_float f)
1164{
1165 x->x_run = 1;
1166 x->x_count = f;
1167 while (x->x_run && x->x_count)
1168 x->x_count--, outlet_bang(x->x_obj.ob_outlet);
1169}
1170
1171static void until_bang2(t_until *x)
1172{
1173 x->x_run = 0;
1174}
1175
1176static void until_setup(void)
1177{
1178 until_class = class_new(gensym("until"), (t_newmethod)until_new, 0,
1179 sizeof(t_until), 0, 0);
1180 class_addbang(until_class, until_bang);
1181 class_addfloat(until_class, until_float);
1182 class_addmethod(until_class, (t_method)until_bang2, gensym("bang2"), 0);
1183}
1184
1185/* ----------------------- makefilename --------------------- */
1186
1187static t_class *makefilename_class;
1188
1189typedef struct _makefilename
1190{
1191 t_object x_obj;
1192 t_symbol *x_format;
1193} t_makefilename;
1194
1195static void *makefilename_new(t_symbol *s)
1196{
1197 t_makefilename *x = (t_makefilename *)pd_new(makefilename_class);
1198 if (!s->s_name) s = gensym("file.%d");
1199 outlet_new(&x->x_obj, &s_symbol);
1200 x->x_format = s;
1201 return (x);
1202}
1203
1204static void makefilename_float(t_makefilename *x, t_floatarg f)
1205{
1206 char buf[MAXPDSTRING];
1207 sprintf(buf, x->x_format->s_name, (int)f);
1208 outlet_symbol(x->x_obj.ob_outlet, gensym(buf));
1209}
1210
1211static void makefilename_symbol(t_makefilename *x, t_symbol *s)
1212{
1213 char buf[MAXPDSTRING];
1214 sprintf(buf, x->x_format->s_name, s->s_name);
1215 outlet_symbol(x->x_obj.ob_outlet, gensym(buf));
1216}
1217
1218static void makefilename_setup(void)
1219{
1220 makefilename_class = class_new(gensym("makefilename"),
1221 (t_newmethod)makefilename_new, 0,
1222 sizeof(t_makefilename), 0, A_DEFSYM, 0);
1223 class_addfloat(makefilename_class, makefilename_float);
1224 class_addsymbol(makefilename_class, makefilename_symbol);
1225}
1226
1227/* -------------------------- swap ------------------------------ */
1228static t_class *swap_class;
1229
1230typedef struct _swap
1231{
1232 t_object x_obj;
1233 t_outlet *x_out2;
1234 t_float x_f1;
1235 t_float x_f2;
1236} t_swap;
1237
1238static void *swap_new(t_floatarg f)
1239{
1240 t_swap *x = (t_swap *)pd_new(swap_class);
1241 x->x_f2 = f;
1242 x->x_f1 = 0;
1243 outlet_new(&x->x_obj, &s_float);
1244 x->x_out2 = outlet_new(&x->x_obj, &s_float);
1245 floatinlet_new(&x->x_obj, &x->x_f2);
1246 return (x);
1247}
1248
1249static void swap_bang(t_swap *x)
1250{
1251 outlet_float(x->x_out2, x->x_f1);
1252 outlet_float(x->x_obj.ob_outlet, x->x_f2);
1253}
1254
1255static void swap_float(t_swap *x, t_float f)
1256{
1257 x->x_f1 = f;
1258 swap_bang(x);
1259}
1260
1261void swap_setup(void)
1262{
1263 swap_class = class_new(gensym("swap"), (t_newmethod)swap_new, 0,
1264 sizeof(t_swap), 0, A_DEFFLOAT, 0);
1265 class_addcreator((t_newmethod)swap_new, gensym("fswap"), A_DEFFLOAT, 0);
1266 class_addbang(swap_class, swap_bang);
1267 class_addfloat(swap_class, swap_float);
1268}
1269
1270/* -------------------------- change ------------------------------ */
1271static t_class *change_class;
1272
1273typedef struct _change
1274{
1275 t_object x_obj;
1276 t_float x_f;
1277} t_change;
1278
1279static void *change_new(t_floatarg f)
1280{
1281 t_change *x = (t_change *)pd_new(change_class);
1282 x->x_f = f;
1283 outlet_new(&x->x_obj, &s_float);
1284 return (x);
1285}
1286
1287static void change_bang(t_change *x)
1288{
1289 outlet_float(x->x_obj.ob_outlet, x->x_f);
1290}
1291
1292static void change_float(t_change *x, t_float f)
1293{
1294 if (f != x->x_f)
1295 {
1296 x->x_f = f;
1297 outlet_float(x->x_obj.ob_outlet, x->x_f);
1298 }
1299}
1300
1301static void change_set(t_change *x, t_float f)
1302{
1303 x->x_f = f;
1304}
1305
1306void change_setup(void)
1307{
1308 change_class = class_new(gensym("change"), (t_newmethod)change_new, 0,
1309 sizeof(t_change), 0, A_DEFFLOAT, 0);
1310 class_addbang(change_class, change_bang);
1311 class_addfloat(change_class, change_float);
1312 class_addmethod(change_class, (t_method)change_set, gensym("set"),
1313 A_DEFFLOAT, 0);
1314}
1315
1316/* -------------------- value ------------------------------ */
1317
1318static t_class *value_class, *vcommon_class;
1319
1320typedef struct vcommon
1321{
1322 t_pd c_pd;
1323 int c_refcount;
1324 t_float c_f;
1325} t_vcommon;
1326
1327typedef struct _value
1328{
1329 t_object x_obj;
1330 t_symbol *x_sym;
1331 t_float *x_floatstar;
1332} t_value;
1333
1334 /* get a pointer to a named floating-point variable. The variable
1335 belongs to a "vcommon" object, which is created if necessary. */
1336t_float *value_get(t_symbol *s)
1337{
1338 t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class);
1339 if (!c)
1340 {
1341 c = (t_vcommon *)pd_new(vcommon_class);
1342 c->c_f = 0;
1343 c->c_refcount = 0;
1344 pd_bind(&c->c_pd, s);
1345 }
1346 c->c_refcount++;
1347 return (&c->c_f);
1348}
1349
1350 /* release a variable. This only frees the "vcommon" resource when the
1351 last interested party releases it. */
1352void value_release(t_symbol *s)
1353{
1354 t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class);
1355 if (c)
1356 {
1357 if (!--c->c_refcount)
1358 {
1359 pd_unbind(&c->c_pd, s);
1360 pd_free(&c->c_pd);
1361 }
1362 }
1363 else bug("value_release");
1364}
1365
1366/*
1367 * value_getfloat -- obtain the float value of a "value" object
1368 * return 0 on success, 1 otherwise
1369 */
1370int
1371value_getfloat(t_symbol *s, t_float *f)
1372{
1373 t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class);
1374 if (!c)
1375 return (1);
1376 *f = c->c_f;
1377 return (0);
1378}
1379
1380/*
1381 * value_setfloat -- set the float value of a "value" object
1382 * return 0 on success, 1 otherwise
1383 */
1384int
1385value_setfloat(t_symbol *s, t_float f)
1386{
1387 t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class);
1388 if (!c)
1389 return (1);
1390 c->c_f = f;
1391 return (0);
1392}
1393
1394static void *value_new(t_symbol *s)
1395{
1396 t_value *x = (t_value *)pd_new(value_class);
1397 x->x_sym = s;
1398 x->x_floatstar = value_get(s);
1399 outlet_new(&x->x_obj, &s_float);
1400 return (x);
1401}
1402
1403static void value_bang(t_value *x)
1404{
1405 outlet_float(x->x_obj.ob_outlet, *x->x_floatstar);
1406}
1407
1408static void value_float(t_value *x, t_float f)
1409{
1410 *x->x_floatstar = f;
1411}
1412
1413static void value_ff(t_value *x)
1414{
1415 value_release(x->x_sym);
1416}
1417
1418static void value_setup(void)
1419{
1420 value_class = class_new(gensym("value"), (t_newmethod)value_new,
1421 (t_method)value_ff,
1422 sizeof(t_value), 0, A_DEFSYM, 0);
1423 class_addcreator((t_newmethod)value_new, gensym("v"), A_DEFSYM, 0);
1424 class_addbang(value_class, value_bang);
1425 class_addfloat(value_class, value_float);
1426 vcommon_class = class_new(gensym("value"), 0, 0,
1427 sizeof(t_vcommon), CLASS_PD, 0);
1428}
1429
1430/* -------------- overall setup routine for this file ----------------- */
1431
1432void x_connective_setup(void)
1433{
1434 pdint_setup();
1435 pdfloat_setup();
1436 pdsymbol_setup();
1437 bang_setup();
1438 send_setup();
1439 receive_setup();
1440 select_setup();
1441 route_setup();
1442 pack_setup();
1443 unpack_setup();
1444 trigger_setup();
1445 spigot_setup();
1446 moses_setup();
1447 until_setup();
1448 makefilename_setup();
1449 swap_setup();
1450 change_setup();
1451 value_setup();
1452}
1453/* Copyright (c) 1997-1999 Miller Puckette.
1454* For information on usage and redistribution, and for a DISCLAIMER OF ALL
1455* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
1456
1457/* connective objects */
1458
1459#include "m_pd.h"
1460
1461#include <string.h>
1462#include <stdio.h>
1463extern t_pd *newest;
1464
1465/* -------------------------- int ------------------------------ */
1466static t_class *pdint_class;
1467
1468typedef struct _pdint
1469{
1470 t_object x_obj;
1471 t_float x_f;
1472} t_pdint;
1473
1474static void *pdint_new(t_floatarg f)
1475{
1476 t_pdint *x = (t_pdint *)pd_new(pdint_class);
1477 x->x_f = f;
1478 outlet_new(&x->x_obj, &s_float);
1479 floatinlet_new(&x->x_obj, &x->x_f);
1480 return (x);
1481}
1482
1483static void pdint_bang(t_pdint *x)
1484{
1485 outlet_float(x->x_obj.ob_outlet, (t_float)(int)(x->x_f));
1486}
1487
1488static void pdint_float(t_pdint *x, t_float f)
1489{
1490 outlet_float(x->x_obj.ob_outlet, (t_float)(int)(x->x_f = f));
1491}
1492
1493void pdint_setup(void)
1494{
1495 pdint_class = class_new(gensym("int"), (t_newmethod)pdint_new, 0,
1496 sizeof(t_pdint), 0, A_DEFFLOAT, 0);
1497 class_addcreator((t_newmethod)pdint_new, gensym("i"), A_DEFFLOAT, 0);
1498 class_addbang(pdint_class, pdint_bang);
1499 class_addfloat(pdint_class, pdint_float);
1500}
1501
1502/* -------------------------- float ------------------------------ */
1503static t_class *pdfloat_class;
1504
1505typedef struct _pdfloat
1506{
1507 t_object x_obj;
1508 t_float x_f;
1509} t_pdfloat;
1510
1511 /* "float," "symbol," and "bang" are special because
1512 they're created by short-circuited messages to the "new"
1513 object which are handled specially in pd_typedmess(). */
1514
1515static void *pdfloat_new(t_pd *dummy, t_float f)
1516{
1517 t_pdfloat *x = (t_pdfloat *)pd_new(pdfloat_class);
1518 x->x_f = f;
1519 outlet_new(&x->x_obj, &s_float);
1520 floatinlet_new(&x->x_obj, &x->x_f);
1521 newest = &x->x_obj.ob_pd;
1522 return (x);
1523}
1524
1525static void *pdfloat_new2(t_floatarg f)
1526{
1527 return (pdfloat_new(0, f));
1528}
1529
1530static void pdfloat_bang(t_pdfloat *x)
1531{
1532 outlet_float(x->x_obj.ob_outlet, x->x_f);
1533}
1534
1535static void pdfloat_float(t_pdfloat *x, t_float f)
1536{
1537 outlet_float(x->x_obj.ob_outlet, x->x_f = f);
1538}
1539
1540void pdfloat_setup(void)
1541{
1542 pdfloat_class = class_new(gensym("float"), (t_newmethod)pdfloat_new, 0,
1543 sizeof(t_pdfloat), 0, A_FLOAT, 0);
1544 class_addcreator((t_newmethod)pdfloat_new2, gensym("f"), A_DEFFLOAT, 0);
1545 class_addbang(pdfloat_class, pdfloat_bang);
1546 class_addfloat(pdfloat_class, (t_method)pdfloat_float);
1547}
1548
1549/* -------------------------- symbol ------------------------------ */
1550static t_class *pdsymbol_class;
1551
1552typedef struct _pdsymbol
1553{
1554 t_object x_obj;
1555 t_symbol *x_s;
1556} t_pdsymbol;
1557
1558static void *pdsymbol_new(t_pd *dummy, t_symbol *s)
1559{
1560 t_pdsymbol *x = (t_pdsymbol *)pd_new(pdsymbol_class);
1561 x->x_s = s;
1562 outlet_new(&x->x_obj, &s_symbol);
1563 symbolinlet_new(&x->x_obj, &x->x_s);
1564 newest = &x->x_obj.ob_pd;
1565 return (x);
1566}
1567
1568static void pdsymbol_bang(t_pdsymbol *x)
1569{
1570 outlet_symbol(x->x_obj.ob_outlet, x->x_s);
1571}
1572
1573static void pdsymbol_symbol(t_pdsymbol *x, t_symbol *s)
1574{
1575 outlet_symbol(x->x_obj.ob_outlet, x->x_s = s);
1576}
1577
1578static void pdsymbol_anything(t_pdsymbol *x, t_symbol *s, int ac, t_atom *av)
1579{
1580 outlet_symbol(x->x_obj.ob_outlet, x->x_s = s);
1581}
1582
1583void pdsymbol_setup(void)
1584{
1585 pdsymbol_class = class_new(gensym("symbol"), (t_newmethod)pdsymbol_new, 0,
1586 sizeof(t_pdsymbol), 0, A_SYMBOL, 0);
1587 class_addbang(pdsymbol_class, pdsymbol_bang);
1588 class_addsymbol(pdsymbol_class, pdsymbol_symbol);
1589 class_addanything(pdsymbol_class, pdsymbol_anything);
1590}
1591
1592/* -------------------------- bang ------------------------------ */
1593static t_class *bang_class;
1594
1595typedef struct _bang
1596{
1597 t_object x_obj;
1598} t_bang;
1599
1600static void *bang_new(t_pd *dummy)
1601{
1602 t_bang *x = (t_bang *)pd_new(bang_class);
1603 outlet_new(&x->x_obj, &s_bang);
1604 newest = &x->x_obj.ob_pd;
1605 return (x);
1606}
1607
1608static void *bang_new2(t_bang f)
1609{
1610 return (bang_new(0));
1611}
1612
1613static void bang_bang(t_bang *x)
1614{
1615 outlet_bang(x->x_obj.ob_outlet);
1616}
1617
1618void bang_setup(void)
1619{
1620 bang_class = class_new(gensym("bang"), (t_newmethod)bang_new, 0,
1621 sizeof(t_bang), 0, 0);
1622 class_addcreator((t_newmethod)bang_new2, gensym("b"), 0);
1623 class_addbang(bang_class, bang_bang);
1624 class_addfloat(bang_class, bang_bang);
1625 class_addsymbol(bang_class, bang_bang);
1626 class_addlist(bang_class, bang_bang);
1627 class_addanything(bang_class, bang_bang);
1628}
1629
1630/* -------------------- send ------------------------------ */
1631
1632static t_class *send_class;
1633
1634typedef struct _send
1635{
1636 t_object x_obj;
1637 t_symbol *x_sym;
1638} t_send;
1639
1640static void send_bang(t_send *x)
1641{
1642 if (x->x_sym->s_thing) pd_bang(x->x_sym->s_thing);
1643}
1644
1645static void send_float(t_send *x, t_float f)
1646{
1647 if (x->x_sym->s_thing) pd_float(x->x_sym->s_thing, f);
1648}
1649
1650static void send_symbol(t_send *x, t_symbol *s)
1651{
1652 if (x->x_sym->s_thing) pd_symbol(x->x_sym->s_thing, s);
1653}
1654
1655static void send_pointer(t_send *x, t_gpointer *gp)
1656{
1657 if (x->x_sym->s_thing) pd_pointer(x->x_sym->s_thing, gp);
1658}
1659
1660static void send_list(t_send *x, t_symbol *s, int argc, t_atom *argv)
1661{
1662 if (x->x_sym->s_thing) pd_list(x->x_sym->s_thing, s, argc, argv);
1663}
1664
1665static void send_anything(t_send *x, t_symbol *s, int argc, t_atom *argv)
1666{
1667 if (x->x_sym->s_thing) typedmess(x->x_sym->s_thing, s, argc, argv);
1668}
1669
1670static void *send_new(t_symbol *s)
1671{
1672 t_send *x = (t_send *)pd_new(send_class);
1673 x->x_sym = s;
1674 return (x);
1675}
1676
1677static void send_setup(void)
1678{
1679 send_class = class_new(gensym("send"), (t_newmethod)send_new, 0,
1680 sizeof(t_send), 0, A_DEFSYM, 0);
1681 class_addcreator((t_newmethod)send_new, gensym("s"), A_DEFSYM, 0);
1682 class_addbang(send_class, send_bang);
1683 class_addfloat(send_class, send_float);
1684 class_addsymbol(send_class, send_symbol);
1685 class_addpointer(send_class, send_pointer);
1686 class_addlist(send_class, send_list);
1687 class_addanything(send_class, send_anything);
1688}
1689/* -------------------- receive ------------------------------ */
1690
1691static t_class *receive_class;
1692
1693typedef struct _receive
1694{
1695 t_object x_obj;
1696 t_symbol *x_sym;
1697} t_receive;
1698
1699static void receive_bang(t_receive *x)
1700{
1701 outlet_bang(x->x_obj.ob_outlet);
1702}
1703
1704static void receive_float(t_receive *x, t_float f)
1705{
1706 outlet_float(x->x_obj.ob_outlet, f);
1707}
1708
1709static void receive_symbol(t_receive *x, t_symbol *s)
1710{
1711 outlet_symbol(x->x_obj.ob_outlet, s);
1712}
1713
1714static void receive_pointer(t_receive *x, t_gpointer *gp)
1715{
1716 outlet_pointer(x->x_obj.ob_outlet, gp);
1717}
1718
1719static void receive_list(t_receive *x, t_symbol *s, int argc, t_atom *argv)
1720{
1721 outlet_list(x->x_obj.ob_outlet, s, argc, argv);
1722}
1723
1724static void receive_anything(t_receive *x, t_symbol *s, int argc, t_atom *argv)
1725{
1726 outlet_anything(x->x_obj.ob_outlet, s, argc, argv);
1727}
1728
1729static void *receive_new(t_symbol *s)
1730{
1731 t_receive *x = (t_receive *)pd_new(receive_class);
1732 x->x_sym = s;
1733 pd_bind(&x->x_obj.ob_pd, s);
1734 outlet_new(&x->x_obj, 0);
1735 return (x);
1736}
1737
1738static void receive_free(t_receive *x)
1739{
1740 pd_unbind(&x->x_obj.ob_pd, x->x_sym);
1741}
1742
1743static void receive_setup(void)
1744{
1745 receive_class = class_new(gensym("receive"), (t_newmethod)receive_new,
1746 (t_method)receive_free, sizeof(t_receive), CLASS_NOINLET, A_DEFSYM, 0);
1747 class_addcreator((t_newmethod)receive_new, gensym("r"), A_DEFSYM, 0);
1748 class_addbang(receive_class, receive_bang);
1749 class_addfloat(receive_class, (t_method)receive_float);
1750 class_addsymbol(receive_class, receive_symbol);
1751 class_addpointer(receive_class, receive_pointer);
1752 class_addlist(receive_class, receive_list);
1753 class_addanything(receive_class, receive_anything);
1754}
1755
1756/* -------------------------- select ------------------------------ */
1757
1758static t_class *sel1_class;
1759
1760typedef struct _sel1
1761{
1762 t_object x_obj;
1763 t_atom x_atom;
1764 t_outlet *x_outlet1;
1765 t_outlet *x_outlet2;
1766} t_sel1;
1767
1768static void sel1_float(t_sel1 *x, t_float f)
1769{
1770 if (x->x_atom.a_type == A_FLOAT && f == x->x_atom.a_w.w_float)
1771 outlet_bang(x->x_outlet1);
1772 else outlet_float(x->x_outlet2, f);
1773}
1774
1775static void sel1_symbol(t_sel1 *x, t_symbol *s)
1776{
1777 if (x->x_atom.a_type == A_SYMBOL && s == x->x_atom.a_w.w_symbol)
1778 outlet_bang(x->x_outlet1);
1779 else outlet_symbol(x->x_outlet2, s);
1780}
1781
1782static t_class *sel2_class;
1783
1784typedef struct _selectelement
1785{
1786 t_word e_w;
1787 t_outlet *e_outlet;
1788} t_selectelement;
1789
1790typedef struct _sel2
1791{
1792 t_object x_obj;
1793 t_atomtype x_type;
1794 t_int x_nelement;
1795 t_selectelement *x_vec;
1796 t_outlet *x_rejectout;
1797} t_sel2;
1798
1799static void sel2_float(t_sel2 *x, t_float f)
1800{
1801 t_selectelement *e;
1802 int nelement;
1803 if (x->x_type == A_FLOAT)
1804 {
1805 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
1806 if (e->e_w.w_float == f)
1807 {
1808 outlet_bang(e->e_outlet);
1809 return;
1810 }
1811 }
1812 outlet_float(x->x_rejectout, f);
1813}
1814
1815static void sel2_symbol(t_sel2 *x, t_symbol *s)
1816{
1817 t_selectelement *e;
1818 int nelement;
1819 if (x->x_type == A_SYMBOL)
1820 {
1821 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
1822 if (e->e_w.w_symbol == s)
1823 {
1824 outlet_bang(e->e_outlet);
1825 return;
1826 }
1827 }
1828 outlet_symbol(x->x_rejectout, s);
1829}
1830
1831static void sel2_free(t_sel2 *x)
1832{
1833 freebytes(x->x_vec, x->x_nelement * sizeof(*x->x_vec));
1834}
1835
1836static void *select_new(t_symbol *s, int argc, t_atom *argv)
1837{
1838 t_atom a;
1839 if (argc == 0)
1840 {
1841 argc = 1;
1842 SETFLOAT(&a, 0);
1843 argv = &a;
1844 }
1845 if (argc == 1)
1846 {
1847 t_sel1 *x = (t_sel1 *)pd_new(sel1_class);
1848 x->x_atom = *argv;
1849 x->x_outlet1 = outlet_new(&x->x_obj, &s_bang);
1850 if (argv->a_type == A_FLOAT)
1851 {
1852 floatinlet_new(&x->x_obj, &x->x_atom.a_w.w_float);
1853 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
1854 }
1855 else
1856 {
1857 symbolinlet_new(&x->x_obj, &x->x_atom.a_w.w_symbol);
1858 x->x_outlet2 = outlet_new(&x->x_obj, &s_symbol);
1859 }
1860 return (x);
1861 }
1862 else
1863 {
1864 int n;
1865 t_selectelement *e;
1866 t_sel2 *x = (t_sel2 *)pd_new(sel2_class);
1867 x->x_nelement = argc;
1868 x->x_vec = (t_selectelement *)getbytes(argc * sizeof(*x->x_vec));
1869 x->x_type = argv[0].a_type;
1870 for (n = 0, e = x->x_vec; n < argc; n++, e++)
1871 {
1872 e->e_outlet = outlet_new(&x->x_obj, &s_bang);
1873 if ((x->x_type = argv->a_type) == A_FLOAT)
1874 e->e_w.w_float = atom_getfloatarg(n, argc, argv);
1875 else e->e_w.w_symbol = atom_getsymbolarg(n, argc, argv);
1876 }
1877 x->x_rejectout = outlet_new(&x->x_obj, &s_float);
1878 return (x);
1879 }
1880
1881}
1882
1883void select_setup(void)
1884{
1885 sel1_class = class_new(gensym("select"), 0, 0,
1886 sizeof(t_sel1), 0, 0);
1887 class_addfloat(sel1_class, sel1_float);
1888 class_addsymbol(sel1_class, sel1_symbol);
1889
1890 sel2_class = class_new(gensym("select"), 0, (t_method)sel2_free,
1891 sizeof(t_sel2), 0, 0);
1892 class_addfloat(sel2_class, sel2_float);
1893 class_addsymbol(sel2_class, sel2_symbol);
1894
1895 class_addcreator((t_newmethod)select_new, gensym("select"), A_GIMME, 0);
1896 class_addcreator((t_newmethod)select_new, gensym("sel"), A_GIMME, 0);
1897}
1898
1899/* -------------------------- route ------------------------------ */
1900
1901static t_class *route_class;
1902
1903typedef struct _routeelement
1904{
1905 t_word e_w;
1906 t_outlet *e_outlet;
1907} t_routeelement;
1908
1909typedef struct _route
1910{
1911 t_object x_obj;
1912 t_atomtype x_type;
1913 t_int x_nelement;
1914 t_routeelement *x_vec;
1915 t_outlet *x_rejectout;
1916} t_route;
1917
1918static void route_anything(t_route *x, t_symbol *sel, int argc, t_atom *argv)
1919{
1920 t_routeelement *e;
1921 int nelement;
1922 if (x->x_type == A_SYMBOL)
1923 {
1924 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
1925 if (e->e_w.w_symbol == sel)
1926 {
1927 if (argc > 0 && argv[0].a_type == A_SYMBOL)
1928 outlet_anything(e->e_outlet, argv[0].a_w.w_symbol,
1929 argc-1, argv+1);
1930 else outlet_list(e->e_outlet, 0, argc, argv);
1931 return;
1932 }
1933 }
1934 outlet_anything(x->x_rejectout, sel, argc, argv);
1935}
1936
1937static void route_list(t_route *x, t_symbol *sel, int argc, t_atom *argv)
1938{
1939 t_routeelement *e;
1940 int nelement;
1941 if (x->x_type == A_FLOAT)
1942 {
1943 float f;
1944 if (!argc) return;
1945 f = atom_getfloat(argv);
1946 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
1947 if (e->e_w.w_float == f)
1948 {
1949 if (argc > 1 && argv[1].a_type == A_SYMBOL)
1950 outlet_anything(e->e_outlet, argv[1].a_w.w_symbol,
1951 argc-2, argv+2);
1952 else outlet_list(e->e_outlet, 0, argc-1, argv+1);
1953 return;
1954 }
1955 }
1956 else /* symbol arguments */
1957 {
1958 if (argc > 1) /* 2 or more args: treat as "list" */
1959 {
1960 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
1961 {
1962 if (e->e_w.w_symbol == &s_list)
1963 {
1964 if (argc > 0 && argv[0].a_type == A_SYMBOL)
1965 outlet_anything(e->e_outlet, argv[0].a_w.w_symbol,
1966 argc-1, argv+1);
1967 else outlet_list(e->e_outlet, 0, argc, argv);
1968 return;
1969 }
1970 }
1971 }
1972 else if (argc == 0) /* no args: treat as "bang" */
1973 {
1974 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
1975 {
1976 if (e->e_w.w_symbol == &s_bang)
1977 {
1978 outlet_bang(e->e_outlet);
1979 return;
1980 }
1981 }
1982 }
1983 else if (argv[0].a_type == A_FLOAT) /* one float arg */
1984 {
1985 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
1986 {
1987 if (e->e_w.w_symbol == &s_float)
1988 {
1989 outlet_float(e->e_outlet, argv[0].a_w.w_float);
1990 return;
1991 }
1992 }
1993 }
1994 else
1995 {
1996 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
1997 {
1998 if (e->e_w.w_symbol == &s_symbol)
1999 {
2000 outlet_symbol(e->e_outlet, argv[0].a_w.w_symbol);
2001 return;
2002 }
2003 }
2004 }
2005 }
2006 outlet_list(x->x_rejectout, 0, argc, argv);
2007}
2008
2009
2010static void route_free(t_route *x)
2011{
2012 freebytes(x->x_vec, x->x_nelement * sizeof(*x->x_vec));
2013}
2014
2015static void *route_new(t_symbol *s, int argc, t_atom *argv)
2016{
2017 int n;
2018 t_routeelement *e;
2019 t_route *x = (t_route *)pd_new(route_class);
2020 t_atom a;
2021 if (argc == 0)
2022 {
2023 argc = 1;
2024 SETFLOAT(&a, 0);
2025 argv = &a;
2026 }
2027 x->x_type = argv[0].a_type;
2028 x->x_nelement = argc;
2029 x->x_vec = (t_routeelement *)getbytes(argc * sizeof(*x->x_vec));
2030 for (n = 0, e = x->x_vec; n < argc; n++, e++)
2031 {
2032 e->e_outlet = outlet_new(&x->x_obj, &s_list);
2033 if (x->x_type == A_FLOAT)
2034 e->e_w.w_float = atom_getfloatarg(n, argc, argv);
2035 else e->e_w.w_symbol = atom_getsymbolarg(n, argc, argv);
2036 }
2037 x->x_rejectout = outlet_new(&x->x_obj, &s_list);
2038 return (x);
2039}
2040
2041void route_setup(void)
2042{
2043 route_class = class_new(gensym("route"), (t_newmethod)route_new,
2044 (t_method)route_free, sizeof(t_route), 0, A_GIMME, 0);
2045 class_addlist(route_class, route_list);
2046 class_addanything(route_class, route_anything);
2047}
2048
2049/* -------------------------- pack ------------------------------ */
2050
2051static t_class *pack_class;
2052
2053typedef struct _pack
2054{
2055 t_object x_obj;
2056 t_int x_n; /* number of args */
2057 t_atom *x_vec; /* input values */
2058 t_int x_nptr; /* number of pointers */
2059 t_gpointer *x_gpointer; /* the pointers */
2060 t_atom *x_outvec; /* space for output values */
2061} t_pack;
2062
2063static void *pack_new(t_symbol *s, int argc, t_atom *argv)
2064{
2065 t_pack *x = (t_pack *)pd_new(pack_class);
2066 t_atom defarg[2], *ap, *vec, *vp;
2067 t_gpointer *gp;
2068 int nptr = 0;
2069 int i;
2070 if (!argc)
2071 {
2072 argv = defarg;
2073 argc = 2;
2074 SETFLOAT(&defarg[0], 0);
2075 SETFLOAT(&defarg[1], 0);
2076 }
2077
2078 x->x_n = argc;
2079 vec = x->x_vec = (t_atom *)getbytes(argc * sizeof(*x->x_vec));
2080 x->x_outvec = (t_atom *)getbytes(argc * sizeof(*x->x_outvec));
2081
2082 for (i = argc, ap = argv; i--; ap++)
2083 if (ap->a_type == A_SYMBOL && *ap->a_w.w_symbol->s_name == 'p')
2084 nptr++;
2085
2086 gp = x->x_gpointer = (t_gpointer *)t_getbytes(nptr * sizeof (*gp));
2087 x->x_nptr = nptr;
2088
2089 for (i = 0, vp = x->x_vec, ap = argv; i < argc; i++, ap++, vp++)
2090 {
2091 if (ap->a_type == A_FLOAT)
2092 {
2093 *vp = *ap;
2094 if (i) floatinlet_new(&x->x_obj, &vp->a_w.w_float);
2095 }
2096 else if (ap->a_type == A_SYMBOL)
2097 {
2098 char c = *ap->a_w.w_symbol->s_name;
2099 if (c == 's')
2100 {
2101 SETSYMBOL(vp, &s_symbol);
2102 if (i) symbolinlet_new(&x->x_obj, &vp->a_w.w_symbol);
2103 }
2104 else if (c == 'p')
2105 {
2106 vp->a_type = A_POINTER;
2107 vp->a_w.w_gpointer = gp;
2108 gpointer_init(gp);
2109 if (i) pointerinlet_new(&x->x_obj, gp);
2110 gp++;
2111 }
2112 else
2113 {
2114 if (c != 'f') pd_error(x, "pack: %s: bad type",
2115 ap->a_w.w_symbol->s_name);
2116 SETFLOAT(vp, 0);
2117 if (i) floatinlet_new(&x->x_obj, &vp->a_w.w_float);
2118 }
2119 }
2120 }
2121 outlet_new(&x->x_obj, &s_list);
2122 return (x);
2123}
2124
2125static void pack_bang(t_pack *x)
2126{
2127 int i, reentered = 0, size = x->x_n * sizeof (t_atom);
2128 t_gpointer *gp;
2129 t_atom *outvec;
2130 for (i = x->x_nptr, gp = x->x_gpointer; i--; gp++)
2131 if (!gpointer_check(gp, 1))
2132 {
2133 pd_error(x, "pack: stale pointer");
2134 return;
2135 }
2136 /* reentrancy protection. The first time through use the pre-allocated
2137 x_outvec; if we're reentered we have to allocate new memory. */
2138 if (!x->x_outvec)
2139 {
2140 /* LATER figure out how to deal with reentrancy and pointers... */
2141 if (x->x_nptr)
2142 post("pack_bang: warning: reentry with pointers unprotected");
2143 outvec = t_getbytes(size);
2144 reentered = 1;
2145 }
2146 else
2147 {
2148 outvec = x->x_outvec;
2149 x->x_outvec = 0;
2150 }
2151 memcpy(outvec, x->x_vec, size);
2152 outlet_list(x->x_obj.ob_outlet, &s_list, x->x_n, outvec);
2153 if (reentered)
2154 t_freebytes(outvec, size);
2155 else x->x_outvec = outvec;
2156}
2157
2158static void pack_pointer(t_pack *x, t_gpointer *gp)
2159{
2160 if (x->x_vec->a_type == A_POINTER)
2161 {
2162 gpointer_unset(x->x_gpointer);
2163 *x->x_gpointer = *gp;
2164 if (gp->gp_stub) gp->gp_stub->gs_refcount++;
2165 pack_bang(x);
2166 }
2167 else pd_error(x, "pack_pointer: wrong type");
2168}
2169
2170static void pack_float(t_pack *x, t_float f)
2171{
2172 if (x->x_vec->a_type == A_FLOAT)
2173 {
2174 x->x_vec->a_w.w_float = f;
2175 pack_bang(x);
2176 }
2177 else pd_error(x, "pack_float: wrong type");
2178}
2179
2180static void pack_symbol(t_pack *x, t_symbol *s)
2181{
2182 if (x->x_vec->a_type == A_SYMBOL)
2183 {
2184 x->x_vec->a_w.w_symbol = s;
2185 pack_bang(x);
2186 }
2187 else pd_error(x, "pack_symbol: wrong type");
2188}
2189
2190static void pack_list(t_pack *x, t_symbol *s, int ac, t_atom *av)
2191{
2192 obj_list(&x->x_obj, 0, ac, av);
2193}
2194
2195static void pack_anything(t_pack *x, t_symbol *s, int ac, t_atom *av)
2196{
2197 t_atom *av2 = (t_atom *)getbytes((ac + 1) * sizeof(t_atom));
2198 int i;
2199 for (i = 0; i < ac; i++)
2200 av2[i + 1] = av[i];
2201 SETSYMBOL(av2, s);
2202 obj_list(&x->x_obj, 0, ac+1, av2);
2203 freebytes(av2, (ac + 1) * sizeof(t_atom));
2204}
2205
2206static void pack_free(t_pack *x)
2207{
2208 t_gpointer *gp;
2209 int i;
2210 for (gp = x->x_gpointer, i = x->x_nptr; i--; gp++)
2211 gpointer_unset(gp);
2212 freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
2213 freebytes(x->x_outvec, x->x_n * sizeof(*x->x_outvec));
2214 freebytes(x->x_gpointer, x->x_nptr * sizeof(*x->x_gpointer));
2215}
2216
2217static void pack_setup(void)
2218{
2219 pack_class = class_new(gensym("pack"), (t_newmethod)pack_new,
2220 (t_method)pack_free, sizeof(t_pack), 0, A_GIMME, 0);
2221 class_addbang(pack_class, pack_bang);
2222 class_addpointer(pack_class, pack_pointer);
2223 class_addfloat(pack_class, pack_float);
2224 class_addsymbol(pack_class, pack_symbol);
2225 class_addlist(pack_class, pack_list);
2226 class_addanything(pack_class, pack_anything);
2227}
2228
2229/* -------------------------- unpack ------------------------------ */
2230
2231static t_class *unpack_class;
2232
2233typedef struct unpackout
2234{
2235 t_atomtype u_type;
2236 t_outlet *u_outlet;
2237} t_unpackout;
2238
2239typedef struct _unpack
2240{
2241 t_object x_obj;
2242 t_int x_n;
2243 t_unpackout *x_vec;
2244} t_unpack;
2245
2246static void *unpack_new(t_symbol *s, int argc, t_atom *argv)
2247{
2248 t_unpack *x = (t_unpack *)pd_new(unpack_class);
2249 t_atom defarg[2], *ap;
2250 t_unpackout *u;
2251 int i;
2252 if (!argc)
2253 {
2254 argv = defarg;
2255 argc = 2;
2256 SETFLOAT(&defarg[0], 0);
2257 SETFLOAT(&defarg[1], 0);
2258 }
2259 x->x_n = argc;
2260 x->x_vec = (t_unpackout *)getbytes(argc * sizeof(*x->x_vec));
2261 for (i = 0, ap = argv, u = x->x_vec; i < argc; u++, ap++, i++)
2262 {
2263 t_atomtype type = ap->a_type;
2264 if (type == A_SYMBOL)
2265 {
2266 char c = *ap->a_w.w_symbol->s_name;
2267 if (c == 's')
2268 {
2269 u->u_type = A_SYMBOL;
2270 u->u_outlet = outlet_new(&x->x_obj, &s_symbol);
2271 }
2272 else if (c == 'p')
2273 {
2274 u->u_type = A_POINTER;
2275 u->u_outlet = outlet_new(&x->x_obj, &s_pointer);
2276 }
2277 else
2278 {
2279 if (c != 'f') pd_error(x, "unpack: %s: bad type",
2280 ap->a_w.w_symbol->s_name);
2281 u->u_type = A_FLOAT;
2282 u->u_outlet = outlet_new(&x->x_obj, &s_float);
2283 }
2284 }
2285 else
2286 {
2287 u->u_type = A_FLOAT;
2288 u->u_outlet = outlet_new(&x->x_obj, &s_float);
2289 }
2290 }
2291 return (x);
2292}
2293
2294static void unpack_list(t_unpack *x, t_symbol *s, int argc, t_atom *argv)
2295{
2296 t_atom *ap;
2297 t_unpackout *u;
2298 int i;
2299 if (argc > x->x_n) argc = x->x_n;
2300 for (i = argc, u = x->x_vec + i, ap = argv + i; u--, ap--, i--;)
2301 {
2302 t_atomtype type = u->u_type;
2303 if (type != ap->a_type)
2304 pd_error(x, "unpack: type mismatch");
2305 else if (type == A_FLOAT)
2306 outlet_float(u->u_outlet, ap->a_w.w_float);
2307 else if (type == A_SYMBOL)
2308 outlet_symbol(u->u_outlet, ap->a_w.w_symbol);
2309 else outlet_pointer(u->u_outlet, ap->a_w.w_gpointer);
2310 }
2311}
2312
2313static void unpack_anything(t_unpack *x, t_symbol *s, int ac, t_atom *av)
2314{
2315 t_atom *av2 = (t_atom *)getbytes((ac + 1) * sizeof(t_atom));
2316 int i;
2317 for (i = 0; i < ac; i++)
2318 av2[i + 1] = av[i];
2319 SETSYMBOL(av2, s);
2320 unpack_list(x, 0, ac+1, av2);
2321 freebytes(av2, (ac + 1) * sizeof(t_atom));
2322}
2323
2324static void unpack_free(t_unpack *x)
2325{
2326 freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
2327}
2328
2329static void unpack_setup(void)
2330{
2331 unpack_class = class_new(gensym("unpack"), (t_newmethod)unpack_new,
2332 (t_method)unpack_free, sizeof(t_unpack), 0, A_GIMME, 0);
2333 class_addlist(unpack_class, unpack_list);
2334 class_addanything(unpack_class, unpack_anything);
2335}
2336
2337/* -------------------------- trigger ------------------------------ */
2338
2339static t_class *trigger_class;
2340#define TR_BANG 0
2341#define TR_FLOAT 1
2342#define TR_SYMBOL 2
2343#define TR_POINTER 3
2344#define TR_LIST 4
2345#define TR_ANYTHING 5
2346
2347typedef struct triggerout
2348{
2349 int u_type; /* outlet type from above */
2350 t_outlet *u_outlet;
2351} t_triggerout;
2352
2353typedef struct _trigger
2354{
2355 t_object x_obj;
2356 t_int x_n;
2357 t_triggerout *x_vec;
2358} t_trigger;
2359
2360static void *trigger_new(t_symbol *s, int argc, t_atom *argv)
2361{
2362 t_trigger *x = (t_trigger *)pd_new(trigger_class);
2363 t_atom defarg[2], *ap;
2364 t_triggerout *u;
2365 int i;
2366 if (!argc)
2367 {
2368 argv = defarg;
2369 argc = 2;
2370 SETSYMBOL(&defarg[0], &s_bang);
2371 SETSYMBOL(&defarg[1], &s_bang);
2372 }
2373 x->x_n = argc;
2374 x->x_vec = (t_triggerout *)getbytes(argc * sizeof(*x->x_vec));
2375 for (i = 0, ap = argv, u = x->x_vec; i < argc; u++, ap++, i++)
2376 {
2377 t_atomtype thistype = ap->a_type;
2378 char c;
2379 if (thistype == TR_SYMBOL) c = ap->a_w.w_symbol->s_name[0];
2380 else if (thistype == TR_FLOAT) c = 'f';
2381 else c = 0;
2382 if (c == 'p')
2383 u->u_type = TR_POINTER,
2384 u->u_outlet = outlet_new(&x->x_obj, &s_pointer);
2385 else if (c == 'f')
2386 u->u_type = TR_FLOAT, u->u_outlet = outlet_new(&x->x_obj, &s_float);
2387 else if (c == 'b')
2388 u->u_type = TR_BANG, u->u_outlet = outlet_new(&x->x_obj, &s_bang);
2389 else if (c == 'l')
2390 u->u_type = TR_LIST, u->u_outlet = outlet_new(&x->x_obj, &s_list);
2391 else if (c == 's')
2392 u->u_type = TR_SYMBOL,
2393 u->u_outlet = outlet_new(&x->x_obj, &s_symbol);
2394 else if (c == 'a')
2395 u->u_type = TR_ANYTHING,
2396 u->u_outlet = outlet_new(&x->x_obj, &s_symbol);
2397 else
2398 {
2399 pd_error(x, "trigger: %s: bad type", ap->a_w.w_symbol->s_name);
2400 u->u_type = TR_FLOAT, u->u_outlet = outlet_new(&x->x_obj, &s_float);
2401 }
2402 }
2403 return (x);
2404}
2405
2406static void trigger_list(t_trigger *x, t_symbol *s, int argc, t_atom *argv)
2407{
2408 t_triggerout *u;
2409 int i;
2410 t_atom at;
2411 if (!argc)
2412 {
2413 argc = 1;
2414 SETFLOAT(&at, 0);
2415 argv = &at;
2416 }
2417 for (i = x->x_n, u = x->x_vec + i; u--, i--;)
2418 {
2419 if (u->u_type == TR_FLOAT)
2420 outlet_float(u->u_outlet, atom_getfloat(argv));
2421 else if (u->u_type == TR_BANG)
2422 outlet_bang(u->u_outlet);
2423 else if (u->u_type == TR_SYMBOL)
2424 outlet_symbol(u->u_outlet, atom_getsymbol(argv));
2425 else if (u->u_type == TR_POINTER)
2426 {
2427 if (argv->a_type != TR_POINTER)
2428 pd_error(x, "unpack: bad pointer");
2429 else outlet_pointer(u->u_outlet, argv->a_w.w_gpointer);
2430 }
2431 else outlet_list(u->u_outlet, &s_list, argc, argv);
2432 }
2433}
2434
2435static void trigger_anything(t_trigger *x, t_symbol *s, int argc, t_atom *argv)
2436{
2437 t_triggerout *u;
2438 int i;
2439 for (i = x->x_n, u = x->x_vec + i; u--, i--;)
2440 {
2441 if (u->u_type == TR_BANG)
2442 outlet_bang(u->u_outlet);
2443 else if (u->u_type == TR_ANYTHING)
2444 outlet_anything(u->u_outlet, s, argc, argv);
2445 else pd_error(x, "trigger: can only convert 's' to 'b' or 'a'",
2446 s->s_name);
2447 }
2448}
2449
2450static void trigger_bang(t_trigger *x)
2451{
2452 trigger_list(x, 0, 0, 0);
2453}
2454
2455static void trigger_pointer(t_trigger *x, t_gpointer *gp)
2456{
2457 t_atom at;
2458 SETPOINTER(&at, gp);
2459 trigger_list(x, 0, 1, &at);
2460}
2461
2462static void trigger_float(t_trigger *x, t_float f)
2463{
2464 t_atom at;
2465 SETFLOAT(&at, f);
2466 trigger_list(x, 0, 1, &at);
2467}
2468
2469static void trigger_symbol(t_trigger *x, t_symbol *s)
2470{
2471 t_atom at;
2472 SETSYMBOL(&at, s);
2473 trigger_list(x, 0, 1, &at);
2474}
2475
2476static void trigger_free(t_trigger *x)
2477{
2478 freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
2479}
2480
2481static void trigger_setup(void)
2482{
2483 trigger_class = class_new(gensym("trigger"), (t_newmethod)trigger_new,
2484 (t_method)trigger_free, sizeof(t_trigger), 0, A_GIMME, 0);
2485 class_addcreator((t_newmethod)trigger_new, gensym("t"), A_GIMME, 0);
2486 class_addlist(trigger_class, trigger_list);
2487 class_addbang(trigger_class, trigger_bang);
2488 class_addpointer(trigger_class, trigger_pointer);
2489 class_addfloat(trigger_class, (t_method)trigger_float);
2490 class_addsymbol(trigger_class, trigger_symbol);
2491 class_addanything(trigger_class, trigger_anything);
2492}
2493
2494/* -------------------------- spigot ------------------------------ */
2495static t_class *spigot_class;
2496
2497typedef struct _spigot
2498{
2499 t_object x_obj;
2500 float x_state;
2501} t_spigot;
2502
2503static void *spigot_new(void)
2504{
2505 t_spigot *x = (t_spigot *)pd_new(spigot_class);
2506 floatinlet_new(&x->x_obj, &x->x_state);
2507 outlet_new(&x->x_obj, 0);
2508 x->x_state = 0;
2509 return (x);
2510}
2511
2512static void spigot_bang(t_spigot *x)
2513{
2514 if (x->x_state != 0) outlet_bang(x->x_obj.ob_outlet);
2515}
2516
2517static void spigot_pointer(t_spigot *x, t_gpointer *gp)
2518{
2519 if (x->x_state != 0) outlet_pointer(x->x_obj.ob_outlet, gp);
2520}
2521
2522static void spigot_float(t_spigot *x, t_float f)
2523{
2524 if (x->x_state != 0) outlet_float(x->x_obj.ob_outlet, f);
2525}
2526
2527static void spigot_symbol(t_spigot *x, t_symbol *s)
2528{
2529 if (x->x_state != 0) outlet_symbol(x->x_obj.ob_outlet, s);
2530}
2531
2532static void spigot_list(t_spigot *x, t_symbol *s, int argc, t_atom *argv)
2533{
2534 if (x->x_state != 0) outlet_list(x->x_obj.ob_outlet, s, argc, argv);
2535}
2536
2537static void spigot_anything(t_spigot *x, t_symbol *s, int argc, t_atom *argv)
2538{
2539 if (x->x_state != 0) outlet_anything(x->x_obj.ob_outlet, s, argc, argv);
2540}
2541
2542static void spigot_setup(void)
2543{
2544 spigot_class = class_new(gensym("spigot"), (t_newmethod)spigot_new, 0,
2545 sizeof(t_spigot), 0, A_DEFSYM, 0);
2546 class_addbang(spigot_class, spigot_bang);
2547 class_addpointer(spigot_class, spigot_pointer);
2548 class_addfloat(spigot_class, spigot_float);
2549 class_addsymbol(spigot_class, spigot_symbol);
2550 class_addlist(spigot_class, spigot_list);
2551 class_addanything(spigot_class, spigot_anything);
2552}
2553
2554/* --------------------------- moses ----------------------------- */
2555static t_class *moses_class;
2556
2557typedef struct _moses
2558{
2559 t_object x_ob;
2560 t_outlet *x_out2;
2561 float x_y;
2562} t_moses;
2563
2564static void *moses_new(t_floatarg f)
2565{
2566 t_moses *x = (t_moses *)pd_new(moses_class);
2567 floatinlet_new(&x->x_ob, &x->x_y);
2568 outlet_new(&x->x_ob, &s_float);
2569 x->x_out2 = outlet_new(&x->x_ob, &s_float);
2570 x->x_y = f;
2571 return (x);
2572}
2573
2574static void moses_float(t_moses *x, t_float f)
2575{
2576 if (f < x->x_y) outlet_float(x->x_ob.ob_outlet, f);
2577 else outlet_float(x->x_out2, f);
2578}
2579
2580static void moses_setup(void)
2581{
2582 moses_class = class_new(gensym("moses"), (t_newmethod)moses_new, 0,
2583 sizeof(t_moses), 0, A_DEFFLOAT, 0);
2584 class_addfloat(moses_class, moses_float);
2585}
2586
2587/* ----------------------- until --------------------- */
2588
2589static t_class *until_class;
2590
2591typedef struct _until
2592{
2593 t_object x_obj;
2594 int x_run;
2595 int x_count;
2596} t_until;
2597
2598static void *until_new(void)
2599{
2600 t_until *x = (t_until *)pd_new(until_class);
2601 inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("bang"), gensym("bang2"));
2602 outlet_new(&x->x_obj, &s_bang);
2603 x->x_run = 0;
2604 return (x);
2605}
2606
2607static void until_bang(t_until *x)
2608{
2609 x->x_run = 1;
2610 x->x_count = -1;
2611 while (x->x_run && x->x_count)
2612 x->x_count--, outlet_bang(x->x_obj.ob_outlet);
2613}
2614
2615static void until_float(t_until *x, t_float f)
2616{
2617 x->x_run = 1;
2618 x->x_count = f;
2619 while (x->x_run && x->x_count)
2620 x->x_count--, outlet_bang(x->x_obj.ob_outlet);
2621}
2622
2623static void until_bang2(t_until *x)
2624{
2625 x->x_run = 0;
2626}
2627
2628static void until_setup(void)
2629{
2630 until_class = class_new(gensym("until"), (t_newmethod)until_new, 0,
2631 sizeof(t_until), 0, 0);
2632 class_addbang(until_class, until_bang);
2633 class_addfloat(until_class, until_float);
2634 class_addmethod(until_class, (t_method)until_bang2, gensym("bang2"), 0);
2635}
2636
2637/* ----------------------- makefilename --------------------- */
2638
2639static t_class *makefilename_class;
2640
2641typedef struct _makefilename
2642{
2643 t_object x_obj;
2644 t_symbol *x_format;
2645} t_makefilename;
2646
2647static void *makefilename_new(t_symbol *s)
2648{
2649 t_makefilename *x = (t_makefilename *)pd_new(makefilename_class);
2650 if (!s->s_name) s = gensym("file.%d");
2651 outlet_new(&x->x_obj, &s_symbol);
2652 x->x_format = s;
2653 return (x);
2654}
2655
2656static void makefilename_float(t_makefilename *x, t_floatarg f)
2657{
2658 char buf[MAXPDSTRING];
2659 sprintf(buf, x->x_format->s_name, (int)f);
2660 outlet_symbol(x->x_obj.ob_outlet, gensym(buf));
2661}
2662
2663static void makefilename_symbol(t_makefilename *x, t_symbol *s)
2664{
2665 char buf[MAXPDSTRING];
2666 sprintf(buf, x->x_format->s_name, s->s_name);
2667 outlet_symbol(x->x_obj.ob_outlet, gensym(buf));
2668}
2669
2670static void makefilename_setup(void)
2671{
2672 makefilename_class = class_new(gensym("makefilename"),
2673 (t_newmethod)makefilename_new, 0,
2674 sizeof(t_makefilename), 0, A_DEFSYM, 0);
2675 class_addfloat(makefilename_class, makefilename_float);
2676 class_addsymbol(makefilename_class, makefilename_symbol);
2677}
2678
2679/* -------------------------- swap ------------------------------ */
2680static t_class *swap_class;
2681
2682typedef struct _swap
2683{
2684 t_object x_obj;
2685 t_outlet *x_out2;
2686 t_float x_f1;
2687 t_float x_f2;
2688} t_swap;
2689
2690static void *swap_new(t_floatarg f)
2691{
2692 t_swap *x = (t_swap *)pd_new(swap_class);
2693 x->x_f2 = f;
2694 x->x_f1 = 0;
2695 outlet_new(&x->x_obj, &s_float);
2696 x->x_out2 = outlet_new(&x->x_obj, &s_float);
2697 floatinlet_new(&x->x_obj, &x->x_f2);
2698 return (x);
2699}
2700
2701static void swap_bang(t_swap *x)
2702{
2703 outlet_float(x->x_out2, x->x_f1);
2704 outlet_float(x->x_obj.ob_outlet, x->x_f2);
2705}
2706
2707static void swap_float(t_swap *x, t_float f)
2708{
2709 x->x_f1 = f;
2710 swap_bang(x);
2711}
2712
2713void swap_setup(void)
2714{
2715 swap_class = class_new(gensym("swap"), (t_newmethod)swap_new, 0,
2716 sizeof(t_swap), 0, A_DEFFLOAT, 0);
2717 class_addcreator((t_newmethod)swap_new, gensym("fswap"), A_DEFFLOAT, 0);
2718 class_addbang(swap_class, swap_bang);
2719 class_addfloat(swap_class, swap_float);
2720}
2721
2722/* -------------------------- change ------------------------------ */
2723static t_class *change_class;
2724
2725typedef struct _change
2726{
2727 t_object x_obj;
2728 t_float x_f;
2729} t_change;
2730
2731static void *change_new(t_floatarg f)
2732{
2733 t_change *x = (t_change *)pd_new(change_class);
2734 x->x_f = f;
2735 outlet_new(&x->x_obj, &s_float);
2736 return (x);
2737}
2738
2739static void change_bang(t_change *x)
2740{
2741 outlet_float(x->x_obj.ob_outlet, x->x_f);
2742}
2743
2744static void change_float(t_change *x, t_float f)
2745{
2746 if (f != x->x_f)
2747 {
2748 x->x_f = f;
2749 outlet_float(x->x_obj.ob_outlet, x->x_f);
2750 }
2751}
2752
2753static void change_set(t_change *x, t_float f)
2754{
2755 x->x_f = f;
2756}
2757
2758void change_setup(void)
2759{
2760 change_class = class_new(gensym("change"), (t_newmethod)change_new, 0,
2761 sizeof(t_change), 0, A_DEFFLOAT, 0);
2762 class_addbang(change_class, change_bang);
2763 class_addfloat(change_class, change_float);
2764 class_addmethod(change_class, (t_method)change_set, gensym("set"),
2765 A_DEFFLOAT, 0);
2766}
2767
2768/* -------------------- value ------------------------------ */
2769
2770static t_class *value_class, *vcommon_class;
2771
2772typedef struct vcommon
2773{
2774 t_pd c_pd;
2775 int c_refcount;
2776 t_float c_f;
2777} t_vcommon;
2778
2779typedef struct _value
2780{
2781 t_object x_obj;
2782 t_symbol *x_sym;
2783 t_float *x_floatstar;
2784} t_value;
2785
2786 /* get a pointer to a named floating-point variable. The variable
2787 belongs to a "vcommon" object, which is created if necessary. */
2788t_float *value_get(t_symbol *s)
2789{
2790 t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class);
2791 if (!c)
2792 {
2793 c = (t_vcommon *)pd_new(vcommon_class);
2794 c->c_f = 0;
2795 c->c_refcount = 0;
2796 pd_bind(&c->c_pd, s);
2797 }
2798 c->c_refcount++;
2799 return (&c->c_f);
2800}
2801
2802 /* release a variable. This only frees the "vcommon" resource when the
2803 last interested party releases it. */
2804void value_release(t_symbol *s)
2805{
2806 t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class);
2807 if (c)
2808 {
2809 if (!--c->c_refcount)
2810 {
2811 pd_unbind(&c->c_pd, s);
2812 pd_free(&c->c_pd);
2813 }
2814 }
2815 else bug("value_release");
2816}
2817
2818/*
2819 * value_getfloat -- obtain the float value of a "value" object
2820 * return 0 on success, 1 otherwise
2821 */
2822int
2823value_getfloat(t_symbol *s, t_float *f)
2824{
2825 t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class);
2826 if (!c)
2827 return (1);
2828 *f = c->c_f;
2829 return (0);
2830}
2831
2832/*
2833 * value_setfloat -- set the float value of a "value" object
2834 * return 0 on success, 1 otherwise
2835 */
2836int
2837value_setfloat(t_symbol *s, t_float f)
2838{
2839 t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class);
2840 if (!c)
2841 return (1);
2842 c->c_f = f;
2843 return (0);
2844}
2845
2846static void *value_new(t_symbol *s)
2847{
2848 t_value *x = (t_value *)pd_new(value_class);
2849 x->x_sym = s;
2850 x->x_floatstar = value_get(s);
2851 outlet_new(&x->x_obj, &s_float);
2852 return (x);
2853}
2854
2855static void value_bang(t_value *x)
2856{
2857 outlet_float(x->x_obj.ob_outlet, *x->x_floatstar);
2858}
2859
2860static void value_float(t_value *x, t_float f)
2861{
2862 *x->x_floatstar = f;
2863}
2864
2865static void value_ff(t_value *x)
2866{
2867 value_release(x->x_sym);
2868}
2869
2870static void value_setup(void)
2871{
2872 value_class = class_new(gensym("value"), (t_newmethod)value_new,
2873 (t_method)value_ff,
2874 sizeof(t_value), 0, A_DEFSYM, 0);
2875 class_addcreator((t_newmethod)value_new, gensym("v"), A_DEFSYM, 0);
2876 class_addbang(value_class, value_bang);
2877 class_addfloat(value_class, value_float);
2878 vcommon_class = class_new(gensym("value"), 0, 0,
2879 sizeof(t_vcommon), CLASS_PD, 0);
2880}
2881
2882/* -------------- overall setup routine for this file ----------------- */
2883
2884void x_connective_setup(void)
2885{
2886 pdint_setup();
2887 pdfloat_setup();
2888 pdsymbol_setup();
2889 bang_setup();
2890 send_setup();
2891 receive_setup();
2892 select_setup();
2893 route_setup();
2894 pack_setup();
2895 unpack_setup();
2896 trigger_setup();
2897 spigot_setup();
2898 moses_setup();
2899 until_setup();
2900 makefilename_setup();
2901 swap_setup();
2902 change_setup();
2903 value_setup();
2904}