aboutsummaryrefslogtreecommitdiff
path: root/cyclone/hammer/offer.c
blob: 3823c85f3deedcceaaebe420157f3710ac180c0b (plain)
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
/* Copyright (c) 2002-2003 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 "hammer/tree.h"

/* As a class `derived' from the common hammertree code (also in funbuff),
   offer uses the auxiliary list, generally not needed here.
   As a side-effect, it gets a bonus of a small speedup of deletion,
   and a penalty of a small slowdown of insertion. */

typedef struct _offer
{
    t_object      x_ob;
    t_float       x_value;
    int           x_valueset;
    t_hammertree  x_tree;
} t_offer;

static t_class *offer_class;

static void offer_float(t_offer *x, t_float f)
{
    int ndx;
    if (loud_checkint((t_pd *)x, f, &ndx, &s_float))  /* CHECKED */
    {
	t_hammernode *np;
	if (x->x_valueset)
	{
	    if (np = hammertree_insert(&x->x_tree, ndx))
		np->n_value = x->x_value;
	    x->x_valueset = 0;
	}
	else if (np = hammertree_search(&x->x_tree, ndx))
	{
	    outlet_float(((t_object *)x)->ob_outlet, np->n_value);
	    hammertree_delete(&x->x_tree, np);
	}
    }
}

static void offer_ft1(t_offer *x, t_floatarg f)
{
    /* this is incompatible -- CHECKED float is silently truncated */
    x->x_value = f;
    x->x_valueset = 1;
}

static void offer_clear(t_offer *x)
{
    hammertree_clear(&x->x_tree, 0);
    /* CHECKED valueset is not cleared */
}

#ifdef HAMMERTREE_DEBUG
static void offer_debug(t_offer *x, t_floatarg f)
{
    hammertree_debug(&x->x_tree, (int)f);
}
#endif

static void offer_free(t_offer *x)
{
    hammertree_clear(&x->x_tree, 0);
}

static void *offer_new(void)
{
    t_offer *x = (t_offer *)pd_new(offer_class);
    x->x_valueset = 0;
    hammertree_init(&x->x_tree, 0);
    inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft1"));
    outlet_new((t_object *)x, &s_float);
    return (x);
}

void offer_setup(void)
{
    offer_class = class_new(gensym("offer"),
			    (t_newmethod)offer_new,
			    (t_method)offer_free,
			    sizeof(t_offer), 0, 0);
    class_addfloat(offer_class, offer_float);
    class_addmethod(offer_class, (t_method)offer_ft1,
		    gensym("ft1"), A_FLOAT, 0);
    class_addmethod(offer_class, (t_method)offer_clear,
		    gensym("clear"), 0);
#ifdef HAMMERTREE_DEBUG
    class_addmethod(offer_class, (t_method)offer_debug,
		    gensym("debug"), A_DEFFLOAT, 0);
#endif
}