flbase.h 15 KB
Newer Older
thomas's avatar
thomas committed
1
2
/* 

thomas's avatar
thomas committed
3
flext - C++ layer for Max/MSP and pd (pure data) externals
thomas's avatar
thomas committed
4
5
6
7
8
9
10

Copyright (c) 2001,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.  

*/

thomas's avatar
thomas committed
11
/*! \file flbase.h
thomas's avatar
thomas committed
12
	\brief Internal flext base classes
thomas's avatar
thomas committed
13
    
thomas's avatar
thomas committed
14
	\remark This is all derived from GEM by Mark Danks
thomas's avatar
thomas committed
15
*/
thomas's avatar
thomas committed
16
 
thomas's avatar
thomas committed
17
18
#ifndef __FLEXT_BASE_H
#define __FLEXT_BASE_H
thomas's avatar
thomas committed
19

thomas's avatar
thomas committed
20
#include "flstdc.h"
thomas's avatar
thomas committed
21
#include "flsupport.h"
thomas's avatar
thomas committed
22

thomas's avatar
thomas committed
23
class flext_obj;
thomas's avatar
thomas committed
24

thomas's avatar
thomas committed
25
// ----------------------------------------------------------------------------
thomas's avatar
thomas committed
26
/*! \brief The obligatory PD or Max/MSP object header
thomas's avatar
thomas committed
27
	\internal
thomas's avatar
thomas committed
28

thomas's avatar
thomas committed
29
30
    This is in a separate struct to assure that obj is the very first thing.  
    If it were the first thing in flext_obj, then there could be problems with
thomas's avatar
thomas committed
31
    the virtual table of the C++ class.
thomas's avatar
thomas committed
32
33
34
*/
// ----------------------------------------------------------------------------

thomas's avatar
thomas committed
35
struct FLEXT_EXT flext_hdr
thomas's avatar
thomas committed
36
{
thomas's avatar
thomas committed
37
38
39
40
41
	/*!	\defgroup FLEXT_OBJHEADER Actual PD or Max/MSP object
		\internal
		@{ 
	*/

thomas's avatar
thomas committed
42
    	/*! \brief The obligatory object header
thomas's avatar
thomas committed
43
			\note MUST reside at memory offset 0 (no virtual table possible)
thomas's avatar
thomas committed
44
45
		*/
    	t_sigobj    	    obj;  
thomas's avatar
thomas committed
46

thomas's avatar
thomas committed
47
#if FLEXT_SYS == FLEXT_SYS_PD
thomas's avatar
thomas committed
48
49
		//! PD only: float signal holder for pd
		float defsig;			
thomas's avatar
thomas committed
50
51
#endif

thomas's avatar
thomas committed
52
53
#if FLEXT_SYS == FLEXT_SYS_MAX
		//! Max/MSP only: current inlet used by proxy objects
thomas's avatar
thomas committed
54
		long curinlet;      
thomas's avatar
thomas committed
55
56
#endif

thomas's avatar
thomas committed
57
    	/*! \brief This points to the actual polymorphic C++ class
thomas's avatar
thomas committed
58
		*/
thomas's avatar
thomas committed
59
        flext_obj           *data;
thomas's avatar
thomas committed
60
61

	//!	@}  FLEXT_OBJHEADER
thomas's avatar
thomas committed
62
63
64
};


thomas's avatar
thomas committed
65
// ----------------------------------------------------------------------------
thomas's avatar
thomas committed
66
/*! \brief The mother of base classes for all flext external objects
thomas's avatar
thomas committed
67

thomas's avatar
thomas committed
68
    Each extern which is written in C++ needs to use the #defines at the
thomas's avatar
thomas committed
69
    end of this header file.  
thomas's avatar
thomas committed
70
71
72
    
    The define
    
thomas's avatar
thomas committed
73
        FLEXT_HEADER(NEW_CLASS, PARENT_CLASS)
thomas's avatar
thomas committed
74
75
76
77
    
    should be somewhere in your header file.
    One of the defines like
    
thomas's avatar
thomas committed
78
    FLEXT_NEW(NEW_CLASS)
thomas's avatar
thomas committed
79
	or
thomas's avatar
thomas committed
80
    FLEXT_NEW_2(NEW_CLASS, float, float)
thomas's avatar
thomas committed
81
82
83
84
    
    should be the first thing in your implementation file.
    NEW_CLASS is the name of your class and PARENT_CLASS is the 
    parent of your class.
thomas's avatar
thomas committed
85
86
87
*/
// ----------------------------------------------------------------------------

