2023-10-11 19:01:06 +00:00
|
|
|
// C reflection: enums, functions, structs, members and anotations.
|
|
|
|
// - rlyeh, public domain
|
|
|
|
//
|
|
|
|
// @todo: nested structs? pointers in members?
|
|
|
|
// @todo: declare TYPEDEF(vec3, float[3]), TYPEDEF(mat4, vec4[4]/*float[16]*/)
|
|
|
|
|
2023-10-16 15:15:59 +00:00
|
|
|
#ifndef OBJTYPE
|
|
|
|
#define OBJTYPE(T) 0
|
2023-10-13 10:59:44 +00:00
|
|
|
#endif
|
2023-10-11 19:01:06 +00:00
|
|
|
|
2023-10-15 11:16:35 +00:00
|
|
|
typedef struct reflect_t {
|
2023-10-11 19:01:06 +00:00
|
|
|
unsigned id, objtype;
|
2023-10-16 20:07:29 +00:00
|
|
|
union {
|
2023-10-11 19:01:06 +00:00
|
|
|
unsigned sz;
|
2023-10-16 20:07:29 +00:00
|
|
|
unsigned member_offset;
|
|
|
|
unsigned enum_value;
|
|
|
|
};
|
2023-10-11 19:01:06 +00:00
|
|
|
const char *name;
|
|
|
|
const char *info;
|
|
|
|
void *addr;
|
|
|
|
unsigned parent;
|
|
|
|
const char *type;
|
2023-10-16 20:07:29 +00:00
|
|
|
unsigned bytes;
|
2023-10-15 11:16:35 +00:00
|
|
|
} reflect_t;
|
2023-10-11 19:01:06 +00:00
|
|
|
|
|
|
|
// inscribe api
|
|
|
|
|
2023-10-23 13:25:03 +00:00
|
|
|
#define ENUM(V, ...) \
|
|
|
|
enum_inscribe(#V,V, "E" __VA_ARGS__ " ("FILELINE")")
|
2023-10-11 19:01:06 +00:00
|
|
|
|
2023-10-23 13:25:03 +00:00
|
|
|
#define FUNCTION(F, ...) \
|
|
|
|
function_inscribe(#F,(void*)F, "F" __VA_ARGS__ " ("FILELINE")")
|
2023-10-11 19:01:06 +00:00
|
|
|
|
2023-10-23 13:25:03 +00:00
|
|
|
#define STRUCT(T, type, member, ...) \
|
|
|
|
struct_inscribe(#T,sizeof(T),OBJTYPE(T),"S" " ("FILELINE")"), \
|
|
|
|
type_inscribe(#type,sizeof(((T){0}).member),"T" __VA_ARGS__ " ("FILELINE")"), \
|
|
|
|
member_inscribe(#T, #member,(uintptr_t)&((T*)0)->member, "M" __VA_ARGS__ " ("FILELINE")", #type, sizeof(((T){0}).member) )
|
2023-10-11 19:01:06 +00:00
|
|
|
|
|
|
|
// find api
|
|
|
|
|
|
|
|
API unsigned enum_find(const char *E);
|
|
|
|
API void * function_find(const char *F);
|
|
|
|
|
2023-10-15 11:16:35 +00:00
|
|
|
API reflect_t member_find(const char *T, const char *M); /// find specific member
|
2023-10-16 20:07:29 +00:00
|
|
|
API void * member_findptr(void *obj, const char *T, const char *M); // @deprecate
|
2023-10-21 09:18:13 +00:00
|
|
|
API array(reflect_t)* members_find(const char *T);
|
2023-10-11 19:01:06 +00:00
|
|
|
|
|
|
|
// iterate members in a struct
|
|
|
|
|
|
|
|
#define each_member(T,R) \
|
2023-10-21 09:18:13 +00:00
|
|
|
(array(reflect_t) *found_ = members_find(T); found_; found_ = 0) \
|
2023-10-11 19:01:06 +00:00
|
|
|
for(int it_ = 0, end_ = array_count(*found_); it_ != end_; ++it_ ) \
|
2023-10-21 09:18:13 +00:00
|
|
|
for(reflect_t *R = &(*found_)[it_]; R; R = 0 )
|
2023-10-11 19:01:06 +00:00
|
|
|
|
|
|
|
// private api, still exposed
|
|
|
|
|
2023-10-20 17:55:43 +00:00
|
|
|
API void type_inscribe(const char *TY,unsigned TYsz,const char *infos);
|
|
|
|
API void enum_inscribe(const char *E,unsigned Eval,const char *infos);
|
|
|
|
API void struct_inscribe(const char *T,unsigned Tsz,unsigned OBJTYPEid, const char *infos);
|
|
|
|
API void member_inscribe(const char *T, const char *M,unsigned Msz, const char *infos, const char *type, unsigned bytes);
|
|
|
|
API void function_inscribe(const char *F,void *func,const char *infos);
|
2023-11-02 09:54:49 +00:00
|
|
|
API const char* symbol_naked(const char *s);
|
2023-10-11 19:01:06 +00:00
|
|
|
|
2023-10-23 13:25:03 +00:00
|
|
|
API int ui_reflect(const char *mask); // *, model* or NULL
|