From f3c9bc114cb1d136fce4e790d6d2721430eb30dc Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 11 Jan 2018 06:32:45 -0800 Subject: Move the polymorphic/inheritance macros to a separate header --- Alc/polymorphism.h | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 Alc/polymorphism.h (limited to 'Alc/polymorphism.h') diff --git a/Alc/polymorphism.h b/Alc/polymorphism.h new file mode 100644 index 00000000..b41ad64b --- /dev/null +++ b/Alc/polymorphism.h @@ -0,0 +1,108 @@ +#ifndef POLYMORPHISM_H +#define POLYMORPHISM_H + +/* Macros to declare inheriting types, and to (down-)cast and up-cast. */ +#define DERIVE_FROM_TYPE(t) t t##_parent +#define STATIC_CAST(to, obj) (&(obj)->to##_parent) +#ifdef __GNUC__ +#define STATIC_UPCAST(to, from, obj) __extension__({ \ + static_assert(__builtin_types_compatible_p(from, __typeof(*(obj))), \ + "Invalid upcast object from type"); \ + (to*)((char*)(obj) - offsetof(to, from##_parent)); \ +}) +#else +#define STATIC_UPCAST(to, from, obj) ((to*)((char*)(obj) - offsetof(to, from##_parent))) +#endif + +/* Defines method forwards, which call the given parent's (T2's) implementation. */ +#define DECLARE_FORWARD(T1, T2, rettype, func) \ +rettype T1##_##func(T1 *obj) \ +{ return T2##_##func(STATIC_CAST(T2, obj)); } + +#define DECLARE_FORWARD1(T1, T2, rettype, func, argtype1) \ +rettype T1##_##func(T1 *obj, argtype1 a) \ +{ return T2##_##func(STATIC_CAST(T2, obj), a); } + +#define DECLARE_FORWARD2(T1, T2, rettype, func, argtype1, argtype2) \ +rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b) \ +{ return T2##_##func(STATIC_CAST(T2, obj), a, b); } + +#define DECLARE_FORWARD3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \ +rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b, argtype3 c) \ +{ return T2##_##func(STATIC_CAST(T2, obj), a, b, c); } + +/* Defines method thunks, functions that call to the child's method. */ +#define DECLARE_THUNK(T1, T2, rettype, func) \ +static rettype T1##_##T2##_##func(T2 *obj) \ +{ return T1##_##func(STATIC_UPCAST(T1, T2, obj)); } + +#define DECLARE_THUNK1(T1, T2, rettype, func, argtype1) \ +static rettype T1##_##T2##_##func(T2 *obj, argtype1 a) \ +{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a); } + +#define DECLARE_THUNK2(T1, T2, rettype, func, argtype1, argtype2) \ +static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b) \ +{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b); } + +#define DECLARE_THUNK3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \ +static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c) \ +{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c); } + +#define DECLARE_THUNK4(T1, T2, rettype, func, argtype1, argtype2, argtype3, argtype4) \ +static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c, argtype4 d) \ +{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c, d); } + +/* Defines the default functions used to (de)allocate a polymorphic object. */ +#define DECLARE_DEFAULT_ALLOCATORS(T) \ +static void* T##_New(size_t size) { return al_malloc(16, size); } \ +static void T##_Delete(void *ptr) { al_free(ptr); } + + +/* Helper to extract an argument list for virtual method calls. */ +#define EXTRACT_VCALL_ARGS(...) __VA_ARGS__)) + +/* Call a "virtual" method on an object, with arguments. */ +#define V(obj, func) ((obj)->vtbl->func((obj), EXTRACT_VCALL_ARGS +/* Call a "virtual" method on an object, with no arguments. */ +#define V0(obj, func) ((obj)->vtbl->func((obj) EXTRACT_VCALL_ARGS + + +/* Helper to extract an argument list for NEW_OBJ calls. */ +#define EXTRACT_NEW_ARGS(...) __VA_ARGS__); \ + } \ +} while(0) + +/* Allocate and construct an object, with arguments. */ +#define NEW_OBJ(_res, T) do { \ + _res = T##_New(sizeof(T)); \ + if(_res) \ + { \ + memset(_res, 0, sizeof(T)); \ + T##_Construct(_res, EXTRACT_NEW_ARGS +/* Allocate and construct an object, with no arguments. */ +#define NEW_OBJ0(_res, T) do { \ + _res = T##_New(sizeof(T)); \ + if(_res) \ + { \ + memset(_res, 0, sizeof(T)); \ + T##_Construct(_res EXTRACT_NEW_ARGS + +/* Destructs and deallocate an object. */ +#define DELETE_OBJ(obj) do { \ + if((obj) != NULL) \ + { \ + V0((obj),Destruct)(); \ + V0((obj),Delete)(); \ + } \ +} while(0) + + +/* Helper to get a type's vtable thunk for a child type. */ +#define GET_VTABLE2(T1, T2) (&(T1##_##T2##_vtable)) +/* Helper to set an object's vtable thunk for a child type. Used when constructing an object. */ +#define SET_VTABLE2(T1, T2, obj) (STATIC_CAST(T2, obj)->vtbl = GET_VTABLE2(T1, T2)) + +/* Helper to set an object's vtable for a type. */ +#define SET_VTABLE1(T1, obj) ((obj)->vtbl = &(T1##_vtable)) + +#endif /* POLYMORPHISM_H */ -- cgit v1.2.3 From 2d2ca1d79110e0100e7a1f3b1c37efc527e37a3b Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 11 Jan 2018 09:39:52 -0800 Subject: Remove SET_VTABLE1 --- Alc/polymorphism.h | 3 --- OpenAL32/alEffect.c | 22 +++++++++++----------- 2 files changed, 11 insertions(+), 14 deletions(-) (limited to 'Alc/polymorphism.h') diff --git a/Alc/polymorphism.h b/Alc/polymorphism.h index b41ad64b..fa31fad2 100644 --- a/Alc/polymorphism.h +++ b/Alc/polymorphism.h @@ -102,7 +102,4 @@ static void T##_Delete(void *ptr) { al_free(ptr); } /* Helper to set an object's vtable thunk for a child type. Used when constructing an object. */ #define SET_VTABLE2(T1, T2, obj) (STATIC_CAST(T2, obj)->vtbl = GET_VTABLE2(T1, T2)) -/* Helper to set an object's vtable for a type. */ -#define SET_VTABLE1(T1, obj) ((obj)->vtbl = &(T1##_vtable)) - #endif /* POLYMORPHISM_H */ diff --git a/OpenAL32/alEffect.c b/OpenAL32/alEffect.c index 48268247..bb56e6a3 100644 --- a/OpenAL32/alEffect.c +++ b/OpenAL32/alEffect.c @@ -432,7 +432,7 @@ static void InitEffectParams(ALeffect *effect, ALenum type) effect->Props.Reverb.LFReference = AL_EAXREVERB_DEFAULT_LFREFERENCE; effect->Props.Reverb.RoomRolloffFactor = AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR; effect->Props.Reverb.DecayHFLimit = AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT; - SET_VTABLE1(ALeaxreverb, effect); + effect->vtbl = &ALeaxreverb_vtable; break; case AL_EFFECT_REVERB: effect->Props.Reverb.Density = AL_REVERB_DEFAULT_DENSITY; @@ -462,7 +462,7 @@ static void InitEffectParams(ALeffect *effect, ALenum type) effect->Props.Reverb.LFReference = 250.0f; effect->Props.Reverb.RoomRolloffFactor = AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR; effect->Props.Reverb.DecayHFLimit = AL_REVERB_DEFAULT_DECAY_HFLIMIT; - SET_VTABLE1(ALreverb, effect); + effect->vtbl = &ALreverb_vtable; break; case AL_EFFECT_CHORUS: effect->Props.Chorus.Waveform = AL_CHORUS_DEFAULT_WAVEFORM; @@ -471,11 +471,11 @@ static void InitEffectParams(ALeffect *effect, ALenum type) effect->Props.Chorus.Depth = AL_CHORUS_DEFAULT_DEPTH; effect->Props.Chorus.Feedback = AL_CHORUS_DEFAULT_FEEDBACK; effect->Props.Chorus.Delay = AL_CHORUS_DEFAULT_DELAY; - SET_VTABLE1(ALchorus, effect); + effect->vtbl = &ALchorus_vtable; break; case AL_EFFECT_COMPRESSOR: effect->Props.Compressor.OnOff = AL_COMPRESSOR_DEFAULT_ONOFF; - SET_VTABLE1(ALcompressor, effect); + effect->vtbl = &ALcompressor_vtable; break; case AL_EFFECT_DISTORTION: effect->Props.Distortion.Edge = AL_DISTORTION_DEFAULT_EDGE; @@ -483,7 +483,7 @@ static void InitEffectParams(ALeffect *effect, ALenum type) effect->Props.Distortion.LowpassCutoff = AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF; effect->Props.Distortion.EQCenter = AL_DISTORTION_DEFAULT_EQCENTER; effect->Props.Distortion.EQBandwidth = AL_DISTORTION_DEFAULT_EQBANDWIDTH; - SET_VTABLE1(ALdistortion, effect); + effect->vtbl = &ALdistortion_vtable; break; case AL_EFFECT_ECHO: effect->Props.Echo.Delay = AL_ECHO_DEFAULT_DELAY; @@ -491,7 +491,7 @@ static void InitEffectParams(ALeffect *effect, ALenum type) effect->Props.Echo.Damping = AL_ECHO_DEFAULT_DAMPING; effect->Props.Echo.Feedback = AL_ECHO_DEFAULT_FEEDBACK; effect->Props.Echo.Spread = AL_ECHO_DEFAULT_SPREAD; - SET_VTABLE1(ALecho, effect); + effect->vtbl = &ALecho_vtable; break; case AL_EFFECT_EQUALIZER: effect->Props.Equalizer.LowCutoff = AL_EQUALIZER_DEFAULT_LOW_CUTOFF; @@ -504,7 +504,7 @@ static void InitEffectParams(ALeffect *effect, ALenum type) effect->Props.Equalizer.Mid2Width = AL_EQUALIZER_DEFAULT_MID2_WIDTH; effect->Props.Equalizer.HighCutoff = AL_EQUALIZER_DEFAULT_HIGH_CUTOFF; effect->Props.Equalizer.HighGain = AL_EQUALIZER_DEFAULT_HIGH_GAIN; - SET_VTABLE1(ALequalizer, effect); + effect->vtbl = &ALequalizer_vtable; break; case AL_EFFECT_FLANGER: effect->Props.Chorus.Waveform = AL_FLANGER_DEFAULT_WAVEFORM; @@ -513,21 +513,21 @@ static void InitEffectParams(ALeffect *effect, ALenum type) effect->Props.Chorus.Depth = AL_FLANGER_DEFAULT_DEPTH; effect->Props.Chorus.Feedback = AL_FLANGER_DEFAULT_FEEDBACK; effect->Props.Chorus.Delay = AL_FLANGER_DEFAULT_DELAY; - SET_VTABLE1(ALflanger, effect); + effect->vtbl = &ALflanger_vtable; break; case AL_EFFECT_RING_MODULATOR: effect->Props.Modulator.Frequency = AL_RING_MODULATOR_DEFAULT_FREQUENCY; effect->Props.Modulator.HighPassCutoff = AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF; effect->Props.Modulator.Waveform = AL_RING_MODULATOR_DEFAULT_WAVEFORM; - SET_VTABLE1(ALmodulator, effect); + effect->vtbl = &ALmodulator_vtable; break; case AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT: case AL_EFFECT_DEDICATED_DIALOGUE: effect->Props.Dedicated.Gain = 1.0f; - SET_VTABLE1(ALdedicated, effect); + effect->vtbl = &ALdedicated_vtable; break; default: - SET_VTABLE1(ALnull, effect); + effect->vtbl = &ALnull_vtable; break; } effect->type = type; -- cgit v1.2.3