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
This commit is contained in:
		
							parent
							
								
									760d9f2879
								
							
						
					
					
						commit
						0c6f1dd8cf
					
				| 
						 | 
					@ -19,7 +19,7 @@ typedef struct Asset {
 | 
				
			||||||
} Asset;
 | 
					} Asset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define impl_Asset_for(T, get_id_f, set_id_f)\
 | 
					#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(asset_id, get_id_f, T*);\
 | 
				
			||||||
    TC_FN_TYPECHECK(void, set_id_f, T*, asset_id);\
 | 
					    TC_FN_TYPECHECK(void, set_id_f, T*, asset_id);\
 | 
				
			||||||
    TC_FN_TYPECHECK(Drop, T##_as_Drop, T*);\
 | 
					    TC_FN_TYPECHECK(Drop, T##_as_Drop, T*);\
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,8 +2,8 @@
 | 
				
			||||||
#define _update_entity_h
 | 
					#define _update_entity_h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "drop.h"
 | 
					#include "drop.h"
 | 
				
			||||||
 | 
					#include "mirror.h"
 | 
				
			||||||
#include "typeclass_helpers.h"
 | 
					#include "typeclass_helpers.h"
 | 
				
			||||||
#include "vmath.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
    void (*const update)(void* self, float dt);
 | 
					    void (*const update)(void* self, float dt);
 | 
				
			||||||
| 
						 | 
					@ -16,10 +16,11 @@ typedef struct {
 | 
				
			||||||
    void* data;
 | 
					    void* data;
 | 
				
			||||||
    IEntityBehaviour const* tc;
 | 
					    IEntityBehaviour const* tc;
 | 
				
			||||||
    IDrop const* drop;
 | 
					    IDrop const* drop;
 | 
				
			||||||
 | 
					    IMirror const* mirror;
 | 
				
			||||||
} BehaviourEntity;
 | 
					} BehaviourEntity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define impl_BehaviourEntity_for(T, start_f, update_f, draw_f, get_depth_f)\
 | 
					#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, start_f, T*);\
 | 
				
			||||||
    TC_FN_TYPECHECK(void, update_f, T*, float);\
 | 
					    TC_FN_TYPECHECK(void, update_f, T*, float);\
 | 
				
			||||||
    TC_FN_TYPECHECK(void, draw_f, T*);\
 | 
					    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,\
 | 
					        .get_depth=(long(*const)(void*))         get_depth_f,\
 | 
				
			||||||
    };\
 | 
					    };\
 | 
				
			||||||
    TC_FN_TYPECHECK(Drop, T##_as_Drop, T*);\
 | 
					    TC_FN_TYPECHECK(Drop, T##_as_Drop, T*);\
 | 
				
			||||||
 | 
					    TC_FN_TYPECHECK(Mirror, T##_as_Mirror, T*);\
 | 
				
			||||||
    IDrop const* drop = T##_as_Drop(x).tc;\
 | 
					    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
 | 
					#endif // !_update_entity_h
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,7 +13,7 @@ typedef struct {
 | 
				
			||||||
} Drop;
 | 
					} Drop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define impl_Drop_for(T, drop_f)\
 | 
					#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*);\
 | 
					    TC_FN_TYPECHECK(void, drop_f, T*);\
 | 
				
			||||||
    static IDrop const tc = {\
 | 
					    static IDrop const tc = {\
 | 
				
			||||||
        .drop = (void(*const)(void*)) drop_f,\
 | 
					        .drop = (void(*const)(void*)) drop_f,\
 | 
				
			||||||
| 
						 | 
					@ -24,7 +24,7 @@ static inline Drop T##_as_Drop(T* x) {\
 | 
				
			||||||
extern void default_drop(void*);
 | 
					extern void default_drop(void*);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define impl_default_Drop_for(T)\
 | 
					#define impl_default_Drop_for(T)\
 | 
				
			||||||
static inline Drop T##_as_Drop(T* x) {\
 | 
					Drop T##_as_Drop(T* x) {\
 | 
				
			||||||
    static IDrop const tc = {\
 | 
					    static IDrop const tc = {\
 | 
				
			||||||
        .drop = default_drop,\
 | 
					        .drop = default_drop,\
 | 
				
			||||||
    };\
 | 
					    };\
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,42 @@
 | 
				
			||||||
#include "debug.h"
 | 
					#include "debug.h"
 | 
				
			||||||
#include "input.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* keybind_new(SDL_Scancode key) {
 | 
				
			||||||
    KeyBind* self = malloc(sizeof(KeyBind));
 | 
					    KeyBind* self = malloc(sizeof(KeyBind));
 | 
				
			||||||
    ASSERT_RETURN(self != NULL, NULL, "Failed to allocate space for KeyBind instance");
 | 
					    ASSERT_RETURN(self != NULL, NULL, "Failed to allocate space for KeyBind instance");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,7 +40,7 @@ typedef struct {
 | 
				
			||||||
} InputAxis;
 | 
					} InputAxis;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define impl_InputAxis_for(T, is_changed_by_f, evaluate_f, set_device_f)\
 | 
					#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(int, is_changed_by_f, T*, SDL_Event);\
 | 
				
			||||||
    TC_FN_TYPECHECK(struct InputEvent, evaluate_f, T*, SDL_Event);\
 | 
					    TC_FN_TYPECHECK(struct InputEvent, evaluate_f, T*, SDL_Event);\
 | 
				
			||||||
    TC_FN_TYPECHECK(void, set_device_f, T*, struct InputDevice*);\
 | 
					    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 struct InputEvent keybind_evaluate(KeyBind* self, SDL_Event);
 | 
				
			||||||
extern void keybind_set_device(KeyBind* self, struct InputDevice* device);
 | 
					extern void keybind_set_device(KeyBind* self, struct InputDevice* device);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl_default_Drop_for(KeyBind)
 | 
					decl_typeclass_impl(InputAxis, KeyBind)
 | 
				
			||||||
impl_InputAxis_for(KeyBind,
 | 
					decl_typeclass_impl(Drop, KeyBind)
 | 
				
			||||||
    keybind_is_changed_by,
 | 
					 | 
				
			||||||
    keybind_evaluate,
 | 
					 | 
				
			||||||
    keybind_set_device
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct ControllerAxis {
 | 
					typedef struct ControllerAxis {
 | 
				
			||||||
    struct InputDevice* device;
 | 
					    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 struct InputEvent controlleraxis_evaluate(ControllerAxis* self, SDL_Event event);
 | 
				
			||||||
extern void controlleraxis_set_device(ControllerAxis* self, struct InputDevice* device);
 | 
					extern void controlleraxis_set_device(ControllerAxis* self, struct InputDevice* device);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl_default_Drop_for(ControllerAxis)
 | 
					decl_typeclass_impl(InputAxis, ControllerAxis)
 | 
				
			||||||
impl_InputAxis_for(ControllerAxis,
 | 
					decl_typeclass_impl(Drop, ControllerAxis)
 | 
				
			||||||
    controlleraxis_is_changed_by,
 | 
					 | 
				
			||||||
    controlleraxis_evaluate,
 | 
					 | 
				
			||||||
    controlleraxis_set_device
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct ControllerButton {
 | 
					typedef struct ControllerButton {
 | 
				
			||||||
    struct InputDevice* device;
 | 
					    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 struct InputEvent controllerbutton_evaluate(ControllerButton* self, SDL_Event event);
 | 
				
			||||||
extern void controllerbutton_set_device(ControllerButton* self, struct InputDevice* device);
 | 
					extern void controllerbutton_set_device(ControllerButton* self, struct InputDevice* device);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl_default_Drop_for(ControllerButton)
 | 
					decl_typeclass_impl(InputAxis, ControllerButton)
 | 
				
			||||||
impl_InputAxis_for(ControllerButton,
 | 
					decl_typeclass_impl(Drop, ControllerButton)
 | 
				
			||||||
    controllerbutton_is_changed_by,
 | 
					 | 
				
			||||||
    controllerbutton_evaluate,
 | 
					 | 
				
			||||||
    controllerbutton_set_device
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct CompositeAxis1D {
 | 
					typedef struct CompositeAxis1D {
 | 
				
			||||||
    InputAxis left;
 | 
					    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_set_device(CompositeAxis1D* self, struct InputDevice* device);
 | 
				
			||||||
extern void compositeaxis1d_drop(CompositeAxis1D* self);
 | 
					extern void compositeaxis1d_drop(CompositeAxis1D* self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl_Drop_for(CompositeAxis1D,
 | 
					decl_typeclass_impl(InputAxis, CompositeAxis1D)
 | 
				
			||||||
    compositeaxis1d_drop
 | 
					decl_typeclass_impl(Drop, CompositeAxis1D)
 | 
				
			||||||
)
 | 
					 | 
				
			||||||
impl_InputAxis_for(CompositeAxis1D,
 | 
					 | 
				
			||||||
    compositeaxis1d_is_changed_by,
 | 
					 | 
				
			||||||
    compositeaxis1d_evaluate,
 | 
					 | 
				
			||||||
    compositeaxis1d_set_device
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // !_fencer_input_axis_h
 | 
					#endif // !_fencer_input_axis_h
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,7 @@
 | 
				
			||||||
#include "transform.h"
 | 
					#include "transform.h"
 | 
				
			||||||
#include "stdint.h"
 | 
					#include "stdint.h"
 | 
				
			||||||
#include "physics_entity.h"
 | 
					#include "physics_entity.h"
 | 
				
			||||||
 | 
					#include "shape.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef uint32_t PhysicsMask;
 | 
					typedef uint32_t PhysicsMask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,7 +29,7 @@ extern void physics_entity_solve_contacts(PhysicsEntity self, List* contacts);
 | 
				
			||||||
extern void physics_entity_update(PhysicsEntity self);
 | 
					extern void physics_entity_update(PhysicsEntity self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define impl_PhysicsEntity_for(T, get_rigidbody_f, on_collision_f, on_overlap_f)\
 | 
					#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(RigidBody*, get_rigidbody_f, T*);\
 | 
				
			||||||
    TC_FN_TYPECHECK(void, on_collision_f, T*, Collision);\
 | 
					    TC_FN_TYPECHECK(void, on_collision_f, T*, Collision);\
 | 
				
			||||||
    TC_FN_TYPECHECK(void, on_overlap_f, T*, Collider*);\
 | 
					    TC_FN_TYPECHECK(void, on_overlap_f, T*, Collider*);\
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,10 @@
 | 
				
			||||||
#include "player_input.h"
 | 
					#include "player_input.h"
 | 
				
			||||||
#include "debug.h"
 | 
					#include "debug.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl_Drop_for(PlayerInput,
 | 
				
			||||||
 | 
					    playerinput_drop
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PlayerInput* playerinput_new(void* target, int device) {
 | 
					PlayerInput* playerinput_new(void* target, int device) {
 | 
				
			||||||
    PlayerInput* self = malloc(sizeof(PlayerInput));
 | 
					    PlayerInput* self = malloc(sizeof(PlayerInput));
 | 
				
			||||||
    ASSERT_RETURN(self != NULL, NULL, "Could not allocate memory for PlayerInput instance");
 | 
					    ASSERT_RETURN(self != NULL, NULL, "Could not allocate memory for PlayerInput instance");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,7 @@
 | 
				
			||||||
#include "list.h"
 | 
					#include "list.h"
 | 
				
			||||||
#include "input.h"
 | 
					#include "input.h"
 | 
				
			||||||
#include "input_axis.h"
 | 
					#include "input_axis.h"
 | 
				
			||||||
 | 
					#include "typeclass_helpers.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct PlayerInput {
 | 
					typedef struct PlayerInput {
 | 
				
			||||||
    InputDevice* device;
 | 
					    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_set_device(PlayerInput* self, int device);
 | 
				
			||||||
extern void playerinput_drop(PlayerInput* self);
 | 
					extern void playerinput_drop(PlayerInput* self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl_Drop_for(PlayerInput,
 | 
					decl_typeclass_impl(Drop, PlayerInput)
 | 
				
			||||||
    playerinput_drop
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // !_fencer_player_input_h
 | 
					#endif // !_fencer_player_input_h
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,6 +26,10 @@ struct RigidBody {
 | 
				
			||||||
    List contacts;
 | 
					    List contacts;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl_Transformable_for(RigidBody,
 | 
				
			||||||
 | 
					    rigidbody_get_transform
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RigidBody* rigidbody_make(PhysicsEntity owner) {
 | 
					RigidBody* rigidbody_make(PhysicsEntity owner) {
 | 
				
			||||||
    RigidBody* self = malloc(sizeof(RigidBody));
 | 
					    RigidBody* self = malloc(sizeof(RigidBody));
 | 
				
			||||||
    ASSERT_RETURN(self != NULL, NULL, "Failed to allocate space for rigidbody");
 | 
					    ASSERT_RETURN(self != NULL, NULL, "Failed to allocate space for rigidbody");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,8 @@
 | 
				
			||||||
#ifndef _fencer_rigidbody_h
 | 
					#ifndef _fencer_rigidbody_h
 | 
				
			||||||
#define _fencer_rigidbody_h
 | 
					#define _fencer_rigidbody_h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "shape.h"
 | 
					 | 
				
			||||||
#include "transformable.h"
 | 
					#include "transformable.h"
 | 
				
			||||||
#include "list.h"
 | 
					#include "list.h"
 | 
				
			||||||
#include "stdint.h"
 | 
					 | 
				
			||||||
#include "physics.h"
 | 
					#include "physics.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
| 
						 | 
					@ -61,8 +59,6 @@ extern void rigidbody_debug_draw_contacts(RigidBody* self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern Transform* rigidbody_get_transform(RigidBody* self);
 | 
					extern Transform* rigidbody_get_transform(RigidBody* self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl_Transformable_for(RigidBody,
 | 
					decl_typeclass_impl(Transformable, RigidBody)
 | 
				
			||||||
    rigidbody_get_transform
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // !_fencer_rigidbody_h
 | 
					#endif // !_fencer_rigidbody_h
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,6 +20,15 @@ struct Spritesheet {
 | 
				
			||||||
    IVector tile_size;
 | 
					    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) {
 | 
					void _internal_spritesheet_destroy(Spritesheet* self) {
 | 
				
			||||||
    SDL_DestroyTexture(self->texture);
 | 
					    SDL_DestroyTexture(self->texture);
 | 
				
			||||||
    free(self);
 | 
					    free(self);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,7 @@
 | 
				
			||||||
#define _fencer_spritesheet_h
 | 
					#define _fencer_spritesheet_h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "asset.h"
 | 
					#include "asset.h"
 | 
				
			||||||
 | 
					#include "typeclass_helpers.h"
 | 
				
			||||||
#include "vmath.h"
 | 
					#include "vmath.h"
 | 
				
			||||||
#include <SDL2/SDL_render.h>
 | 
					#include <SDL2/SDL_render.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,13 +22,7 @@ extern void spritesheet_set_asset_id(Spritesheet* self, asset_id id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void _internal_spritesheet_destroy(Spritesheet* self_void);
 | 
					extern void _internal_spritesheet_destroy(Spritesheet* self_void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl_Drop_for(Spritesheet,
 | 
					decl_typeclass_impl(Drop, Spritesheet)
 | 
				
			||||||
    _internal_spritesheet_destroy
 | 
					decl_typeclass_impl(Asset, Spritesheet)
 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl_Asset_for(Spritesheet,
 | 
					 | 
				
			||||||
    spritesheet_get_asset_id,
 | 
					 | 
				
			||||||
    spritesheet_set_asset_id
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // !_fencer_spritesheet_h
 | 
					#endif // !_fencer_spritesheet_h
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										5
									
								
								core/src/transform.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								core/src/transform.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,5 @@
 | 
				
			||||||
 | 
					#include "transform.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl_Transformable_for(Transform,
 | 
				
			||||||
 | 
					    transform_get_transform
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
#ifndef _fencer_transform_h
 | 
					#ifndef _fencer_transform_h
 | 
				
			||||||
#define _fencer_transform_h
 | 
					#define _fencer_transform_h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "typeclass_helpers.h"
 | 
				
			||||||
#include "vmath.h"
 | 
					#include "vmath.h"
 | 
				
			||||||
#include "transformable.h"
 | 
					#include "transformable.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -56,8 +57,6 @@ Transform* transform_get_transform(Transform* self) {
 | 
				
			||||||
    return self;
 | 
					    return self;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl_Transformable_for(Transform,
 | 
					decl_typeclass_impl(Transformable, Transform)
 | 
				
			||||||
    transform_get_transform
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // !_fencer_transform_h
 | 
					#endif // !_fencer_transform_h
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,7 +26,7 @@ extern void transformable_set_rotation(Transformable self, float rotation);
 | 
				
			||||||
extern void transformable_rotate(Transformable self, float delta);
 | 
					extern void transformable_rotate(Transformable self, float delta);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define impl_Transformable_for(T, get_transform_f)\
 | 
					#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*);\
 | 
					    TC_FN_TYPECHECK(Transform*, get_transform_f, T*);\
 | 
				
			||||||
    static ITransformable const tc = {\
 | 
					    static ITransformable const tc = {\
 | 
				
			||||||
        .get_transform =    (Transform*(*const)(void*)) get_transform_f\
 | 
					        .get_transform =    (Transform*(*const)(void*)) get_transform_f\
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,4 +4,7 @@
 | 
				
			||||||
#define TC_FN_TYPECHECK(__Return, __Name, ...)\
 | 
					#define TC_FN_TYPECHECK(__Return, __Name, ...)\
 | 
				
			||||||
__Return (*const __Name##_)(__VA_ARGS__) = __Name; (void)__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
 | 
					#endif // !_fencer_typeclass_helpers_h
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,7 +20,7 @@ typedef struct {
 | 
				
			||||||
} Damagable;
 | 
					} Damagable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define impl_Damagable_for(T, damage_f)\
 | 
					#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*);\
 | 
					    TC_FN_TYPECHECK(int, damage_f, T*, DamageEventData*);\
 | 
				
			||||||
    static const IDamagable tc = {\
 | 
					    static const IDamagable tc = {\
 | 
				
			||||||
        .damage = (int(*const)(void*, DamageEventData*)) damage_f,\
 | 
					        .damage = (int(*const)(void*, DamageEventData*)) damage_f,\
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,6 +13,31 @@ START_REFLECT(Enemy)
 | 
				
			||||||
    REFLECT_TYPECLASS(Enemy, Damagable)
 | 
					    REFLECT_TYPECLASS(Enemy, Damagable)
 | 
				
			||||||
END_REFLECT(Enemy)
 | 
					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* MakeEnemy() {
 | 
				
			||||||
    Enemy* self = malloc(sizeof(Enemy));
 | 
					    Enemy* self = malloc(sizeof(Enemy));
 | 
				
			||||||
    ASSERT_RETURN(self != NULL, NULL, "Failed to allocate Enemy");
 | 
					    ASSERT_RETURN(self != NULL, NULL, "Failed to allocate Enemy");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,6 +13,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Damagable.h"
 | 
					#include "Damagable.h"
 | 
				
			||||||
#include "EnemyStates.h"
 | 
					#include "EnemyStates.h"
 | 
				
			||||||
 | 
					#include "typeclass_helpers.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct Enemy {
 | 
					typedef struct Enemy {
 | 
				
			||||||
    Transform transform;
 | 
					    Transform transform;
 | 
				
			||||||
| 
						 | 
					@ -56,29 +57,10 @@ extern int EnemyDamage(Enemy* self, DamageEventData* data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DECL_REFLECT(Enemy)
 | 
					DECL_REFLECT(Enemy)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl_Transformable_for(Enemy,
 | 
					decl_typeclass_impl(Transformable, Enemy)
 | 
				
			||||||
    EnemyGetTransform
 | 
					decl_typeclass_impl(Drop, Enemy)
 | 
				
			||||||
)
 | 
					decl_typeclass_impl(BehaviourEntity, Enemy)
 | 
				
			||||||
 | 
					decl_typeclass_impl(PhysicsEntity, Enemy)
 | 
				
			||||||
impl_Drop_for(Enemy,
 | 
					decl_typeclass_impl(Damagable, Enemy)
 | 
				
			||||||
    EnemyDestroy
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl_BehaviourEntity_for(Enemy,
 | 
					 | 
				
			||||||
    EnemyStart,
 | 
					 | 
				
			||||||
    EnemyUpdate,
 | 
					 | 
				
			||||||
    EnemyDraw,
 | 
					 | 
				
			||||||
    EnemyGetDepth
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl_PhysicsEntity_for(Enemy,
 | 
					 | 
				
			||||||
    EnemyGetRigidBody,
 | 
					 | 
				
			||||||
    EnemyOnCollision,
 | 
					 | 
				
			||||||
    EnemyOnOverlap
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl_Damagable_for(Enemy,
 | 
					 | 
				
			||||||
    EnemyDamage
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // !FIGHT_ENEMY_H
 | 
					#endif // !FIGHT_ENEMY_H
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,27 @@ START_REFLECT(Player)
 | 
				
			||||||
    REFLECT_TYPECLASS(Player, BehaviourEntity)
 | 
					    REFLECT_TYPECLASS(Player, BehaviourEntity)
 | 
				
			||||||
END_REFLECT(Player)
 | 
					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
 | 
					static inline
 | 
				
			||||||
void Internal_PlayerInitInput(Player* self) {
 | 
					void Internal_PlayerInitInput(Player* self) {
 | 
				
			||||||
    playerinput_add(self->playerInput, CompositeAxis1D_as_InputAxis(compositeaxis1d_new(
 | 
					    playerinput_add(self->playerInput, CompositeAxis1D_as_InputAxis(compositeaxis1d_new(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,6 +10,7 @@
 | 
				
			||||||
#include "player_input.h"
 | 
					#include "player_input.h"
 | 
				
			||||||
#include "rigidbody.h"
 | 
					#include "rigidbody.h"
 | 
				
			||||||
#include "collider.h"
 | 
					#include "collider.h"
 | 
				
			||||||
 | 
					#include "typeclass_helpers.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern const Vector PLAYER_SPEED;
 | 
					extern const Vector PLAYER_SPEED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,25 +62,9 @@ static long PlayerGetDepth(Player* self) { return (int)(-10-self->transform.posi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DECL_REFLECT(Player);
 | 
					DECL_REFLECT(Player);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl_Drop_for(Player,
 | 
					decl_typeclass_impl(BehaviourEntity, Player)
 | 
				
			||||||
    DestroyPlayer
 | 
					decl_typeclass_impl(Drop, Player)
 | 
				
			||||||
)
 | 
					decl_typeclass_impl(Transformable, Player)
 | 
				
			||||||
 | 
					decl_typeclass_impl(PhysicsEntity, Player)
 | 
				
			||||||
impl_BehaviourEntity_for(Player,
 | 
					 | 
				
			||||||
    PlayerStart,
 | 
					 | 
				
			||||||
    PlayerUpdate,
 | 
					 | 
				
			||||||
    PlayerDraw,
 | 
					 | 
				
			||||||
    PlayerGetDepth
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl_Transformable_for(Player,
 | 
					 | 
				
			||||||
    PlayerGetTransform
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl_PhysicsEntity_for(Player,
 | 
					 | 
				
			||||||
    PlayerGetRigidBody,
 | 
					 | 
				
			||||||
    PlayerOnCollision,
 | 
					 | 
				
			||||||
    PlayerOnOverlap
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // !FIGHT_PLAYER_H
 | 
					#endif // !FIGHT_PLAYER_H
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,6 +10,27 @@ START_REFLECT(Prop)
 | 
				
			||||||
    REFLECT_TYPECLASS(Prop, BehaviourEntity)
 | 
					    REFLECT_TYPECLASS(Prop, BehaviourEntity)
 | 
				
			||||||
END_REFLECT(Prop)
 | 
					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* MakeProp(Sprite* sprite, Shape* shape) {
 | 
				
			||||||
    Prop* self = malloc(sizeof(Prop));
 | 
					    Prop* self = malloc(sizeof(Prop));
 | 
				
			||||||
    ASSERT_RETURN(self != NULL, NULL, "Failed to allocate space for Prop instance");
 | 
					    ASSERT_RETURN(self != NULL, NULL, "Failed to allocate space for Prop instance");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,7 @@
 | 
				
			||||||
#include "sprite.h"
 | 
					#include "sprite.h"
 | 
				
			||||||
#include "rigidbody.h"
 | 
					#include "rigidbody.h"
 | 
				
			||||||
#include "collider.h"
 | 
					#include "collider.h"
 | 
				
			||||||
 | 
					#include "typeclass_helpers.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct Prop {
 | 
					typedef struct Prop {
 | 
				
			||||||
    Transform transform;
 | 
					    Transform transform;
 | 
				
			||||||
| 
						 | 
					@ -35,25 +36,9 @@ static long PropGetDepth(Prop* self) { return -(int)(self->transform.position.y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DECL_REFLECT(Prop)
 | 
					DECL_REFLECT(Prop)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl_Transformable_for(Prop,
 | 
					decl_typeclass_impl(Transformable, Prop)
 | 
				
			||||||
    PropGetTransform
 | 
					decl_typeclass_impl(PhysicsEntity, Prop)
 | 
				
			||||||
)
 | 
					decl_typeclass_impl(Drop, Prop)
 | 
				
			||||||
 | 
					decl_typeclass_impl(BehaviourEntity, Prop)
 | 
				
			||||||
impl_PhysicsEntity_for(Prop,
 | 
					 | 
				
			||||||
    PropGetRigidBody,
 | 
					 | 
				
			||||||
    PropOnCollision,
 | 
					 | 
				
			||||||
    PropOnOverlap
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl_Drop_for(Prop,
 | 
					 | 
				
			||||||
    DestroyProp
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl_BehaviourEntity_for(Prop,
 | 
					 | 
				
			||||||
    PropStart,
 | 
					 | 
				
			||||||
    PropUpdate,
 | 
					 | 
				
			||||||
    PropDraw,
 | 
					 | 
				
			||||||
    PropGetDepth
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // !FIGHT_PROP_H
 | 
					#endif // !FIGHT_PROP_H
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue