aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/flext/tutorial/attr3/main.cpp
blob: 835c28815f69a51656c2dab3a41819a3832e0b31 (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
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)