thomas's avatar
thomas committed
88
class flext_obj:
thomas's avatar
thomas committed
89
	public flext
thomas's avatar
thomas committed
90
91
92
{
    public:

thomas's avatar
thomas committed
93
94
95
96
	/*!	\defgroup FLEXT_OBJCLASS Object base class
		@{ 
	*/
// --- creation -------------------------------------------------------	
thomas's avatar
thomas committed
97

thomas's avatar
thomas committed
98
99
100
	/*!	\defgroup FLEXT_O_CREATION Creation/Destruction functionality
		@{ 
	*/
thomas's avatar
thomas committed
101

thomas's avatar
thomas committed
102
        //! Constructor
thomas's avatar
thomas committed
103
    	flext_obj();
thomas's avatar
thomas committed
104

thomas's avatar
thomas committed
105
    	//! Destructor
thomas's avatar
thomas committed
106
    	virtual ~flext_obj() = 0;
thomas's avatar
thomas committed
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

        /*! \brief Signal a construction problem
			\note This should only be used in the constructor. Object creation will be aborted.
		*/
		void InitProblem() { init_ok = false; }

		/*! \brief Enable/disable attribute procession (default = false)
			\note Use that in the static class setup function (also library setup function)
		*/
		static void ProcessAttributes(bool attr) { process_attributes = attr; }

		//! Virtual function called at creation time (but after the constructor)
		// this also guarantees that there are no instances of flext_obj
		virtual bool Init() = 0; 
	
		//! Virtual function called at destruction (before the destructor)
		virtual void Exit() {}

	//!	@}  FLEXT_O_CREATION

// --- info -------------------------------------------------------	

	/*!	\defgroup FLEXT_O_INFO Get various information
		@{ 
	*/

thomas's avatar
thomas committed
133
        //! Get the object's canvas
thomas's avatar
thomas committed
134
        t_canvas *thisCanvas() { return(m_canvas); }
thomas's avatar
thomas committed
135

thomas's avatar
thomas committed
136
        //! Get the PD or Max/MSP object
thomas's avatar
thomas committed
137
		t_sigobj *thisHdr() { return &x_obj->obj; }
thomas's avatar
thomas committed
138
        //! Get the PD or Max/MSP object
thomas's avatar
thomas committed
139
		const t_sigobj *thisHdr() const { return &x_obj->obj; }
thomas's avatar
thomas committed
140
        //! Get the class name (as a string)
thomas's avatar
thomas committed
141
		const char *thisName() const { return GetString(m_name); } 
thomas's avatar
thomas committed
142
        //! Get the class name (as a symbol)
thomas's avatar
thomas committed
143
		const t_symbol *thisNameSym() const { return m_name; } 
thomas's avatar
thomas committed
144

thomas's avatar
thomas committed
145
#if FLEXT_SYS == FLEXT_SYS_PD
thomas's avatar
thomas committed
146
        //! Get the class pointer
thomas's avatar
thomas committed
147
		t_class *thisClass() { return (t_class *)((t_object *)(x_obj))->te_g.g_pd; }
thomas's avatar
thomas committed
148
#elif FLEXT_SYS == FLEXT_SYS_MAX
thomas's avatar
thomas committed
149
        //! Get the class pointer
thomas's avatar
thomas committed
150
151
		t_class *thisClass() { return (t_class *)(((t_tinyobject *)x_obj)->t_messlist-1); } 
#endif
thomas's avatar
thomas committed
152

thomas's avatar
thomas committed
153
	//!	@}  FLEXT_O_INFO
thomas's avatar
thomas committed
154

thomas's avatar
thomas committed
155
// --- memory -------------------------------------------------------	
thomas's avatar
thomas committed
156

thomas's avatar
thomas committed
157
158
159
160
161
	/*!	\defgroup FLEXT_O_MEMORY Memory allocation functions
		@{ 
	*/

		/*! Overloaded new memory allocation method
thomas's avatar
thomas committed
162
			\warning Max/MSP (or MacOS) allows only 16K in overdrive mode!
thomas's avatar
thomas committed
163
164
165
166
167
168
169
170
171
		*/
		void *operator new(size_t bytes);
		//! Overloaded delete method
		void operator delete(void *blk);

		#ifndef __MRC__ // doesn't allow new[] overloading?!
		void *operator new[](size_t bytes) { return operator new(bytes); }
		void operator delete[](void *blk) { operator delete(blk); }
		#endif
thomas's avatar
thomas committed
172

thomas's avatar
thomas committed
173
174
175
176
177
178
179
		//! Get an aligned memory block
		static void *NewAligned(size_t bytes,int bitalign = 128);
		//! Free an aligned memory block
		static void FreeAligned(void *blk);
		
	//!	@}  FLEXT_O_MEMORY
    	
thomas's avatar
thomas committed
180
181
// --- help -------------------------------------------------------	

thomas's avatar
thomas committed
182
183
184
185
	/*!	\defgroup FLEXT_O_HELP Help/assistance functionality
		\remark This is still PD only
		@{ 
	*/
thomas's avatar
thomas committed
186

thomas's avatar
thomas committed
187
188
		/*! Define the help reference symbol for a class
			\internal
thomas's avatar
thomas committed
189
190
		*/
		static void DefineHelp(t_class *c,const char *ref,const char *dir = NULL,bool addtilde = false);
thomas's avatar
thomas committed
191
192

		//! Define the help reference symbol for a class
thomas's avatar
thomas committed
193
194
		void DefineHelp(const char *ref,const char *dir = NULL,bool addtilde = false) { DefineHelp(thisClass(),ref,dir,addtilde); }

thomas's avatar
thomas committed
195
	//!	@} 
thomas's avatar
thomas committed
196
197


thomas's avatar
thomas committed
198
199
200
201
202
203
204
// --- internal stuff -------------------------------------------------------	

	/*!	\defgroup FLEXT_O_INTERNAL Internal stuff
		\internal
		@{ 
	*/

thomas's avatar
thomas committed
205
206
    protected:    	
		
thomas's avatar
thomas committed
207
        //! The object header
thomas's avatar
thomas committed
208
        flext_hdr          *x_obj;        	
thomas's avatar
thomas committed
209

thomas's avatar
thomas committed
210
211
212
        //! Flag for attribute procession
        bool				procattr;

thomas's avatar
thomas committed
213
214
		static bool				process_attributes;

thomas's avatar
thomas committed
215
216
    private:

thomas's avatar
thomas committed
217
        //! The canvas (patcher) that the object is in
thomas's avatar
thomas committed
218
        t_canvas            *m_canvas;
thomas's avatar
thomas committed
219
220
221
        
        //! Flag for successful object construction
        bool				init_ok;
thomas's avatar
thomas committed
222

thomas's avatar
thomas committed
223
	public:
thomas's avatar
thomas committed
224

thomas's avatar
thomas committed
225
    	//! Creation callback
thomas's avatar
thomas committed
226
		static void __setup__(t_class *) { flext::Setup(); }	
thomas's avatar
thomas committed
227

thomas's avatar
thomas committed
228
229
230
		/*! \brief This is a temporary holder
			\warning don't touch it!
		*/
thomas's avatar
thomas committed
231
        static flext_hdr     *m_holder;
thomas's avatar
thomas committed
232
		//! Hold object's name during construction
thomas's avatar
thomas committed
233
        static const t_symbol *m_holdname;  
thomas's avatar
thomas committed
234

thomas's avatar
thomas committed
235
		//! Holders for attribute procession flag
thomas's avatar
thomas committed
236
		static bool m_holdattr;
thomas's avatar
thomas committed
237
238
		static int m_holdaargc;
		static const t_atom *m_holdaargv;
thomas's avatar
thomas committed
239

thomas's avatar
thomas committed
240
        //! The object's name in the patcher
thomas's avatar
thomas committed
241
		const t_symbol *m_name;
thomas's avatar
thomas committed
242

thomas's avatar
thomas committed
243
		//! Check whether construction was successful
thomas's avatar
thomas committed
244
245
		bool InitOk() const { return init_ok; }

thomas's avatar
thomas committed
246
		// Definitions for library objects
thomas's avatar
thomas committed
247
		static void lib_init(const char *name,void setupfun(),bool attr);
thomas's avatar
thomas committed
248
		static void obj_add(bool lib,bool dsp,bool attr,const char *idname,const char *names,void setupfun(t_class *),flext_obj *(*newfun)(int,t_atom *),void (*freefun)(flext_hdr *),int argtp1,...);
thomas's avatar
thomas committed
249
250
		static flext_hdr *obj_new(const t_symbol *s,int argc,t_atom *argv);
		static void obj_free(flext_hdr *o);
thomas's avatar
thomas committed
251
252
253
254

	//!	@} FLEXT_O_INTERNAL

	//!	@} FLEXT_OBJCLASS   	
thomas's avatar
thomas committed
255
256
257
};


