feat: replaced messagereceiver with mirror
This commit is contained in:
parent
be64a55588
commit
bf23ff877a
16 changed files with 236 additions and 116 deletions
|
|
@ -1,13 +0,0 @@
|
|||
#include "message_receiver.h"
|
||||
#include "stddef.h"
|
||||
|
||||
void* message_receiver_refuse(void* self, MessageID id, uintptr_t data) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MessageReceiver message_receiver_no_implementation(void* data) {
|
||||
static IMessageReceiver const tc = {
|
||||
.handle_message = message_receiver_refuse
|
||||
};
|
||||
return (MessageReceiver){.data = data, .tc = &tc};
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
#ifndef _fencer_message_receiver_h
|
||||
#define _fencer_message_receiver_h
|
||||
|
||||
#include "stdint.h"
|
||||
#include "typeclass_helpers.h"
|
||||
|
||||
typedef uint32_t MessageID;
|
||||
|
||||
typedef struct IMessageReceiver {
|
||||
void* (*const handle_message)(void*, MessageID, uintptr_t);
|
||||
} IMessageReceiver;
|
||||
|
||||
typedef struct MessageReceiver {
|
||||
void* data;
|
||||
IMessageReceiver const* tc;
|
||||
} MessageReceiver;
|
||||
|
||||
extern void* message_receiver_refuse(void* self, MessageID id, uintptr_t);
|
||||
|
||||
extern MessageReceiver message_receiver_no_implementation(void* x);
|
||||
|
||||
#define impl_no_MessageReceiver_for(T)\
|
||||
static inline MessageReceiver T##_as_MessageReceiver(T* x) {\
|
||||
return message_receiver_no_implementation(x);\
|
||||
}
|
||||
|
||||
#define impl_MessageReceiver_for(T, handle_message_f)\
|
||||
static inline MessageReceiver T##_as_MessageReceiver(T* x) {\
|
||||
TC_FN_TYPECHECK(void*, handle_message_f, T*, MessageID, uintptr_t);\
|
||||
static IMessageReceiver const tc = {\
|
||||
.handle_message = (void*(*const)(void*,MessageID,uintptr_t)) handle_message_f,\
|
||||
};\
|
||||
return (MessageReceiver){.data = x, .tc = &tc};\
|
||||
}
|
||||
|
||||
#endif // !_fencer_message_receiver_h
|
||||
10
core/src/mirror.c
Normal file
10
core/src/mirror.c
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#include "mirror.h"
|
||||
|
||||
void* mirror_get_converter(void* self, IMirror const* tc, const char* typeclass) {
|
||||
uintptr_t target_hash = strhash(typeclass);
|
||||
list_foreach(MirroredTypeclass*, class, tc->get_typeclasses(self)) {
|
||||
if(target_hash == class->name_hash && strcmp(typeclass, class->typeclass_name) == 0)
|
||||
return class->wrap;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
101
core/src/mirror.h
Normal file
101
core/src/mirror.h
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
#ifndef _fencer_mirror_h
|
||||
#define _fencer_mirror_h
|
||||
|
||||
#include "typeclass_helpers.h"
|
||||
#include "stdint.h"
|
||||
#include "string.h"
|
||||
#include "list.h"
|
||||
#include "strutil.h"
|
||||
|
||||
typedef uintptr_t typeid;
|
||||
|
||||
typedef struct {
|
||||
const char* (*const get_typestring)(void* self);
|
||||
typeid (*const get_typeid)(void* self);
|
||||
List* (*const get_typeclasses)(void* self);
|
||||
} IMirror;
|
||||
|
||||
typedef struct {
|
||||
void* data;
|
||||
IMirror const* tc;
|
||||
} Mirror;
|
||||
|
||||
typedef struct {
|
||||
const char* typeclass_name;
|
||||
uintptr_t name_hash;
|
||||
void* (*const wrap)(void*);
|
||||
} MirroredTypeclass;
|
||||
|
||||
static inline int mirror_is_typeid(const Mirror* mirror, typeid id) {
|
||||
return mirror->tc->get_typeid(mirror->data) == id;
|
||||
}
|
||||
static inline int mirror_is_typestring(const Mirror* mirror, const char* id) {
|
||||
return strcmp(id, mirror->tc->get_typestring(mirror->data)) == 0;
|
||||
}
|
||||
static inline int mirror_eq(const Mirror* lhs, const Mirror* rhs) {
|
||||
return lhs->tc->get_typeid(lhs->data) == rhs->tc->get_typeid(rhs->data);
|
||||
}
|
||||
|
||||
extern void* mirror_get_converter(void* data, IMirror const* tc, const char* typeclass);
|
||||
|
||||
#define MIRROR_TRY_WRAP(Into_, Mirror_, Typeclass_){\
|
||||
MirroredTypeclassWrapFunc fn_ = mirror_get_typeclass(Mirror_, #Typeclass_);\
|
||||
if(fn_ != NULL) {\
|
||||
Into_ = (TypeClass_)fn(Mirror_->data);\
|
||||
}\
|
||||
}
|
||||
|
||||
#define impl_Mirror_for(T, get_typestring_f, get_typeid_f, get_typeclasses_f)\
|
||||
static inline Mirror T##_as_Mirror(T* x) {\
|
||||
TC_FN_TYPECHECK(const char*, get_typestring_f, T*);\
|
||||
TC_FN_TYPECHECK(typeid, get_typeid_f, T*);\
|
||||
TC_FN_TYPECHECK(List*, get_typeclasses_f, T*);\
|
||||
static IMirror const tc = {\
|
||||
.get_typestring = (const char*(*const)(void*)) get_typestring_f,\
|
||||
.get_typeid = (typeid (*const)(void*)) get_typeid_f,\
|
||||
.get_typeclasses = (List* (*const)(void*)) get_typeclasses_f,\
|
||||
};\
|
||||
return (Mirror){.tc = &tc, .data = x};\
|
||||
}
|
||||
|
||||
#define DECL_REFLECT(T)\
|
||||
extern const char* T##_get_typestring(T* self);\
|
||||
extern typeid T##_get_typeid(T* self);\
|
||||
extern List* T##_get_typeclasses(T* self);\
|
||||
impl_Mirror_for(T, T##_get_typestring, T##_get_typeid, T##_get_typeclasses)
|
||||
|
||||
|
||||
#define START_REFLECT(T)\
|
||||
const char* T##_get_typestring(T* self) {\
|
||||
static const char* const typestring = #T;\
|
||||
return typestring;\
|
||||
}\
|
||||
typeid T##_get_typeid(T* self) {\
|
||||
static char init_flag = 0;\
|
||||
static typeid id = 0;\
|
||||
if(!init_flag) {\
|
||||
init_flag = 1;\
|
||||
id = strhash(#T);\
|
||||
}\
|
||||
return id;\
|
||||
}\
|
||||
List* T##_get_typeclasses(T* self) {\
|
||||
static char init_flag = 0;\
|
||||
static List typeclasses;\
|
||||
if(!init_flag) {\
|
||||
init_flag = 1,\
|
||||
typeclasses = list_init(sizeof(MirroredTypeclass));\
|
||||
|
||||
#define REFLECT_TYPECLASS(T, TypeClass_)\
|
||||
list_add(&typeclasses, &(MirroredTypeclass){\
|
||||
.name_hash = strhash(#TypeClass_),\
|
||||
.typeclass_name = #TypeClass_,\
|
||||
.wrap = (void*(*const)(void*)) T##_as_##TypeClass_\
|
||||
});
|
||||
|
||||
#define END_REFLECT(T)\
|
||||
}\
|
||||
return &typeclasses;\
|
||||
}\
|
||||
|
||||
#endif // !_fencer_mirror_h
|
||||
|
|
@ -4,12 +4,11 @@
|
|||
#include "typeclass_helpers.h"
|
||||
#include "list.h"
|
||||
#include "transformable.h"
|
||||
#include "message_receiver.h"
|
||||
#include "mirror.h"
|
||||
|
||||
typedef struct Collider Collider;
|
||||
typedef struct Collision Collision;
|
||||
typedef struct RigidBody RigidBody;
|
||||
|
||||
typedef struct PhysicsEntity PhysicsEntity;
|
||||
|
||||
typedef struct IPhysicsEntity {
|
||||
|
|
@ -22,7 +21,7 @@ typedef struct PhysicsEntity {
|
|||
void* data;
|
||||
IPhysicsEntity const* tc;
|
||||
ITransformable const* transformable;
|
||||
IMessageReceiver const* message_receiver;
|
||||
IMirror const* mirror;
|
||||
} PhysicsEntity;
|
||||
|
||||
extern void physics_entity_debug_draw(PhysicsEntity self);
|
||||
|
|
@ -40,8 +39,8 @@ static inline PhysicsEntity T##_as_PhysicsEntity(T* x) {\
|
|||
.on_overlap = (void(*const)(void*,Collider*)) on_overlap_f,\
|
||||
};\
|
||||
Transformable transformable = T##_as_Transformable(x);\
|
||||
MessageReceiver receiver = T##_as_MessageReceiver(x);\
|
||||
return (PhysicsEntity){.data = x, .tc = &tc, .transformable = transformable.tc, .message_receiver = receiver.tc};\
|
||||
Mirror mirror = T##_as_Mirror(x);\
|
||||
return (PhysicsEntity){.data = x, .tc = &tc, .transformable = transformable.tc, .mirror = mirror.tc};\
|
||||
}
|
||||
|
||||
#endif // !_fencer_collidable_h
|
||||
|
|
|
|||
15
core/src/strutil.c
Normal file
15
core/src/strutil.c
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#include "strutil.h"
|
||||
#include "string.h"
|
||||
|
||||
uintptr_t strnhash(const char* s, size_t n) {
|
||||
static const size_t shift = sizeof(uintptr_t) * 8 - 4;
|
||||
uintptr_t hash = 0;
|
||||
for(size_t i = 0; i < n; ++i) {
|
||||
hash = ((hash << 4) | s[i]) ^ (((uintptr_t)0xF << shift) & hash);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
uintptr_t strhash(const char* s) {
|
||||
return strnhash(s, strlen(s));
|
||||
}
|
||||
10
core/src/strutil.h
Normal file
10
core/src/strutil.h
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef _fencer_strutil_h
|
||||
#define _fencer_strutil_h
|
||||
|
||||
#include "stdlib.h"
|
||||
#include "stdint.h"
|
||||
|
||||
extern uintptr_t strnhash(const char* s, size_t n);
|
||||
extern uintptr_t strhash(const char* s);
|
||||
|
||||
#endif // !_fencer_strutil_h
|
||||
Loading…
Add table
Add a link
Reference in a new issue