From d62e56f4df9594f72ce501f5e19c974fd18e7295 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Tue, 22 Oct 2002 23:07:10 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r186, which included commits to RCS files with non-trunk default branches. svn path=/trunk/; revision=187 --- externals/grill/flext/source/flbase.h | 426 ++++++++++++++++++++++++++++++++++ 1 file changed, 426 insertions(+) create mode 100644 externals/grill/flext/source/flbase.h (limited to 'externals/grill/flext/source/flbase.h') diff --git a/externals/grill/flext/source/flbase.h b/externals/grill/flext/source/flbase.h new file mode 100644 index 00000000..f3f8b647 --- /dev/null +++ b/externals/grill/flext/source/flbase.h @@ -0,0 +1,426 @@ +/* + +flext - C++ layer for Max/MSP and pd (pure data) externals + +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. + +*/ + +/*! \file flbase.h + \brief Internal flext base classes + + \remark This is all derived from GEM by Mark Danks +*/ + +#ifndef __FLEXT_BASE_H +#define __FLEXT_BASE_H + +#include "flstdc.h" +#include "flsupport.h" + +#ifdef FLEXT_THREADS +#include +#endif + +class flext_obj; + +// ---------------------------------------------------------------------------- +/*! \struct flext_hdr + \brief The obligatory PD or Max/MSP object header + \internal + + 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 + the virtual table of the C++ class. +*/ +// ---------------------------------------------------------------------------- + +struct FLEXT_EXT flext_hdr +{ + /*! \brief The obligatory object header + MUST reside at memory offset 0 (no virtual table possible) + */ + t_sigobj obj; + +#ifdef PD + //! PD only: float signal holder for pd + float defsig; +#endif + +#if defined(MAXMSP) + //! MaxMSP only: current inlet used by proxy objects + long curinlet; +#endif + + /*! \brief This points to flext object class + This points to the actual polymorphic C++ class + */ + flext_obj *data; +}; + + +// ---------------------------------------------------------------------------- +/*! \class flext_obj + \brief The mother of base classes for all flext externs + \internal + + Each extern which is written in C++ needs to use the #defines at the + end of this header file. + + The define + + FLEXT_HEADER(NEW_CLASS, PARENT_CLASS) + + should be somewhere in your header file. + One of the defines like + + FLEXT_NEW(NEW_CLASS) + FLEXT_NEW_2(NEW_CLASS, float, float) + + 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. +*/ +// ---------------------------------------------------------------------------- + +class FLEXT_EXT flext_obj: + public flext +{ + public: + + // --- overloading of new/delete memory allocation methods ---- + // MaxMSP allows only 16K in overdrive mode! + + void *operator new(size_t bytes); + 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 + + // these are aligned + static void *NewAligned(size_t bytes,int bitalign = 128); + static void FreeAligned(void *blk); + + // --------------------- + + //! Constructor + flext_obj(); + + //! Destructor + virtual ~flext_obj() = 0; + + //! Get the object's canvas + t_canvas *thisCanvas() { return(m_canvas); } + + t_sigobj *thisHdr() { return &x_obj->obj; } + const t_sigobj *thisHdr() const { return &x_obj->obj; } + const char *thisName() const { return GetString(m_name); } + const t_symbol *thisNameSym() const { return m_name; } + +#ifdef PD + t_class *thisClass() { return (t_class *)((t_object *)(x_obj))->te_g.g_pd; } +#elif defined(MAXMSP) + t_class *thisClass() { return (t_class *)(((t_tinyobject *)x_obj)->t_messlist-1); } +#endif + + void InitProblem() { init_ok = false; } + + static void ProcessAttributes(bool attr) { process_attributes = attr; } + + // this also guarantees that there are no instances of flext_obj + virtual bool Init() = 0; + virtual void Exit() {} + +// --- help ------------------------------------------------------- + + /*! \defgroup FLEXT_C_HELP Flext help/assistance functionality + + @{ + */ + + static void DefineHelp(t_class *c,const char *ref,const char *dir = NULL,bool addtilde = false); + void DefineHelp(const char *ref,const char *dir = NULL,bool addtilde = false) { DefineHelp(thisClass(),ref,dir,addtilde); } + + //! @} + + + protected: + + //! The object header + flext_hdr *x_obj; + + //! Flag for attribute procession + bool procattr; + + static bool process_attributes; + + private: + + //! The canvas (patcher) that the object is in + t_canvas *m_canvas; + + //! Flag for successful object construction + bool init_ok; + + public: + + //! Creation callback + static void __setup__(t_class *) { flext::Setup(); } + + /*! \brief This is a temporary holder + \warning don't touch it! + */ + static flext_hdr *m_holder; + //! Hold object's name during construction + static const t_symbol *m_holdname; + + static bool m_holdattr; + + //! The object's name in the patcher + const t_symbol *m_name; + + //! Check whether construction was successful + bool InitOk() const { return init_ok; } + + //@{ + //! Definitions for library objects + + static void lib_init(const char *name,void setupfun(),bool attr); + 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,...); + static flext_hdr *obj_new(const t_symbol *s,int argc,t_atom *argv); + static void obj_free(flext_hdr *o); + //@} +}; + + +// max. 4 creation args (see the following macros) +#define FLEXT_MAXNEWARGS 4 + +// max. 5 method args (see the following macros) +#define FLEXT_MAXMETHARGS 5 + +// 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 + + +#ifndef FLEXT_ATTRIBUTES +#define FLEXT_ATTRIBUTES 0 +#endif + +// ---------------------------------------- +// These should be used in the header +// ---------------------------------------- + + +#define FLEXT_REALHDR(NEW_CLASS, PARENT_CLASS) \ +public: \ +typedef NEW_CLASS thisType; \ +static flext_obj *__init__(int argc,t_atom *argv); \ +static void __free__(flext_hdr *hdr) \ +{ flext_obj *mydata = hdr->data; delete mydata; \ + hdr->flext_hdr::~flext_hdr(); } \ +static void __setup__(t_class *classPtr) { \ + PARENT_CLASS::__setup__(classPtr); } \ +protected: \ +static inline NEW_CLASS *thisObject(void *c) { return FLEXT_CAST(((flext_hdr *)c)->data); } + + +#define FLEXT_REALHDR_S(NEW_CLASS, PARENT_CLASS,SETUPFUN) \ +public: \ +typedef NEW_CLASS thisType; \ +static flext_obj *__init__(int argc,t_atom *argv); \ +static void __free__(flext_hdr *hdr) \ +{ flext_obj *mydata = hdr->data; delete mydata; \ + hdr->flext_hdr::~flext_hdr(); } \ +static void __setup__(t_class *classPtr) \ +{ PARENT_CLASS::__setup__(classPtr); \ + NEW_CLASS::SETUPFUN(classPtr); } \ +protected: \ +static inline NEW_CLASS *thisObject(void *c) { return FLEXT_CAST(((flext_hdr *)c)->data); } + + +// generate name of dsp/non-dsp setup function +#define FLEXT_STPF_0(NAME) NAME##_setup +#define FLEXT_STPF_1(NAME) NAME##_tilde_setup +#define FLEXT_STPF_(DSP) FLEXT_STPF_##DSP +#define FLEXT_STPF(NAME,DSP) FLEXT_STPF_(DSP)(NAME) + + + +// -------------------------------------------------------------------------------------- + + + +// these can be used in library setup functions +// to register the individual objects in the library + +#define FLEXT_SETUP(cl) \ +extern void cl##_setup(); \ +cl##_setup() + +#define FLEXT_DSP_SETUP(cl) \ +extern void cl##_tilde_setup(); \ +cl##_tilde_setup() + +// deprecated +#define FLEXT_TILDE_SETUP FLEXT_DSP_SETUP + + +// specify that to define the library itself + +#ifdef PD +#define FLEXT_LIB_SETUP(NAME,SETUPFUN) extern "C" FLEXT_EXT void NAME##_setup() { flext_obj::lib_init(#NAME,SETUPFUN,FLEXT_ATTRIBUTES); } +#else // MAXMSP +#define FLEXT_LIB_SETUP(NAME,SETUPFUN) extern "C" FLEXT_EXT int main() { flext_obj::lib_init(#NAME,SETUPFUN,FLEXT_ATTRIBUTES); return 0; } +#endif + + +// -------------------------------------------------- + + +#define FLEXT_EXP_0 extern "C" FLEXT_EXT +#define FLEXT_EXP_1 +#define FLEXT_EXP(LIB) FLEXT_EXP_##LIB + +#ifdef PD +#define FLEXT_OBJ_SETUP_0(NEW_CLASS,DSP) +#else // MAXMSP +#define FLEXT_OBJ_SETUP_0(NEW_CLASS,DSP) extern "C" FLEXT_EXT int main() { FLEXT_STPF(NEW_CLASS,DSP)(); return 0; } +#endif +#define FLEXT_OBJ_SETUP_1(NEW_CLASS,DSP) + +#define FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB) FLEXT_OBJ_SETUP_##LIB(NEW_CLASS,DSP) + + + +// ---------------------------------------- +// These definitions are used below +// ---------------------------------------- + +// Shortcuts for PD/Max type arguments +#define FLEXTTYPE_void A_NULL +#define CALLBTYPE_void void +#define FLEXTTYPE_float A_FLOAT +#define CALLBTYPE_float float +#define FLEXTTYPE_t_float A_FLOAT +#define CALLBTYPE_t_float t_float + +//* #define FLEXTTYPE_t_flint A_FLINT + +#ifdef PD +#define FLEXTTYPE_int A_FLOAT +#define CALLBTYPE_int float +#else +#define FLEXTTYPE_int A_INT +#define CALLBTYPE_int int +#endif + +#define FLEXTTYPE_t_symptr A_SYMBOL +#define CALLBTYPE_t_symptr t_symptr +#define FLEXTTYPE_t_symtype A_SYMBOL +#define CALLBTYPE_t_symtype t_symptr +#define FLEXTTYPE_t_ptrtype A_POINTER +#define CALLBTYPE_t_ptrtype t_ptrtype + +#define FLEXTTP(TP) FLEXTTYPE_ ## TP +#define CALLBTP(TP) CALLBTYPE_ ## TP + + +#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) + + +#define REAL_NEW(NAME,NEW_CLASS,DSP,LIB) \ +FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB) \ +flext_obj *NEW_CLASS::__init__(int argc,t_atom *argv) \ +{ \ + return new NEW_CLASS; \ +} \ +FLEXT_EXP(LIB) void FLEXT_STPF(NEW_CLASS,DSP)() \ +{ \ + flext_obj::obj_add(LIB,DSP,FLEXT_ATTRIBUTES,#NEW_CLASS,NAME,NEW_CLASS::__setup__,NEW_CLASS::__init__,&NEW_CLASS::__free__,A_NULL); \ +} + +#define REAL_NEW_V(NAME,NEW_CLASS,DSP,LIB) \ +FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB) \ +flext_obj *NEW_CLASS::__init__(int argc,t_atom *argv) \ +{ \ + return new NEW_CLASS(argc,argv); \ +} \ +FLEXT_EXP(LIB) void FLEXT_STPF(NEW_CLASS,DSP)() \ +{ \ + flext_obj::obj_add(LIB,DSP,FLEXT_ATTRIBUTES,#NEW_CLASS,NAME,NEW_CLASS::__setup__,NEW_CLASS::__init__,&NEW_CLASS::__free__,A_GIMME,A_NULL); \ +} + +#define REAL_NEW_1(NAME,NEW_CLASS,DSP,LIB, TYPE1) \ +FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB) \ +flext_obj *NEW_CLASS::__init__(int argc,t_atom *argv) \ +{ \ + return new NEW_CLASS(ARGCAST(argv[0],TYPE1)); \ +} \ +FLEXT_EXP(LIB) void FLEXT_STPF(NEW_CLASS,DSP)() \ +{ \ + flext_obj::obj_add(LIB,DSP,FLEXT_ATTRIBUTES,#NEW_CLASS,NAME,NEW_CLASS::__setup__,NEW_CLASS::__init__,NEW_CLASS::__free__,FLEXTTP(TYPE1),A_NULL); \ +} + +#define REAL_NEW_2(NAME,NEW_CLASS,DSP,LIB, TYPE1,TYPE2) \ +FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB) \ +flext_obj *NEW_CLASS::__init__(int argc,t_atom *argv) \ +{ \ + return new NEW_CLASS(ARGCAST(argv[0],TYPE1),ARGCAST(argv[1],TYPE2)); \ +} \ +FLEXT_EXP(LIB) void FLEXT_STPF(NEW_CLASS,DSP)() \ +{ \ + 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); \ +} + +#define REAL_NEW_3(NAME,NEW_CLASS,DSP,LIB, TYPE1, TYPE2, TYPE3) \ +FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB) \ +flext_obj *NEW_CLASS::__init__(int argc,t_atom *argv) \ +{ \ + return new NEW_CLASS(ARGCAST(argv[0],TYPE1),ARGCAST(argv[1],TYPE2),ARGCAST(argv[2],TYPE3)); \ +} \ +FLEXT_EXP(LIB) void FLEXT_STPF(NEW_CLASS,DSP)() \ +{ \ + 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); \ +} + +#define REAL_NEW_4(NAME,NEW_CLASS,DSP,LIB, TYPE1,TYPE2, TYPE3, TYPE4) \ +FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB) \ +flext_obj *NEW_CLASS::__init__(int argc,t_atom *argv) \ +{ \ + return new NEW_CLASS(ARGCAST(argv[0],TYPE1),ARGCAST(argv[1],TYPE2),ARGCAST(argv[2],TYPE3),ARGCAST(argv[3],TYPE4)); \ +} \ +FLEXT_EXP(LIB) void FLEXT_STPF(NEW_CLASS,DSP)() \ +{ \ + 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); \ +} + + +// 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 +#define FLEXTARG_t_symptr a_symbol +#define FLEXTARG_t_ptrtype a_pointer + +#define FLEXTARG(TP) FLEXTARG_ ## TP + + +#endif + + + + -- cgit v1.2.1