thomas's avatar
thomas committed
258
259
260
261
262
263
// max. 4 creation args (see the following macros)
#define FLEXT_MAXNEWARGS 4 

// max. 5 method args (see the following macros)
#define FLEXT_MAXMETHARGS 5 

thomas's avatar
thomas committed
264
265
266
267
268
269
270
// prefixes for the macro generated handler functions
#define FLEXT_CALL_PRE(F) flext_c_##F
#define FLEXT_THR_PRE(F) flext_t_##F
#define FLEXT_GET_PRE(F) flext_g_##F
#define FLEXT_SET_PRE(F) flext_s_##F


thomas's avatar
thomas committed
271
#ifndef FLEXT_ATTRIBUTES
thomas's avatar
thomas committed
272
273
274
275
276
277
278
/*! \brief Switch for global attribute processing
	\note Should be set to 1 or 0 (or not be defined)
	\ingroup FLEXT_DEFS
*/
#define FLEXT_ATTRIBUTES \
\
0
thomas's avatar
thomas committed
279
280
#endif

thomas's avatar
thomas committed
281
// ----------------------------------------
thomas's avatar
thomas committed
282
// These should be used in the header
thomas's avatar
thomas committed
283
// ----------------------------------------
thomas's avatar
thomas committed
284

thomas's avatar
thomas committed
285

