summaryrefslogtreecommitdiffhomepage
path: root/src/vcall.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/vcall.h')
-rw-r--r--src/vcall.h36
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