1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
/* Copyright (c) 2002-2005 krzYszcz and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
#include "m_pd.h"
#include "common/loud.h"
#include "common/fitter.h"
#define SWITCH_MININLETS 2 /* LATER consider using 1 (with a warning) */
#define SWITCH_C74MAXINLETS 100
#define SWITCH_DEFINLETS 2
typedef struct _switch
{
t_object x_ob;
int x_open;
int x_ninlets; /* not counting left one */
int x_nproxies; /* as requested (and allocated) */
t_pd **x_proxies;
} t_switch;
typedef struct _switch_proxy
{
t_object p_ob;
t_switch *p_master;
int p_id;
} t_switch_proxy;
static t_class *switch_class;
static t_class *switch_proxy_class;
static void switch_proxy_bang(t_switch_proxy *x)
{
t_switch *master = x->p_master;
if (master->x_open == x->p_id)
outlet_bang(((t_object *)master)->ob_outlet);
}
static void switch_proxy_float(t_switch_proxy *x, t_float f)
{
t_switch *master = x->p_master;
if (master->x_open == x->p_id)
outlet_float(((t_object *)master)->ob_outlet, f);
}
static void switch_proxy_symbol(t_switch_proxy *x, t_symbol *s)
{
t_switch *master = x->p_master;
if (master->x_open == x->p_id)
outlet_symbol(((t_object *)master)->ob_outlet, s);
}
static void switch_proxy_pointer(t_switch_proxy *x, t_gpointer *gp)
{
t_switch *master = x->p_master;
if (master->x_open == x->p_id)
outlet_pointer(((t_object *)master)->ob_outlet, gp);
}
static void switch_proxy_list(t_switch_proxy *x,
t_symbol *s, int ac, t_atom *av)
{
t_switch *master = x->p_master;
if (master->x_open == x->p_id)
outlet_list(((t_object *)master)->ob_outlet, s, ac, av);
}
static void switch_proxy_anything(t_switch_proxy *x,
t_symbol *s, int ac, t_atom *av)
{
t_switch *master = x->p_master;
if (master->x_open == x->p_id)
outlet_anything(((t_object *)master)->ob_outlet, s, ac, av);
}
static void switch_float(t_switch *x, t_float f)
{
int i = (int)f;
if (i < 0) i = -i;
if (i > x->x_ninlets) i = x->x_ninlets;
x->x_open = i;
}
static void switch_bang(t_switch *x)
{
outlet_float(((t_object *)x)->ob_outlet, x->x_open);
}
static void switch_free(t_switch *x)
{
if (x->x_proxies)
{
int i = x->x_ninlets;
while (i--) pd_free(x->x_proxies[i]);
freebytes(x->x_proxies, x->x_nproxies * sizeof(*x->x_proxies));
}
}
static void *switch_new(t_floatarg f1, t_floatarg f2)
{
t_switch *x;
int i, ninlets, nproxies = (int)f1;
t_pd **proxies;
if (nproxies < SWITCH_MININLETS)
nproxies = SWITCH_DEFINLETS;
if (nproxies > SWITCH_C74MAXINLETS)
fittermax_rangewarning(switch_class, SWITCH_C74MAXINLETS, "inlets");
if (!(proxies = (t_pd **)getbytes(nproxies * sizeof(*proxies))))
return (0);
for (ninlets = 0; ninlets < nproxies; ninlets++)
if (!(proxies[ninlets] = pd_new(switch_proxy_class))) break;
if (ninlets < SWITCH_MININLETS)
{
int i = ninlets;
while (i--) pd_free(proxies[i]);
freebytes(proxies, nproxies * sizeof(*proxies));
return (0);
}
x = (t_switch *)pd_new(switch_class);
x->x_ninlets = ninlets;
x->x_nproxies = nproxies;
x->x_proxies = proxies;
for (i = 0; i < ninlets; i++)
{
t_switch_proxy *y = (t_switch_proxy *)proxies[i];
y->p_master = x;
y->p_id = i + 1;
inlet_new((t_object *)x, (t_pd *)y, 0, 0);
}
outlet_new((t_object *)x, &s_anything);
switch_float(x, (f2 > 0 ? f2 : 0)); /* CHECKED */
return (x);
}
void switch_setup(void)
{
switch_class = class_new(gensym("switch"),
(t_newmethod)switch_new,
(t_method)switch_free,
sizeof(t_switch), 0,
A_DEFFLOAT, A_DEFFLOAT, 0);
class_addfloat(switch_class, switch_float);
class_addbang(switch_class, switch_bang);
switch_proxy_class = class_new(gensym("_switch_proxy"), 0, 0,
sizeof(t_switch_proxy),
CLASS_PD | CLASS_NOINLET, 0);
class_addfloat(switch_proxy_class, switch_proxy_float);
class_addbang(switch_proxy_class, switch_proxy_bang);
class_addsymbol(switch_proxy_class, switch_proxy_symbol);
class_addpointer(switch_proxy_class, switch_proxy_pointer);
class_addlist(switch_proxy_class, switch_proxy_list);
class_addanything(switch_proxy_class, switch_proxy_anything);
fitter_setup(switch_class, 0);
}
|