thomas's avatar
thomas committed
286
#define FLEXT_REALHDR(NEW_CLASS, PARENT_CLASS)    	    	\
thomas's avatar
thomas committed
287
288
public:     	    	    \
typedef NEW_CLASS thisType;  \
thomas's avatar
thomas committed
289
290
static flext_obj *__init__(int argc,t_atom *argv);  \
static void __free__(flext_hdr *hdr)    	    	    	\
thomas's avatar
thomas committed
291
292
{ flext_obj *mydata = hdr->data; delete mydata; \
  hdr->flext_hdr::~flext_hdr(); }   	    	\
thomas's avatar
thomas committed
293
static void __setup__(t_class *classPtr) { 	    	\
thomas's avatar
thomas committed
294
	PARENT_CLASS::__setup__(classPtr); } \
thomas's avatar
thomas committed
295
protected:    \
thomas's avatar
thomas committed
296
static inline NEW_CLASS *thisObject(void *c) { return FLEXT_CAST<NEW_CLASS *>(((flext_hdr *)c)->data); } 
thomas's avatar
thomas committed
297

thomas's avatar
thomas committed
298

thomas's avatar
thomas committed
299
#define FLEXT_REALHDR_S(NEW_CLASS, PARENT_CLASS,SETUPFUN)    	    	\
thomas's avatar
thomas committed
300
301
public:     	    	    \
typedef NEW_CLASS thisType;  \
thomas's avatar
thomas committed
302
303
static flext_obj *__init__(int argc,t_atom *argv);  \
static void __free__(flext_hdr *hdr)    	    	    	\
thomas's avatar
thomas committed
304
305
{ flext_obj *mydata = hdr->data; delete mydata; \
  hdr->flext_hdr::~flext_hdr(); }   	    	\
