diff --git a/src/transform.h b/src/transform.h index 9627601..8d5054a 100644 --- a/src/transform.h +++ b/src/transform.h @@ -2,6 +2,7 @@ #define _fencer_transform_h #include "vmath.h" +#include "transformable.h" typedef struct Transform Transform; struct Transform { @@ -45,4 +46,31 @@ Vector transform_point(Transform* self, Vector position) { return vaddf(vmulf(transform_direction(self, position), self->scale), self->position); } +static +Transform* transform_get_transform(Transform* self) { + return self; +} + +static +Vector* transform_get_position(Transform* self) { + return &self->position; +} + +static +Vector* transform_get_scale(Transform* self) { + return &self->scale; +} + +static +float* transform_get_rotation(Transform* self) { + return &self->rotation; +} + +impl_Transformable_for(Transform, + transform_get_transform, + transform_get_position, + transform_get_scale, + transform_get_rotation +); + #endif // !_fencer_transform_h diff --git a/src/transformable.h b/src/transformable.h new file mode 100644 index 0000000..32f38c3 --- /dev/null +++ b/src/transformable.h @@ -0,0 +1,33 @@ +#ifndef _fencer_transformable_h +#define _fencer_transformable_h + +#include "vmath.h" +#include "typeclass_helpers.h" + +typedef struct { + struct Transform* (*const get_transform)(void* self); + Vector* (*const get_position)(void* self); + Vector* (*const get_scale)(void* self); + float* (*const get_rotation)(void* self); +} ITransformable; + +typedef struct { + void* self; + ITransformable const* tc; +} Transformable; + +#define impl_Transformable_for(T, get_transform_f, get_position_f, get_scale_f, get_rotation_f)\ +static inline Transformable T##_as_Transformable(T* x) {\ + TC_FN_TYPECHECK(Transform*, get_transform_f, T* e);\ + TC_FN_TYPECHECK(Vector*, get_position_f, T* e);\ + TC_FN_TYPECHECK(float*, get_rotation_f, T* e);\ + static ITransformable const tc = {\ + .get_transform = (Transform*(*const)(void*)) get_transform_f,\ + .get_position = (Vector*(*const)(void*)) get_position_f,\ + .get_scale = (Vector*(*const)(void*)) get_scale_f,\ + .get_rotation = (float*(*const)(void*)) get_rotation_f\ + };\ + return (Transformable){.tc = &tc, .self = x };\ +} + +#endif // !_fencer_transformable_h diff --git a/src/typeclass_helpers.h b/src/typeclass_helpers.h new file mode 100644 index 0000000..2457295 --- /dev/null +++ b/src/typeclass_helpers.h @@ -0,0 +1,7 @@ +#ifndef _fencer_typeclass_helpers_h +#define _fencer_typeclass_helpers_h + +#define TC_FN_TYPECHECK(__Return, __Name, ...)\ +__Return (*const __Name##_)(__VA_ARGS__) = __Name; (void)__Name##_ + +#endif // !_fencer_typeclass_helpers_h