aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/flext/source/flbase.h
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2002-10-22 23:07:10 +0000
committerThomas Grill <xovo@users.sourceforge.net>2002-10-22 23:07:10 +0000
commitd62e56f4df9594f72ce501f5e19c974fd18e7295 (patch)
tree635d4af7a7c2425098e60ca277086ec436b617f7 /externals/grill/flext/source/flbase.h
parentc6f373c281ecb5cd1f4aa7a070e15cc61ab8793c (diff)
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
Diffstat (limited to 'externals/grill/flext/source/flbase.h')
-rw-r--r--externals/grill/flext/source/flbase.h426
1 files changed, 426 insertions, 0 deletions
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 <pthread.h>
+#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<NEW_CLASS *>(((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<NEW_CLASS *>(((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
+
+
+
+