thomas's avatar
thomas committed
306
307
static void __setup__(t_class *classPtr)  	    	\
{ PARENT_CLASS::__setup__(classPtr);    	    	\
thomas's avatar
thomas committed
308
	NEW_CLASS::SETUPFUN(classPtr); 	}    	    	\
thomas's avatar
thomas committed
309
310
protected: \
static inline NEW_CLASS *thisObject(void *c) { return FLEXT_CAST<NEW_CLASS *>(((flext_hdr *)c)->data); }
thomas's avatar
thomas committed
311

thomas's avatar
thomas committed
312

thomas's avatar
thomas committed
313
314
315
// generate name of dsp/non-dsp setup function
#define FLEXT_STPF_0(NAME) NAME##_setup
#define FLEXT_STPF_1(NAME) NAME##_tilde_setup
thomas's avatar
thomas committed
316
317
#define FLEXT_STPF_(DSP) FLEXT_STPF_##DSP
#define FLEXT_STPF(NAME,DSP) FLEXT_STPF_(DSP)(NAME)
thomas's avatar
thomas committed
318

thomas's avatar
thomas committed
319

thomas's avatar
thomas committed
320

thomas's avatar
thomas committed
321
// --------------------------------------------------------------------------------------
thomas's avatar
thomas committed
322

thomas's avatar
thomas committed
323

thomas's avatar
thomas committed
324

thomas's avatar
thomas committed
325
326
// these can be used in library setup functions 
// to register the individual objects in the library
thomas's avatar
thomas committed
327

thomas's avatar
thomas committed
328
#define REAL_SETUP_0(cl) \
thomas's avatar
thomas committed
329
330
extern void cl##_setup(); \
cl##_setup()  
thomas's avatar
thomas committed
331

thomas's avatar
thomas committed
332
#define REAL_SETUP_1(cl) \
thomas's avatar
thomas committed
333
334
extern void cl##_tilde_setup(); \
cl##_tilde_setup()  
thomas's avatar
thomas committed
335

thomas's avatar
thomas committed
336
#define REAL_SETUP(cl,DSP) REAL_SETUP_##DSP(cl)
thomas's avatar
thomas committed
337
338
339

// specify that to define the library itself

thomas's avatar
thomas committed
340
#if FLEXT_SYS == FLEXT_SYS_PD
thomas's avatar
thomas committed
341
#define REAL_LIB_SETUP(NAME,SETUPFUN) extern "C" FLEXT_EXT void NAME##_setup() { flext_obj::lib_init(#NAME,SETUPFUN,FLEXT_ATTRIBUTES); }
thomas's avatar
thomas committed
342
#elif FLEXT_SYS == FLEXT_SYS_MAX
thomas's avatar
thomas committed
343
#define REAL_LIB_SETUP(NAME,SETUPFUN) extern "C" FLEXT_EXT int main() { flext_obj::lib_init(#NAME,SETUPFUN,FLEXT_ATTRIBUTES); return 0; }
thomas's avatar
thomas committed
344
345
#else
#error
thomas's avatar
thomas committed
346
#endif
thomas's avatar
thomas committed
347

