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
155
156
157
158
159
160
161
162
163
|
/*
flext tutorial - attributes 3
Copyright (c) 2002 Thomas Grill (xovo@gmx.net)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
-------------------------------------------------------------------------
This is tutorial example "advanced 3" with the usage of attributes.
*/
// IMPORTANT: enable attribute processing (specify before inclusion of flext headers!)
// For clarity, this is done here, but you'd better specify it as a compiler definition
// FLEXT_ATTRIBUTES must be 0 or 1,
#define FLEXT_ATTRIBUTES 1
// include flext header
#include <flext.h>
// check for appropriate flext version
#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 401)
#error You need at least flext version 0.4.1
#endif
class attr3:
public flext_base
{
FLEXT_HEADER_S(attr3,flext_base,setup)
public:
// constructor with no arguments
attr3(int argc,t_atom *argv):
i_step(1)
{
// --- initialize bounds and step size ---
int f1 = 0,f2 = 0;
switch(argc) {
default:
case 3:
i_step = GetInt(argv[2]);
case 2:
f2 = GetInt(argv[1]);
case 1:
f1 = GetInt(argv[0]);
case 0:
;
}
if(argc < 2) f2 = f1;
m_bound(f1,f2);
i_count = i_down;
// --- define inlets and outlets ---
AddInAnything(); // default inlet
AddInList(); // inlet for bounds
AddInInt(); // inlet for step size
AddOutInt(); // outlet for integer count
AddOutBang(); // outlet for bang
}
protected:
void m_reset() { i_count = i_down; }
void m_set(int argc,t_atom *argv)
{
i_count = argc?GetAInt(argv[0]):0;
}
void m_bang()
{
int f = i_count;
i_count += i_step;
if(i_down != i_up) {
if((i_step > 0) && (i_count > i_up)) {
i_count = i_down;
ToOutBang(1);
}
else if(i_count < i_down) {
i_count = i_up;
ToOutBang(1);
}
}
ToOutInt(0,f);
}
void m_bound(int f1,int f2)
{
i_down = f1 < f2?f1:f2;
i_up = f1 > f2?f1:f2;
}
void m_step(int s) { i_step = s; }
int i_count,i_down,i_up,i_step;
// setter method of bounds variables
void ms_bound(const AtomList &l)
{
if(l.Count() == 2 && CanbeInt(l[0]) && CanbeInt(l[1]))
// if it is a two element integer list use m_bound method
m_bound(GetAInt(l[0]),GetAInt(l[1]));
else
// else post a warning
post("%s - bound needs to integer parameters",thisName());
}
// getter method of bounds variables
void mg_bound(AtomList &l) const
{
l(2); // initialize two element list
SetInt(l[0],i_down); // set first element
SetInt(l[1],i_up); // set second element
}
private:
static void setup(t_class *c)
{
// --- set up methods (class scope) ---
// register a bang method to the default inlet (0)
FLEXT_CADDBANG(c,0,m_bang);
// set up tagged methods for the default inlet (0)
FLEXT_CADDMETHOD_(c,0,"reset",m_reset);
FLEXT_CADDMETHOD_(c,0,"set",m_set);
// set up methods for inlets 1 and 2
// no message tag used
FLEXT_CADDMETHOD(c,1,m_bound); // variable arg type recognized automatically
FLEXT_CADDMETHOD(c,2,m_step); // single int arg also recognized automatically
// --- set up attributes (class scope) ---
FLEXT_CADDATTR_VAR1(c,"count",i_count);
FLEXT_CADDATTR_VAR1(c,"step",i_step);
FLEXT_CADDATTR_VAR(c,"bound",mg_bound,ms_bound);
}
// normal method callbacks for bang and reset
FLEXT_CALLBACK(m_bang)
FLEXT_CALLBACK(m_reset)
FLEXT_CALLBACK_V(m_set) // normal method wrapper for m_set
FLEXT_ATTRVAR_I(i_count) // wrapper function for integer variable i_count
FLEXT_CALLBACK_II(m_bound) // normal method wrapper for m_bound
FLEXT_CALLVAR_V(mg_bound,ms_bound) // getter and setter method of bounds
FLEXT_CALLBACK_I(m_step) // normal method wrapper for m_step
FLEXT_ATTRVAR_I(i_step) // wrapper function for integer variable i_step
};
// instantiate the class (constructor has a variable argument list)
FLEXT_NEW_V("attr3",attr3)
|