From 0c6f1dd8cfa338fbef1a6f49d65b9974b8cc9481 Mon Sep 17 00:00:00 2001 From: Sara Date: Fri, 12 Jan 2024 09:02:42 +0100 Subject: [PATCH] feat: reworked typeclasses to forward-declare then define forward declarations are simplified with decl_typeclass_impl impl_Typeclass_for now instead only define static inline impl_Typeclass_for can be used to achieve the old behaviour --- core/src/asset.h | 2 +- core/src/behaviour_entity.h | 9 ++++++--- core/src/drop.h | 4 ++-- core/src/input_axis.c | 36 ++++++++++++++++++++++++++++++++++++ core/src/input_axis.h | 36 +++++++++--------------------------- core/src/physics.h | 1 + core/src/physics_entity.h | 2 +- core/src/player_input.c | 4 ++++ core/src/player_input.h | 5 ++--- core/src/rigidbody.c | 4 ++++ core/src/rigidbody.h | 6 +----- core/src/spritesheet.c | 9 +++++++++ core/src/spritesheet.h | 11 +++-------- core/src/transform.c | 5 +++++ core/src/transform.h | 5 ++--- core/src/transformable.h | 2 +- core/src/typeclass_helpers.h | 3 +++ game/src/Damagable.h | 2 +- game/src/Enemy.c | 25 +++++++++++++++++++++++++ game/src/Enemy.h | 30 ++++++------------------------ game/src/Player.c | 21 +++++++++++++++++++++ game/src/Player.h | 25 +++++-------------------- game/src/Prop.c | 21 +++++++++++++++++++++ game/src/Prop.h | 25 +++++-------------------- 24 files changed, 174 insertions(+), 119 deletions(-) create mode 100644 core/src/transform.c diff --git a/core/src/asset.h b/core/src/asset.h index f5739b7..08cbc3f 100644 --- a/core/src/asset.h +++ b/core/src/asset.h @@ -19,7 +19,7 @@ typedef struct Asset { } Asset; #define impl_Asset_for(T, get_id_f, set_id_f)\ -static inline Asset T##_as_Asset(T* x) {\ +Asset T##_as_Asset(T* x) {\ TC_FN_TYPECHECK(asset_id, get_id_f, T*);\ TC_FN_TYPECHECK(void, set_id_f, T*, asset_id);\ TC_FN_TYPECHECK(Drop, T##_as_Drop, T*);\ diff --git a/core/src/behaviour_entity.h b/core/src/behaviour_entity.h index c5b8391..bd7802a 100644 --- a/core/src/behaviour_entity.h +++ b/core/src/behaviour_entity.h @@ -2,8 +2,8 @@ #define _update_entity_h #include "drop.h" +#include "mirror.h" #include "typeclass_helpers.h" -#include "vmath.h" typedef struct { void (*const update)(void* self, float dt); @@ -16,10 +16,11 @@ typedef struct { void* data; IEntityBehaviour const* tc; IDrop const* drop; + IMirror const* mirror; } BehaviourEntity; #define impl_BehaviourEntity_for(T, start_f, update_f, draw_f, get_depth_f)\ -static inline BehaviourEntity T##_as_BehaviourEntity(T* x) {\ +BehaviourEntity T##_as_BehaviourEntity(T* x) {\ TC_FN_TYPECHECK(void, start_f, T*);\ TC_FN_TYPECHECK(void, update_f, T*, float);\ TC_FN_TYPECHECK(void, draw_f, T*);\ @@ -31,8 +32,10 @@ static inline BehaviourEntity T##_as_BehaviourEntity(T* x) {\ .get_depth=(long(*const)(void*)) get_depth_f,\ };\ TC_FN_TYPECHECK(Drop, T##_as_Drop, T*);\ + TC_FN_TYPECHECK(Mirror, T##_as_Mirror, T*);\ IDrop const* drop = T##_as_Drop(x).tc;\ - return (BehaviourEntity){.tc = &tc, .drop = drop, .data = x};\ + IMirror const* mirror = T##_as_Mirror(x).tc;\ + return (BehaviourEntity){.data = x, .tc = &tc, .drop = drop, .mirror = mirror};\ }\ #endif // !_update_entity_h diff --git a/core/src/drop.h b/core/src/drop.h index 894b62d..bc237d8 100644 --- a/core/src/drop.h +++ b/core/src/drop.h @@ -13,7 +13,7 @@ typedef struct { } Drop; #define impl_Drop_for(T, drop_f)\ -static inline Drop T##_as_Drop(T* x) {\ +Drop T##_as_Drop(T* x) {\ TC_FN_TYPECHECK(void, drop_f, T*);\ static IDrop const tc = {\ .drop = (void(*const)(void*)) drop_f,\ @@ -24,7 +24,7 @@ static inline Drop T##_as_Drop(T* x) {\ extern void default_drop(void*); #define impl_default_Drop_for(T)\ -static inline Drop T##_as_Drop(T* x) {\ +Drop T##_as_Drop(T* x) {\ static IDrop const tc = {\ .drop = default_drop,\ };\ diff --git a/core/src/input_axis.c b/core/src/input_axis.c index d5233de..1dbaae0 100644 --- a/core/src/input_axis.c +++ b/core/src/input_axis.c @@ -2,6 +2,42 @@ #include "debug.h" #include "input.h" + +impl_default_Drop_for( + KeyBind +) +impl_InputAxis_for(KeyBind, + keybind_is_changed_by, + keybind_evaluate, + keybind_set_device +) +impl_default_Drop_for( + ControllerAxis +) +impl_InputAxis_for(ControllerAxis, + controlleraxis_is_changed_by, + controlleraxis_evaluate, + controlleraxis_set_device +) + +impl_default_Drop_for( + ControllerButton +) +impl_InputAxis_for(ControllerButton, + controllerbutton_is_changed_by, + controllerbutton_evaluate, + controllerbutton_set_device +) + +impl_Drop_for(CompositeAxis1D, + compositeaxis1d_drop +) +impl_InputAxis_for(CompositeAxis1D, + compositeaxis1d_is_changed_by, + compositeaxis1d_evaluate, + compositeaxis1d_set_device +) + KeyBind* keybind_new(SDL_Scancode key) { KeyBind* self = malloc(sizeof(KeyBind)); ASSERT_RETURN(self != NULL, NULL, "Failed to allocate space for KeyBind instance"); diff --git a/core/src/input_axis.h b/core/src/input_axis.h index 57af6c8..fed369c 100644 --- a/core/src/input_axis.h +++ b/core/src/input_axis.h @@ -40,7 +40,7 @@ typedef struct { } InputAxis; #define impl_InputAxis_for(T, is_changed_by_f, evaluate_f, set_device_f)\ -static inline InputAxis T##_as_InputAxis(T* x) {\ +InputAxis T##_as_InputAxis(T* x) {\ TC_FN_TYPECHECK(int, is_changed_by_f, T*, SDL_Event);\ TC_FN_TYPECHECK(struct InputEvent, evaluate_f, T*, SDL_Event);\ TC_FN_TYPECHECK(void, set_device_f, T*, struct InputDevice*);\ @@ -64,12 +64,8 @@ extern int keybind_is_changed_by(KeyBind* self, SDL_Event event); extern struct InputEvent keybind_evaluate(KeyBind* self, SDL_Event); extern void keybind_set_device(KeyBind* self, struct InputDevice* device); -impl_default_Drop_for(KeyBind) -impl_InputAxis_for(KeyBind, - keybind_is_changed_by, - keybind_evaluate, - keybind_set_device -) +decl_typeclass_impl(InputAxis, KeyBind) +decl_typeclass_impl(Drop, KeyBind) typedef struct ControllerAxis { struct InputDevice* device; @@ -81,12 +77,8 @@ extern int controlleraxis_is_changed_by(ControllerAxis* self, SDL_Event event); extern struct InputEvent controlleraxis_evaluate(ControllerAxis* self, SDL_Event event); extern void controlleraxis_set_device(ControllerAxis* self, struct InputDevice* device); -impl_default_Drop_for(ControllerAxis) -impl_InputAxis_for(ControllerAxis, - controlleraxis_is_changed_by, - controlleraxis_evaluate, - controlleraxis_set_device -) +decl_typeclass_impl(InputAxis, ControllerAxis) +decl_typeclass_impl(Drop, ControllerAxis) typedef struct ControllerButton { struct InputDevice* device; @@ -98,12 +90,8 @@ extern int controllerbutton_is_changed_by(ControllerButton* self, SDL_Event even extern struct InputEvent controllerbutton_evaluate(ControllerButton* self, SDL_Event event); extern void controllerbutton_set_device(ControllerButton* self, struct InputDevice* device); -impl_default_Drop_for(ControllerButton) -impl_InputAxis_for(ControllerButton, - controllerbutton_is_changed_by, - controllerbutton_evaluate, - controllerbutton_set_device -) +decl_typeclass_impl(InputAxis, ControllerButton) +decl_typeclass_impl(Drop, ControllerButton) typedef struct CompositeAxis1D { InputAxis left; @@ -117,13 +105,7 @@ extern struct InputEvent compositeaxis1d_evaluate(CompositeAxis1D* self, SDL_Eve extern void compositeaxis1d_set_device(CompositeAxis1D* self, struct InputDevice* device); extern void compositeaxis1d_drop(CompositeAxis1D* self); -impl_Drop_for(CompositeAxis1D, - compositeaxis1d_drop -) -impl_InputAxis_for(CompositeAxis1D, - compositeaxis1d_is_changed_by, - compositeaxis1d_evaluate, - compositeaxis1d_set_device -) +decl_typeclass_impl(InputAxis, CompositeAxis1D) +decl_typeclass_impl(Drop, CompositeAxis1D) #endif // !_fencer_input_axis_h diff --git a/core/src/physics.h b/core/src/physics.h index 84178fa..dbc12fe 100644 --- a/core/src/physics.h +++ b/core/src/physics.h @@ -5,6 +5,7 @@ #include "transform.h" #include "stdint.h" #include "physics_entity.h" +#include "shape.h" typedef uint32_t PhysicsMask; diff --git a/core/src/physics_entity.h b/core/src/physics_entity.h index acfef5d..7e133c6 100644 --- a/core/src/physics_entity.h +++ b/core/src/physics_entity.h @@ -29,7 +29,7 @@ extern void physics_entity_solve_contacts(PhysicsEntity self, List* contacts); extern void physics_entity_update(PhysicsEntity self); #define impl_PhysicsEntity_for(T, get_rigidbody_f, on_collision_f, on_overlap_f)\ -static inline PhysicsEntity T##_as_PhysicsEntity(T* x) {\ +PhysicsEntity T##_as_PhysicsEntity(T* x) {\ TC_FN_TYPECHECK(RigidBody*, get_rigidbody_f, T*);\ TC_FN_TYPECHECK(void, on_collision_f, T*, Collision);\ TC_FN_TYPECHECK(void, on_overlap_f, T*, Collider*);\ diff --git a/core/src/player_input.c b/core/src/player_input.c index 55d1efc..eca8519 100644 --- a/core/src/player_input.c +++ b/core/src/player_input.c @@ -1,6 +1,10 @@ #include "player_input.h" #include "debug.h" +impl_Drop_for(PlayerInput, + playerinput_drop +) + PlayerInput* playerinput_new(void* target, int device) { PlayerInput* self = malloc(sizeof(PlayerInput)); ASSERT_RETURN(self != NULL, NULL, "Could not allocate memory for PlayerInput instance"); diff --git a/core/src/player_input.h b/core/src/player_input.h index acadf79..18bced8 100644 --- a/core/src/player_input.h +++ b/core/src/player_input.h @@ -4,6 +4,7 @@ #include "list.h" #include "input.h" #include "input_axis.h" +#include "typeclass_helpers.h" typedef struct PlayerInput { InputDevice* device; @@ -16,8 +17,6 @@ extern void playerinput_add(PlayerInput* self, InputAxis axis, InputDelegateFn d extern void playerinput_set_device(PlayerInput* self, int device); extern void playerinput_drop(PlayerInput* self); -impl_Drop_for(PlayerInput, - playerinput_drop -) +decl_typeclass_impl(Drop, PlayerInput) #endif // !_fencer_player_input_h diff --git a/core/src/rigidbody.c b/core/src/rigidbody.c index c45d14e..91d8ee3 100644 --- a/core/src/rigidbody.c +++ b/core/src/rigidbody.c @@ -26,6 +26,10 @@ struct RigidBody { List contacts; }; +impl_Transformable_for(RigidBody, + rigidbody_get_transform +) + RigidBody* rigidbody_make(PhysicsEntity owner) { RigidBody* self = malloc(sizeof(RigidBody)); ASSERT_RETURN(self != NULL, NULL, "Failed to allocate space for rigidbody"); diff --git a/core/src/rigidbody.h b/core/src/rigidbody.h index 9ba0e5a..e34b7b0 100644 --- a/core/src/rigidbody.h +++ b/core/src/rigidbody.h @@ -1,10 +1,8 @@ #ifndef _fencer_rigidbody_h #define _fencer_rigidbody_h -#include "shape.h" #include "transformable.h" #include "list.h" -#include "stdint.h" #include "physics.h" typedef struct { @@ -61,8 +59,6 @@ extern void rigidbody_debug_draw_contacts(RigidBody* self); extern Transform* rigidbody_get_transform(RigidBody* self); -impl_Transformable_for(RigidBody, - rigidbody_get_transform -) +decl_typeclass_impl(Transformable, RigidBody) #endif // !_fencer_rigidbody_h diff --git a/core/src/spritesheet.c b/core/src/spritesheet.c index 554fa6f..b6cf4be 100644 --- a/core/src/spritesheet.c +++ b/core/src/spritesheet.c @@ -20,6 +20,15 @@ struct Spritesheet { IVector tile_size; }; +impl_Drop_for(Spritesheet, + _internal_spritesheet_destroy +) + +impl_Asset_for(Spritesheet, + spritesheet_get_asset_id, + spritesheet_set_asset_id +) + void _internal_spritesheet_destroy(Spritesheet* self) { SDL_DestroyTexture(self->texture); free(self); diff --git a/core/src/spritesheet.h b/core/src/spritesheet.h index 6d56887..71e18cd 100644 --- a/core/src/spritesheet.h +++ b/core/src/spritesheet.h @@ -2,6 +2,7 @@ #define _fencer_spritesheet_h #include "asset.h" +#include "typeclass_helpers.h" #include "vmath.h" #include @@ -21,13 +22,7 @@ extern void spritesheet_set_asset_id(Spritesheet* self, asset_id id); extern void _internal_spritesheet_destroy(Spritesheet* self_void); -impl_Drop_for(Spritesheet, - _internal_spritesheet_destroy -) - -impl_Asset_for(Spritesheet, - spritesheet_get_asset_id, - spritesheet_set_asset_id -) +decl_typeclass_impl(Drop, Spritesheet) +decl_typeclass_impl(Asset, Spritesheet) #endif // !_fencer_spritesheet_h diff --git a/core/src/transform.c b/core/src/transform.c new file mode 100644 index 0000000..edef40c --- /dev/null +++ b/core/src/transform.c @@ -0,0 +1,5 @@ +#include "transform.h" + +impl_Transformable_for(Transform, + transform_get_transform +) diff --git a/core/src/transform.h b/core/src/transform.h index 7ed243e..4c657de 100644 --- a/core/src/transform.h +++ b/core/src/transform.h @@ -1,6 +1,7 @@ #ifndef _fencer_transform_h #define _fencer_transform_h +#include "typeclass_helpers.h" #include "vmath.h" #include "transformable.h" @@ -56,8 +57,6 @@ Transform* transform_get_transform(Transform* self) { return self; } -impl_Transformable_for(Transform, - transform_get_transform -); +decl_typeclass_impl(Transformable, Transform) #endif // !_fencer_transform_h diff --git a/core/src/transformable.h b/core/src/transformable.h index 0ac7531..1e38d61 100644 --- a/core/src/transformable.h +++ b/core/src/transformable.h @@ -26,7 +26,7 @@ extern void transformable_set_rotation(Transformable self, float rotation); extern void transformable_rotate(Transformable self, float delta); #define impl_Transformable_for(T, get_transform_f)\ -static inline Transformable T##_as_Transformable(T* x) {\ +Transformable T##_as_Transformable(T* x) {\ TC_FN_TYPECHECK(Transform*, get_transform_f, T*);\ static ITransformable const tc = {\ .get_transform = (Transform*(*const)(void*)) get_transform_f\ diff --git a/core/src/typeclass_helpers.h b/core/src/typeclass_helpers.h index 2457295..5f24513 100644 --- a/core/src/typeclass_helpers.h +++ b/core/src/typeclass_helpers.h @@ -4,4 +4,7 @@ #define TC_FN_TYPECHECK(__Return, __Name, ...)\ __Return (*const __Name##_)(__VA_ARGS__) = __Name; (void)__Name##_ +#define decl_typeclass_impl(__Typeclass, __Type)\ +extern __Typeclass __Type##_as_##__Typeclass(__Type*); + #endif // !_fencer_typeclass_helpers_h diff --git a/game/src/Damagable.h b/game/src/Damagable.h index 453f938..677ada6 100644 --- a/game/src/Damagable.h +++ b/game/src/Damagable.h @@ -20,7 +20,7 @@ typedef struct { } Damagable; #define impl_Damagable_for(T, damage_f)\ -static inline Damagable T##_as_Damagable(T* x) {\ +Damagable T##_as_Damagable(T* x) {\ TC_FN_TYPECHECK(int, damage_f, T*, DamageEventData*);\ static const IDamagable tc = {\ .damage = (int(*const)(void*, DamageEventData*)) damage_f,\ diff --git a/game/src/Enemy.c b/game/src/Enemy.c index 4889107..b6b83bb 100644 --- a/game/src/Enemy.c +++ b/game/src/Enemy.c @@ -13,6 +13,31 @@ START_REFLECT(Enemy) REFLECT_TYPECLASS(Enemy, Damagable) END_REFLECT(Enemy) +impl_Transformable_for(Enemy, + EnemyGetTransform +) + +impl_Drop_for(Enemy, + EnemyDestroy +) + +impl_BehaviourEntity_for(Enemy, + EnemyStart, + EnemyUpdate, + EnemyDraw, + EnemyGetDepth +) + +impl_PhysicsEntity_for(Enemy, + EnemyGetRigidBody, + EnemyOnCollision, + EnemyOnOverlap +) + +impl_Damagable_for(Enemy, + EnemyDamage +) + Enemy* MakeEnemy() { Enemy* self = malloc(sizeof(Enemy)); ASSERT_RETURN(self != NULL, NULL, "Failed to allocate Enemy"); diff --git a/game/src/Enemy.h b/game/src/Enemy.h index 1e54323..7bc4e25 100644 --- a/game/src/Enemy.h +++ b/game/src/Enemy.h @@ -13,6 +13,7 @@ #include "Damagable.h" #include "EnemyStates.h" +#include "typeclass_helpers.h" typedef struct Enemy { Transform transform; @@ -56,29 +57,10 @@ extern int EnemyDamage(Enemy* self, DamageEventData* data); DECL_REFLECT(Enemy) -impl_Transformable_for(Enemy, - EnemyGetTransform -) - -impl_Drop_for(Enemy, - EnemyDestroy -) - -impl_BehaviourEntity_for(Enemy, - EnemyStart, - EnemyUpdate, - EnemyDraw, - EnemyGetDepth -) - -impl_PhysicsEntity_for(Enemy, - EnemyGetRigidBody, - EnemyOnCollision, - EnemyOnOverlap -) - -impl_Damagable_for(Enemy, - EnemyDamage -) +decl_typeclass_impl(Transformable, Enemy) +decl_typeclass_impl(Drop, Enemy) +decl_typeclass_impl(BehaviourEntity, Enemy) +decl_typeclass_impl(PhysicsEntity, Enemy) +decl_typeclass_impl(Damagable, Enemy) #endif // !FIGHT_ENEMY_H diff --git a/game/src/Player.c b/game/src/Player.c index 3976e6d..cc16526 100644 --- a/game/src/Player.c +++ b/game/src/Player.c @@ -15,6 +15,27 @@ START_REFLECT(Player) REFLECT_TYPECLASS(Player, BehaviourEntity) END_REFLECT(Player) +impl_Drop_for(Player, + DestroyPlayer +) + +impl_BehaviourEntity_for(Player, + PlayerStart, + PlayerUpdate, + PlayerDraw, + PlayerGetDepth +) + +impl_Transformable_for(Player, + PlayerGetTransform +) + +impl_PhysicsEntity_for(Player, + PlayerGetRigidBody, + PlayerOnCollision, + PlayerOnOverlap +) + static inline void Internal_PlayerInitInput(Player* self) { playerinput_add(self->playerInput, CompositeAxis1D_as_InputAxis(compositeaxis1d_new( diff --git a/game/src/Player.h b/game/src/Player.h index 146a6d7..ba9c3f6 100644 --- a/game/src/Player.h +++ b/game/src/Player.h @@ -10,6 +10,7 @@ #include "player_input.h" #include "rigidbody.h" #include "collider.h" +#include "typeclass_helpers.h" extern const Vector PLAYER_SPEED; @@ -61,25 +62,9 @@ static long PlayerGetDepth(Player* self) { return (int)(-10-self->transform.posi DECL_REFLECT(Player); -impl_Drop_for(Player, - DestroyPlayer -) - -impl_BehaviourEntity_for(Player, - PlayerStart, - PlayerUpdate, - PlayerDraw, - PlayerGetDepth -) - -impl_Transformable_for(Player, - PlayerGetTransform -) - -impl_PhysicsEntity_for(Player, - PlayerGetRigidBody, - PlayerOnCollision, - PlayerOnOverlap -) +decl_typeclass_impl(BehaviourEntity, Player) +decl_typeclass_impl(Drop, Player) +decl_typeclass_impl(Transformable, Player) +decl_typeclass_impl(PhysicsEntity, Player) #endif // !FIGHT_PLAYER_H diff --git a/game/src/Prop.c b/game/src/Prop.c index 0917ff3..61a83f6 100644 --- a/game/src/Prop.c +++ b/game/src/Prop.c @@ -10,6 +10,27 @@ START_REFLECT(Prop) REFLECT_TYPECLASS(Prop, BehaviourEntity) END_REFLECT(Prop) +impl_Transformable_for(Prop, + PropGetTransform +) + +impl_PhysicsEntity_for(Prop, + PropGetRigidBody, + PropOnCollision, + PropOnOverlap +) + +impl_Drop_for(Prop, + DestroyProp +) + +impl_BehaviourEntity_for(Prop, + PropStart, + PropUpdate, + PropDraw, + PropGetDepth +) + Prop* MakeProp(Sprite* sprite, Shape* shape) { Prop* self = malloc(sizeof(Prop)); ASSERT_RETURN(self != NULL, NULL, "Failed to allocate space for Prop instance"); diff --git a/game/src/Prop.h b/game/src/Prop.h index 5fe516f..e3b0ee7 100644 --- a/game/src/Prop.h +++ b/game/src/Prop.h @@ -9,6 +9,7 @@ #include "sprite.h" #include "rigidbody.h" #include "collider.h" +#include "typeclass_helpers.h" typedef struct Prop { Transform transform; @@ -35,25 +36,9 @@ static long PropGetDepth(Prop* self) { return -(int)(self->transform.position.y DECL_REFLECT(Prop) -impl_Transformable_for(Prop, - PropGetTransform -) - -impl_PhysicsEntity_for(Prop, - PropGetRigidBody, - PropOnCollision, - PropOnOverlap -) - -impl_Drop_for(Prop, - DestroyProp -) - -impl_BehaviourEntity_for(Prop, - PropStart, - PropUpdate, - PropDraw, - PropGetDepth -) +decl_typeclass_impl(Transformable, Prop) +decl_typeclass_impl(PhysicsEntity, Prop) +decl_typeclass_impl(Drop, Prop) +decl_typeclass_impl(BehaviourEntity, Prop) #endif // !FIGHT_PROP_H