thomas's avatar
thomas committed
348
349
350
351
352
353
354
355

// --------------------------------------------------


#define FLEXT_EXP_0 extern "C" FLEXT_EXT
#define FLEXT_EXP_1 
#define FLEXT_EXP(LIB) FLEXT_EXP_##LIB

thomas's avatar
thomas committed
356
#if FLEXT_SYS == FLEXT_SYS_PD
thomas's avatar
thomas committed
357
#define FLEXT_OBJ_SETUP_0(NEW_CLASS,DSP)
thomas's avatar
thomas committed
358
#elif FLEXT_SYS == FLEXT_SYS_MAX
thomas's avatar
thomas committed
359
#define FLEXT_OBJ_SETUP_0(NEW_CLASS,DSP) extern "C" FLEXT_EXT int main() { FLEXT_STPF(NEW_CLASS,DSP)(); return 0; }
thomas's avatar
thomas committed
360
361
#else
#error
thomas's avatar
thomas committed
362
#endif
thomas's avatar
thomas committed
363

thomas's avatar
thomas committed
364
365
366
#define FLEXT_OBJ_SETUP_1(NEW_CLASS,DSP)

#define FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB) FLEXT_OBJ_SETUP_##LIB(NEW_CLASS,DSP)
thomas's avatar
thomas committed
367
368


thomas's avatar
thomas committed
369

thomas's avatar
thomas committed
370
// ----------------------------------------
thomas's avatar
thomas committed
371
// These definitions are used below
thomas's avatar
thomas committed
372
// ----------------------------------------
thomas's avatar
thomas committed
373

thomas's avatar
thomas committed
374
// Shortcuts for PD/Max type arguments
thomas's avatar
thomas committed
375
#define FLEXTTYPE_void A_NULL
thomas's avatar
thomas committed
376
#define CALLBTYPE_void void
thomas's avatar
thomas committed
377
#define FLEXTTYPE_float A_FLOAT
thomas's avatar
thomas committed
378
#define CALLBTYPE_float float
thomas's avatar
thomas committed
379
#define FLEXTTYPE_t_float A_FLOAT
thomas's avatar
thomas committed
380
381
#define CALLBTYPE_t_float t_float

thomas's avatar
thomas committed
382
#if FLEXT_SYS == FLEXT_SYS_PD
thomas's avatar
thomas committed
383
384
#define FLEXTTYPE_int A_FLOAT
#define CALLBTYPE_int float
thomas's avatar
thomas committed
385
#elif FLEXT_SYS == FLEXT_SYS_MAX
thomas's avatar
thomas committed
386
387
#define FLEXTTYPE_int A_INT
#define CALLBTYPE_int int
thomas's avatar
thomas committed
388
389
#else
#error
thomas's avatar
thomas committed
390
391
#endif

thomas's avatar
thomas committed
392
#define FLEXTTYPE_t_symptr A_SYMBOL
thomas's avatar
thomas committed
393
#define CALLBTYPE_t_symptr t_symptr
thomas's avatar
thomas committed
394
395
#define FLEXTTYPE_t_symtype A_SYMBOL
#define CALLBTYPE_t_symtype t_symptr
thomas's avatar
thomas committed
396
#define FLEXTTYPE_t_ptrtype A_POINTER
thomas's avatar
thomas committed
397
#define CALLBTYPE_t_ptrtype t_ptrtype
thomas's avatar
thomas committed
398
399

#define FLEXTTP(TP) FLEXTTYPE_ ## TP
thomas's avatar
thomas committed
400
#define CALLBTP(TP) CALLBTYPE_ ## TP
thomas's avatar
thomas committed
401
402


thomas's avatar
thomas committed
403
404
405
406
407
#define ARGMEMBER_int(a) GetInt(a)
#define ARGMEMBER_float(a) GetFloat(a)
#define ARGMEMBER_t_symptr(a) GetSymbol(a)
#define ARGMEMBER_t_symtype(a) GetSymbol(a)
#define ARGCAST(arg,tp) ARGMEMBER_##tp(arg)
thomas's avatar
thomas committed
408

