diff options
Diffstat (limited to 'src/vcall.h')
-rw-r--r-- | src/vcall.h | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/src/vcall.h b/src/vcall.h index 654cafb..caee70a 100644 --- a/src/vcall.h +++ b/src/vcall.h @@ -1,5 +1,5 @@ /* - * Copyright © 2021 Michael Smith <mikesmiffy128@gmail.com> + * Copyright © 2022 Michael Smith <mikesmiffy128@gmail.com> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -17,6 +17,8 @@ #ifndef INC_VCALL_H #define INC_VCALL_H +#include "gamedata.h" + /* * Convenient facilities for calling simple (single-table) virtual functions on * possibly-opaque pointers to C++ objects. @@ -33,24 +35,32 @@ #define VCALLCONV #endif -#define DECL_VFUNC0(ret, name, idx) \ - enum { _VTIDX_##name = (idx) }; \ - typedef ret (*VCALLCONV _VFUNC_##name)(void *this); +#define _DECL_VFUNC_DYN(ret, conv, name, ...) \ + /* XXX: GCC extension, seems worthwhile vs having two macros for one thing. + Replace with __VA_OPT__(,) whenever that gets fully standardised. */ \ + typedef ret (*conv name##_func)(void *this, ##__VA_ARGS__); +#define _DECL_VFUNC(ret, conv, name, idx, ...) \ + enum { vtidx_##name = (idx) }; \ + _DECL_VFUNC_DYN(ret, conv, name, ##__VA_ARGS__) +/* Define a virtual function with a known index */ #define DECL_VFUNC(ret, name, idx, ...) \ - enum { _VTIDX_##name = (idx) }; \ - typedef ret (*VCALLCONV _VFUNC_##name)(void *this, __VA_ARGS__); + _DECL_VFUNC(ret, VCALLCONV, name, idx, ##__VA_ARGS__) -// not bothering to provide a zero-argument version because the main use of -// this is vararg functions, which error if __thiscall +/* Define a virtual function with a known index, without thiscall convention */ #define DECL_VFUNC_CDECL(ret, name, idx, ...) \ - enum { _VTIDX_##name = (idx) }; \ - typedef ret (*_VFUNC_##name)(void *this, __VA_ARGS__); + _DECL_VFUNC(ret, , name, idx, ##__VA_ARGS__) + +/* Define a virtual function with an index defined elsewhere */ +#define DECL_VFUNC_DYN(ret, name, ...) \ + _DECL_VFUNC_DYN(ret, VCALLCONV, name, ##__VA_ARGS__) -#define VFUNC(x, name) ((*(_VFUNC_##name **)(x))[_VTIDX_##name]) +/* Define a virtual function with an index defined elsewhere, without thiscall */ +#define DECL_VFUNC_CDECLDYN(ret, name, ...) \ + _DECL_VFUNC_DYN(ret, , name, ##__VA_ARGS__) -#define VCALL0(x, name) (VFUNC(x, name)(x)) -#define VCALL(x, name, ...) VFUNC(x, name)(x, __VA_ARGS__) +#define VFUNC(x, name) ((*(name##_func **)(x))[vtidx_##name]) +#define VCALL(x, name, ...) VFUNC(x, name)(x, ##__VA_ARGS__) #endif |