X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffg_callback_macros.h;h=a1b8c380db96bbc1b0e602662fbde892a2a8b643;hb=b1ed93dd348f7b8f3bd2c75474f5d4151d502f1f;hp=2aa6ccd97e22767ef45a373bf573072d7506db77;hpb=071be85d52e073ab57e290d3ee9a458b34ff0b4e;p=freeglut diff --git a/src/fg_callback_macros.h b/src/fg_callback_macros.h index 2aa6ccd..a1b8c38 100644 --- a/src/fg_callback_macros.h +++ b/src/fg_callback_macros.h @@ -34,32 +34,21 @@ */ /* - * Compiler defines: - * FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK: if the compiler supports GCC's variadic macro implementation (AKA, ##__VA_ARGS__) - * FG_COMPILER_SUPPORTS_VA_ARGS: if the compiler supports variadic macros + * Compiler define: FG_COMPILER_SUPPORTS_VA_ARGS: if the compiler supports variadic macros */ /* What supports variadic macros based off Wikipedia article on it (GCC-like must support C99 or higher to use variadic macros) */ #if (((defined(__GNUC__) && (__GNUC__ >= 3)) || \ - (defined(__clang__))) && \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L))) || \ - (defined(_MSC_VER) && (_MSC_VER >= 1400)) || \ - (defined(__BORLANDC__) && (__BORLANDC__ >= 0x570)) || \ - (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x530)) + (defined(__clang__))) && \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L))) || \ + (defined(_MSC_VER) && (_MSC_VER >= 1400)) || \ + (defined(__BORLANDC__) && (__BORLANDC__ >= 0x570)) || \ + (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x530)) #define FG_COMPILER_SUPPORTS_VA_ARGS 1 #else #define FG_COMPILER_SUPPORTS_VA_ARGS 0 #endif -/* If __VA_ARGS__ is supported, it needs to be GCC(-like) or Clang (since Clang mimics GCC) */ -#if FG_COMPILER_SUPPORTS_VA_ARGS && \ - (defined(__GNUC__)) || \ - (defined(__clang__)) -#define FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK 1 -#else -#define FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK 0 -#endif - /* * -------------------------- * Executing window callbacks @@ -69,7 +58,7 @@ * * This took a while to figure out, so be sure try to understand what is happening so that you can ensure that whatever you * change won't break other areas. - * + * * If you are just adding a new callback/changing it's argument count, just go to the bottom of the file. * * This whole file exists purely for the sake of preventing the need to implement additional parsing logic for each callback @@ -81,92 +70,26 @@ * then the GCC macro, so maybe it's good to stay as is. * * Onto the different "versions" of macros: - * - * There is one for GCC/Clang(/and supposedly the Intel compiler) which supports the non-standard ##__VA_ARGS__ token. The code may - * look ugly, but the result is, if this was standard, no one would ever need to open this file unless they were curious (or needed - * more then 5 arguments for a callback, but that's trivial to add). It works by adding many fake macros to a "picker" macro - * (PP_HAS_ARGS_IMPL2) which then indictaes which macro counter to use. As we can already use variadic macros (the VA in __VA_ARGS__), - * this just becomes a "reuse the arguments*. - * - * The next is for any non-GCC/Clang/etc. compiler *cough* MSVC/compiler you probably shouldn't be using *cough* that supports C99 - * by default. It requires each callback to have a specific argument count passthrough macro. The only reason there are specific - * count macros is so that (see paraghraph below) don't need have their own set of callback macros. Ideally, there would only be - * ZERO and ONE_OR_MORE. This works by having callback-specific macros call a specific handler macro to return user data (ZERO) or - * return one or more arguments along with userData (ONE_OR_MORE) where, with variadic macros, it just reuses the arguments. - * - * The last set is for the poor individual who has to use a compiler that doesn't support C99 by default, or may not support it at - * all. Stuff like MSVC6... It works by having a specific-count macro that "extracts" each argument to have them reused without the - * parathesis. - * - * A note on parathesis, as earlier mentioned, if the GCC variadic macro element was standard, then instead of needing: - * - * func EXPAND_WCB(Mouse)(( (GLUT_LEFT_BUTTON, GLUT_DOWN, 10, 30), userData)); - * - * ...you can do the following: - * - * func EXPAND_WCB (GLUT_LEFT_BUTTON, GLUT_DOWN, 10, 30); - * - * Wow... so much nice and easier to understand. Sub-note: I have not worked on a version that explicitly takes userData, so for now - * if you can get to that version, look in the version control change history for this file and you'll find that version which - * implicitly passes "userData" and only works on GCC vardiac macro supporting compilers. - */ - -#if FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK - - /* - * EXPAND_WCB() is used as: - * - * EXPAND_WCB( cbname )(( arg_list, userData )) - * - * ... where {(arg_list)} is the parameter list and userData is user - * provided data. * - * All additional macros are to get around trailing ',' for zero-arg - * callbacks. + * The first is for any compiler that supports C99 by default. It requires each callback to have a specific argument count + * passthrough macro. The only reason there are specific count macros is so that (see paraghraph below) don't need have their own + * set of callback macros. Ideally, there would only be ZERO and ONE_OR_MORE. This works by having callback-specific macros call a + * specific handler macro to return user data (ZERO) or return one or more arguments along with userData (ONE_OR_MORE) where, with + * variadic macros, it just reuses the arguments. * - * Modification of: - * http://stackoverflow.com/questions/5355241/generating-function-declaration-using-a-macro-iteration/5355946#5355946 + * The last macro set is for the poor individual who has to use a compiler that doesn't support C99 by default, or may not support + * it at all. Stuff like MSVC6... It works by having a specific-count macro that "extracts" each argument to have them reused without + * the parathesis. * - * -------------- - * - * GCC-specific design that doesn't require per-callback defines - * - * The naming is terrible... and it's very convuluted and complex, but - * should not require any modification unless additional arguments are to - * be supported. - * - * Supports callbacks up to 5 args (follow the pattern of - * EXPAND_WCB_PP_HAS_ARGS_IMPL2 and EXPAND_WCB_PP_HAS_ARGS_SOURCE to add more) - * - * Edit with care. + * There is a 3rd macro set that only worked on GCC/Clang, and thus was removed (last seen in revision e9676fc of the GIT mirror. + * Not sure at this time what the SVN number is.) as it's a non-standard functionality. */ -#define EXPAND_WCB_UNPARAN(...) __VA_ARGS__ - -#define EXPAND_WCB_PP_HAS_ARGS_IMPL2(_0, _1, _2, _3, _4, _5, N, ...) N -#define EXPAND_WCB_PP_HAS_ARGS_SOURCE() ONE_OR_MORE, ONE_OR_MORE, ONE_OR_MORE, ONE_OR_MORE, ONE_OR_MORE, ZERO - -#define EXPAND_WCB_PP_HAS_ARGS_IMPL(...) EXPAND_WCB_PP_HAS_ARGS_IMPL2( __VA_ARGS__ ) -#define EXPAND_WCB_PP_HAS_ARGS(...) EXPAND_WCB_PP_HAS_ARGS_IMPL( NOT_EXIST, ##__VA_ARGS__, EXPAND_WCB_PP_HAS_ARGS_SOURCE() ) - -#define EXPAND_WCB_ZERO(args, userData) ( userData ) -#define EXPAND_WCB_ONE_OR_MORE(args, userData) ( EXPAND_WCB_UNPARAN args, userData ) - -#define EXPAND_WCB_DISAMBIGUATE2(has_args, args, userData) EXPAND_WCB_ ## has_args ( args, userData ) -#define EXPAND_WCB_DISAMBIGUATE(has_args, args, userData) EXPAND_WCB_DISAMBIGUATE2( has_args, args, userData ) - -#define EXPAND_WCB_UNWRAP_ARGS2(args, userData) EXPAND_WCB_DISAMBIGUATE( EXPAND_WCB_PP_HAS_ARGS args, args, userData ) -#define EXPAND_WCB_UNWRAP_ARGS(args) EXPAND_WCB_UNWRAP_ARGS2 args - -#define EXPAND_WCB(cbname) EXPAND_WCB_UNWRAP_ARGS - -#else - /* * EXPAND_WCB() is used as: - * + * * EXPAND_WCB( cbname )(( arg_list, userData )) - * + * * ... where {(arg_list)} is the parameter list and userData is user * provided data. * @@ -217,7 +140,7 @@ #define EXPAND_WCB(cbname) EXPAND_WCB_SUB_ ## cbname -/* +/* * Freeglut callbacks type definitions macros * * Every time a callback is updated in fg_internal.h is updated, this needs updated @@ -255,8 +178,6 @@ #define EXPAND_WCB_SUB_InitContext(args) EXPAND_WCB_ZERO args #define EXPAND_WCB_SUB_AppStatus(args) EXPAND_WCB_ONE args -#endif - /* * ------------------------ * Setting window callbacks @@ -282,39 +203,39 @@ do \ #define IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,b) \ static void fgh##a##FuncCallback( FGCBUserData userData ) \ { \ - FGCB##b callback = (FGCB##b)userData; \ - callback(); \ + FGCB##b* callback = (FGCB##b*)&userData; \ + (*callback)(); \ } #define IMPLEMENT_CALLBACK_FUNC_CB_ARG1(a,b) \ static void fgh##a##FuncCallback( int arg1val, FGCBUserData userData ) \ { \ - FGCB##b callback = (FGCB##b)userData; \ - callback( arg1val ); \ + FGCB##b* callback = (FGCB##b*)&userData; \ + (*callback)( arg1val ); \ } #define IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,b) \ static void fgh##a##FuncCallback( int arg1val, int arg2val, FGCBUserData userData ) \ { \ - FGCB##b callback = (FGCB##b)userData; \ - callback( arg1val, arg2val ); \ + FGCB##b* callback = (FGCB##b*)&userData; \ + (*callback)( arg1val, arg2val ); \ } #define IMPLEMENT_CALLBACK_FUNC_CB_ARG3_USER(a,b,arg1,arg2,arg3) \ static void fgh##a##FuncCallback( arg1 arg1val, arg2 arg2val, arg3 arg3val, FGCBUserData userData ) \ { \ - FGCB##b callback = (FGCB##b)userData; \ - callback( arg1val, arg2val, arg3val ); \ + FGCB##b* callback = (FGCB##b*)&userData; \ + (*callback)( arg1val, arg2val, arg3val ); \ } #define IMPLEMENT_CALLBACK_FUNC_CB_ARG3(a,b) IMPLEMENT_CALLBACK_FUNC_CB_ARG3_USER(a,b,int,int,int) #define IMPLEMENT_CALLBACK_FUNC_CB_ARG4(a,b) \ static void fgh##a##FuncCallback( int arg1val, int arg2val, int arg3val, int arg4val, FGCBUserData userData ) \ { \ - FGCB##b callback = (FGCB##b)userData; \ - callback( arg1val, arg2val, arg3val, arg4val ); \ + FGCB##b* callback = (FGCB##b*)&userData; \ + (*callback)( arg1val, arg2val, arg3val, arg4val ); \ } #define IMPLEMENT_CALLBACK_FUNC_CB_ARG5(a,b) \ static void fgh##a##FuncCallback( int arg1val, int arg2val, int arg3val, int arg4val, int arg5val, FGCBUserData userData ) \ { \ - FGCB##b callback = (FGCB##b)userData; \ - callback( arg1val, arg2val, arg3val, arg4val, arg5val ); \ + FGCB##b* callback = (FGCB##b*)&userData; \ + (*callback)( arg1val, arg2val, arg3val, arg4val, arg5val ); \ } /* @@ -331,14 +252,17 @@ void FGAPIENTRY glut##a##Func( FGCB##b callback ) \ { \ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glut"#a"Func" ); \ if( callback ) \ - glut##a##FuncUcall( fgh##a##FuncCallback, (FGCBUserData)callback ); \ + { \ + FGCB##b* reference = &callback; \ + glut##a##FuncUcall( fgh##a##FuncCallback, *((FGCBUserData*)reference) ); \ + } \ else \ glut##a##FuncUcall( NULL, NULL ); \ } #define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,b) \ - IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT_UCALL(a,b) \ - IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,b) + IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT_UCALL(a,b) \ + IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,b) /* * Combine _glut and _cb macros: @@ -352,20 +276,20 @@ void FGAPIENTRY glut##a##Func( FGCB##b callback ) \ IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,b) #define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG0(a) \ - IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,a) \ - IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,a) + IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,a) \ + IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,a) #define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG0_2NAME(a,b) \ - IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,b) \ - IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,b) + IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,b) \ + IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,b) #define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG1(a) \ IMPLEMENT_CALLBACK_FUNC_CB_ARG1(a,a) \ IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,a) #define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG1(a) \ - IMPLEMENT_CALLBACK_FUNC_CB_ARG1(a,a) \ - IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,a) + IMPLEMENT_CALLBACK_FUNC_CB_ARG1(a,a) \ + IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,a) #define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG2(a) \ IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,a) \ @@ -376,12 +300,12 @@ void FGAPIENTRY glut##a##Func( FGCB##b callback ) \ IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,b) #define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG2(a) \ - IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,a) \ - IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,a) + IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,a) \ + IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,a) #define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG2_2NAME(a,b) \ - IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,b) \ - IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,b) + IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,b) \ + IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,b) #define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG3(a) \ IMPLEMENT_CALLBACK_FUNC_CB_ARG3(a,a) \ @@ -392,12 +316,12 @@ void FGAPIENTRY glut##a##Func( FGCB##b callback ) \ IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,a) #define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG3(a) \ - IMPLEMENT_CALLBACK_FUNC_CB_ARG3(a,a) \ - IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,a) + IMPLEMENT_CALLBACK_FUNC_CB_ARG3(a,a) \ + IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,a) #define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG3_2NAME(a,b) \ - IMPLEMENT_CALLBACK_FUNC_CB_ARG3(a,b) \ - IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,b) + IMPLEMENT_CALLBACK_FUNC_CB_ARG3(a,b) \ + IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,b) #define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG4(a) \ IMPLEMENT_CALLBACK_FUNC_CB_ARG4(a,a) \