thomas's avatar
thomas committed
409

thomas's avatar
thomas committed
410
411
#define REAL_NEW(NAME,NEW_CLASS,DSP,LIB) \
flext_obj *NEW_CLASS::__init__(int argc,t_atom *argv) \
thomas's avatar
thomas committed
412
413
414
415
416
{     	    	    	    	    	    	    	    	\
    return new NEW_CLASS;                     \
}   	    	    	    	    	    	    	    	\
FLEXT_EXP(LIB) void FLEXT_STPF(NEW_CLASS,DSP)()   \
{   	    	    	    	    	    	    	    	\
thomas's avatar
thomas committed
417
    flext_obj::obj_add(LIB,DSP,FLEXT_ATTRIBUTES,#NEW_CLASS,NAME,NEW_CLASS::__setup__,NEW_CLASS::__init__,&NEW_CLASS::__free__,A_NULL); \
thomas's avatar
thomas committed
418
419
} \
FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB)
thomas's avatar
thomas committed
420

thomas's avatar
thomas committed
421
422
#define REAL_NEW_V(NAME,NEW_CLASS,DSP,LIB) \
flext_obj *NEW_CLASS::__init__(int argc,t_atom *argv) \
thomas's avatar
thomas committed
423
424
425
426
427
{     	    	    	    	    	    	    	    	\
    return new NEW_CLASS(argc,argv);                     \
}   	    	    	    	    	    	    	    	\
FLEXT_EXP(LIB) void FLEXT_STPF(NEW_CLASS,DSP)()   \
{   	    	    	    	    	    	    	    	\
thomas's avatar
thomas committed
428
    flext_obj::obj_add(LIB,DSP,FLEXT_ATTRIBUTES,#NEW_CLASS,NAME,NEW_CLASS::__setup__,NEW_CLASS::__init__,&NEW_CLASS::__free__,A_GIMME,A_NULL); \
thomas's avatar
thomas committed
429
430
} \
FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB)
thomas's avatar
thomas committed
431

thomas's avatar
thomas committed
432
433
#define REAL_NEW_1(NAME,NEW_CLASS,DSP,LIB, TYPE1) \
flext_obj *NEW_CLASS::__init__(int argc,t_atom *argv) \
thomas's avatar
thomas committed
434
{     	    	    	    	    	    	    	    	\
thomas's avatar
thomas committed
435
    return new NEW_CLASS(ARGCAST(argv[0],TYPE1));                     \
thomas's avatar
thomas committed
436
437
438
}   	    	    	    	    	    	    	    	\
FLEXT_EXP(LIB) void FLEXT_STPF(NEW_CLASS,DSP)()   \
{   	    	    	    	    	    	    	    	\
thomas's avatar
thomas committed
439
    flext_obj::obj_add(LIB,DSP,FLEXT_ATTRIBUTES,#NEW_CLASS,NAME,NEW_CLASS::__setup__,NEW_CLASS::__init__,NEW_CLASS::__free__,FLEXTTP(TYPE1),A_NULL); \
thomas's avatar
thomas committed
440
441
} \
FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB)
thomas's avatar
thomas committed
442

thomas's avatar
thomas committed
443
444
#define REAL_NEW_2(NAME,NEW_CLASS,DSP,LIB, TYPE1,TYPE2) \
flext_obj *NEW_CLASS::__init__(int argc,t_atom *argv) \
thomas's avatar
thomas committed
445
{     	    	    	    	    	    	    	    	\
thomas's avatar
thomas committed
446
    return new NEW_CLASS(ARGCAST(argv[0],TYPE1),ARGCAST(argv[1],TYPE2));                     \
thomas's avatar
thomas committed
447
448
449
}   	    	    	    	    	    	    	    	\
FLEXT_EXP(LIB) void FLEXT_STPF(NEW_CLASS,DSP)()   \
{   	    	    	    	    	    	    	    	\
thomas's avatar
thomas committed
450
    flext_obj::obj_add(LIB,DSP,FLEXT_ATTRIBUTES,#NEW_CLASS,NAME,NEW_CLASS::__setup__,NEW_CLASS::__init__,NEW_CLASS::__free__,FLEXTTP(TYPE1),FLEXTTP(TYPE2),A_NULL); \
thomas's avatar
thomas committed
451
452
} \
FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB)
thomas's avatar
thomas committed
453

thomas's avatar
thomas committed
454
455
#define REAL_NEW_3(NAME,NEW_CLASS,DSP,LIB, TYPE1, TYPE2, TYPE3) \
flext_obj *NEW_CLASS::__init__(int argc,t_atom *argv) \
thomas's avatar
thomas committed
456
{     	    	    	    	    	    	    	    	\
thomas's avatar
thomas committed
457
    return new NEW_CLASS(ARGCAST(argv[0],TYPE1),ARGCAST(argv[1],TYPE2),ARGCAST(argv[2],TYPE3));                     \
thomas's avatar
thomas committed
458
459
460
}   	    	    	    	    	    	    	    	\
FLEXT_EXP(LIB) void FLEXT_STPF(NEW_CLASS,DSP)()   \
{   	    	    	    	    	    	    	    	\
thomas's avatar
thomas committed
461
    flext_obj::obj_add(LIB,DSP,FLEXT_ATTRIBUTES,#NEW_CLASS,NAME,NEW_CLASS::__setup__,NEW_CLASS::__init__,NEW_CLASS::__free__,FLEXTTP(TYPE1),FLEXTTP(TYPE2),FLEXTTP(TYPE3),A_NULL); \
thomas's avatar
thomas committed
462
463
} \
FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB)
thomas's avatar
thomas committed
464

thomas's avatar
thomas committed
465
466
#define REAL_NEW_4(NAME,NEW_CLASS,DSP,LIB, TYPE1,TYPE2, TYPE3, TYPE4) \
flext_obj *NEW_CLASS::__init__(int argc,t_atom *argv) \
thomas's avatar
thomas committed
467
{     	    	    	    	    	    	    	    	\
thomas's avatar
thomas committed
468
    return new NEW_CLASS(ARGCAST(argv[0],TYPE1),ARGCAST(argv[1],TYPE2),ARGCAST(argv[2],TYPE3),ARGCAST(argv[3],TYPE4));                     \
thomas's avatar
thomas committed
469
470
471
}   	    	    	    	    	    	    	    	\
FLEXT_EXP(LIB) void FLEXT_STPF(NEW_CLASS,DSP)()   \
{   	    	    	    	    	    	    	    	\
thomas's avatar
thomas committed
472
    flext_obj::obj_add(LIB,DSP,FLEXT_ATTRIBUTES,#NEW_CLASS,NAME,NEW_CLASS::__setup__,NEW_CLASS::__init__,NEW_CLASS::__free__,FLEXTTP(TYPE1),FLEXTTP(TYPE2),FLEXTTP(TYPE3),FLEXTTP(TYPE4),A_NULL); \
thomas's avatar
thomas committed
473
474
} \
FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB)
thomas's avatar
thomas committed
475

thomas's avatar
thomas committed
476
477
478
479
480
481
482

// Shortcuts for method arguments:
#define FLEXTARG_float a_float
#define FLEXTARG_int a_int
#define FLEXTARG_bool a_int
#define FLEXTARG_t_float a_float
#define FLEXTARG_t_symtype a_symbol
thomas's avatar
thomas committed
483
#define FLEXTARG_t_symptr a_symbol
thomas's avatar
thomas committed
484
485
486
487
488
#define FLEXTARG_t_ptrtype a_pointer

#define FLEXTARG(TP) FLEXTARG_ ## TP


thomas's avatar
thomas committed
489
#endif
thomas's avatar
thomas committed
490
491


thomas's avatar
thomas committed
492
493