sync fwk
parent
7ec8d2aba7
commit
d822f4f16d
2
_mirror
2
_mirror
|
@ -1 +1 @@
|
||||||
Subproject commit 15f0bafa8d6b428bea1a0931861e891e8d6017e7
|
Subproject commit a23d27f206b89c4971803fdc74ac0d3a7b65217a
|
|
@ -2457,8 +2457,9 @@ const char *type;
|
||||||
void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos);
|
void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos);
|
||||||
void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type);
|
void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type);
|
||||||
void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos);
|
void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos);
|
||||||
void reflected_printf(reflect_t *r);
|
void reflect_print(const char *symbol);
|
||||||
void reflected_printf_all();
|
void reflect_dump(const char *mask);
|
||||||
|
void reflect_init();
|
||||||
typedef unsigned handle;
|
typedef unsigned handle;
|
||||||
unsigned rgba( uint8_t r, uint8_t g, uint8_t b, uint8_t a );
|
unsigned rgba( uint8_t r, uint8_t g, uint8_t b, uint8_t a );
|
||||||
unsigned bgra( uint8_t b, uint8_t g, uint8_t r, uint8_t a );
|
unsigned bgra( uint8_t b, uint8_t g, uint8_t r, uint8_t a );
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
// hello ui: config, window, system, ui, video
|
||||||
|
// - rlyeh, public domain.
|
||||||
|
//
|
||||||
|
// Compile with:
|
||||||
|
// `make demos\01-ui.c` (windows)
|
||||||
|
// `sh MAKE.bat demos/01-ui.c` (linux, osx)
|
||||||
|
|
||||||
|
#include "v4k.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
window_create(80, 0);
|
||||||
|
window_title(__FILE__);
|
||||||
|
|
||||||
|
camera_t cam = camera();
|
||||||
|
|
||||||
|
vec3 route[] = {
|
||||||
|
vec3(0.0f, 0.0f, 5.0f),
|
||||||
|
vec3(0.0f, 0.0f, 10.0f),
|
||||||
|
vec3(0.0f, 2.0f, 20.0f),
|
||||||
|
vec3(0.0f, 8.0f, 30.0f),
|
||||||
|
vec3(0.0f, 12.0f, 40.0f),
|
||||||
|
vec3(0.0f, 0.0f, 80.0f),
|
||||||
|
};
|
||||||
|
|
||||||
|
#define route_len (sizeof route / sizeof route[0])
|
||||||
|
|
||||||
|
// app loop
|
||||||
|
while( window_swap() ) {
|
||||||
|
// input controls
|
||||||
|
if( input(KEY_ESC) ) break;
|
||||||
|
|
||||||
|
// fps camera
|
||||||
|
bool active = ui_active() || ui_hover() || gizmo_active() ? false : input(MOUSE_L) || input(MOUSE_M) || input(MOUSE_R);
|
||||||
|
if( active ) cam.speed = clampf(cam.speed + input_diff(MOUSE_W) / 10, 0.05f, 5.0f);
|
||||||
|
vec2 mouse = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active);
|
||||||
|
vec3 wasdecq = scale3(vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-(input(KEY_C)||input(KEY_Q)),input(KEY_W)-input(KEY_S)), cam.speed);
|
||||||
|
camera_moveby(&cam, wasdecq);
|
||||||
|
camera_fps(&cam, mouse.x,mouse.y);
|
||||||
|
window_cursor( !active );
|
||||||
|
|
||||||
|
ddraw_ground(0);
|
||||||
|
|
||||||
|
for (int i = 0; i < route_len; i++) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14241,6 +14241,22 @@ extern "C" {
|
||||||
#define EXPAND_ARGS(args) EXPAND_RETURN_COUNT args ///-
|
#define EXPAND_ARGS(args) EXPAND_RETURN_COUNT args ///-
|
||||||
#define EXPAND_RETURN_COUNT(_1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, _9_, count, ...) count ///-
|
#define EXPAND_RETURN_COUNT(_1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, _9_, count, ...) count ///-
|
||||||
|
|
||||||
|
// expands to the first argument
|
||||||
|
#define VA_FIRST(...) VA_F1RST(__VA_ARGS__, throwaway)
|
||||||
|
#define VA_F1RST(first, ...) first ///-
|
||||||
|
// if there's only one argument, expands to nothing. if there is more
|
||||||
|
// than one argument, expands to a comma followed by everything but
|
||||||
|
// the first argument. only supports up to 9 arguments but can be expanded.
|
||||||
|
#define VA_REST(...) VA_R3ST(VA_NUM(__VA_ARGS__), __VA_ARGS__)
|
||||||
|
#define VA_R3ST(qty, ...) VA_R3S7(qty, __VA_ARGS__) ///-
|
||||||
|
#define VA_R3S7(qty, ...) VA_R3S7_##qty(__VA_ARGS__) ///-
|
||||||
|
#define VA_R3S7_ONE(first) ///-
|
||||||
|
#define VA_R3S7_TWOORMORE(first, ...) , __VA_ARGS__ ///-
|
||||||
|
#define VA_NUM(...) VA_SELECT_10TH(__VA_ARGS__, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway) ///-
|
||||||
|
#define VA_SELECT_10TH(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, ...) A10
|
||||||
|
// VA_SPLIT() expands to A) 1 item OR B) 1 item + ',' + va_args[1..N]
|
||||||
|
#define VA_SPLIT(...) VA_FIRST(__VA_ARGS__) VA_REST(__VA_ARGS__)
|
||||||
|
|
||||||
#if is(cl) && !is(cpp)
|
#if is(cl) && !is(cpp)
|
||||||
#define INLINE __inline
|
#define INLINE __inline
|
||||||
#else
|
#else
|
||||||
|
@ -14265,6 +14281,21 @@ extern "C" {
|
||||||
// typedef union vec2 { float X,Y; }; vec2 a = {0,1}, b = vec2(0,1);
|
// typedef union vec2 { float X,Y; }; vec2 a = {0,1}, b = vec2(0,1);
|
||||||
#define C_CAST(type, ...) ( ifdef(c,(type),type) { __VA_ARGS__ } )
|
#define C_CAST(type, ...) ( ifdef(c,(type),type) { __VA_ARGS__ } )
|
||||||
|
|
||||||
|
// create a WARNING(...) macro
|
||||||
|
// usage: WARNING("this is displayed at compile time")
|
||||||
|
#if is(gcc)
|
||||||
|
# define WARNING(msg) WARN1NG( message( msg ) )
|
||||||
|
# define WARN1NG(msg) _Pragma(#msg)
|
||||||
|
#elif is(cl)
|
||||||
|
# define WARNING(msg) __pragma( message( msg ) )
|
||||||
|
#else
|
||||||
|
# define WARNING(msg)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// document todos and fixmes via compiler warnings
|
||||||
|
#define TODO(str) ifdef(debug,WARNING("TO DO: " str " (" FILELINE ")"))
|
||||||
|
#define FIXME(str) ifdef(debug,WARNING("FIXME: " str " (" FILELINE ")"))
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// autorun initializers for C
|
// autorun initializers for C
|
||||||
// - rlyeh, public domain
|
// - rlyeh, public domain
|
||||||
|
@ -14273,29 +14304,25 @@ extern "C" {
|
||||||
// note: XIU for C initializers, XCU for C++ initializers, XTU for C deinitializers
|
// note: XIU for C initializers, XCU for C++ initializers, XTU for C deinitializers
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#define AUTORUN \
|
#define AUTORUN_(fn) \
|
||||||
static void AUTORUN_U(f)(void); \
|
static void fn(void); \
|
||||||
static const int AUTORUN_J(AUTORUN_U(f),__1) = (AUTORUN_U(f)(), 1); \
|
static const int concat(fn,__1) = (fn(), 1); \
|
||||||
static void AUTORUN_U(f)(void)
|
static void fn(void)
|
||||||
#elif defined _MSC_VER && !defined(__clang__) // cl, but not clang-cl
|
#elif defined _MSC_VER && !defined(__clang__) // cl, but not clang-cl
|
||||||
#define AUTORUN \
|
#define AUTORUN_(fn) \
|
||||||
static void AUTORUN_U(f)(void); \
|
static void fn(void); \
|
||||||
static int AUTORUN_J(AUTORUN_U(f),__1) (){ AUTORUN_U(f)(); return 0; } \
|
static int concat(fn,__1) (){ fn(); return 0; } \
|
||||||
__pragma(section(".CRT$XIU", long, read)) \
|
__pragma(section(".CRT$XIU", long, read)) \
|
||||||
__declspec(allocate(".CRT$XIU")) \
|
__declspec(allocate(".CRT$XIU")) \
|
||||||
static int(* AUTORUN_J(AUTORUN_U(f),__2) )() = AUTORUN_J(AUTORUN_U(f),__1); \
|
static int(* concat(fn,__2) )() = concat(fn,__1); \
|
||||||
static void AUTORUN_U(f)(void)
|
static void fn(void)
|
||||||
#else // gcc,tcc,clang,clang-cl...
|
#else // gcc,tcc,clang,clang-cl...
|
||||||
#define AUTORUN \
|
#define AUTORUN_(fn) \
|
||||||
__attribute__((constructor)) \
|
__attribute__((constructor)) \
|
||||||
static void AUTORUN_U(f)(void)
|
static void fn(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// join + unique macro utils
|
#define AUTORUN AUTORUN_( concat(concat(concat(fn_L,__LINE__),_),__COUNTER__) )
|
||||||
|
|
||||||
#define AUTORUN_j(a, b) a##b
|
|
||||||
#define AUTORUN_J(a, b) AUTORUN_j(a, b)
|
|
||||||
#define AUTORUN_U(x) AUTORUN_J(x, __LINE__)
|
|
||||||
|
|
||||||
#if 0 // autorun demo
|
#if 0 // autorun demo
|
||||||
void byebye(void) { puts("seen after main()"); }
|
void byebye(void) { puts("seen after main()"); }
|
||||||
|
@ -16577,8 +16604,8 @@ extern API int profiler_enabled; ///-
|
||||||
// @todo: nested structs? pointers in members?
|
// @todo: nested structs? pointers in members?
|
||||||
// @todo: declare TYPEDEF(vec3, float[3]), TYPEDEF(mat4, vec4[4]/*float[16]*/)
|
// @todo: declare TYPEDEF(vec3, float[3]), TYPEDEF(mat4, vec4[4]/*float[16]*/)
|
||||||
|
|
||||||
#ifndef ifdef_objapi
|
#ifndef OBJTYPE
|
||||||
#define ifdef_objapi(T,...) __VA_ARGS__
|
#define OBJTYPE(T) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct reflect_t {
|
typedef struct reflect_t {
|
||||||
|
@ -16600,7 +16627,7 @@ typedef struct reflect_t {
|
||||||
function_inscribe(#F,intern(#F),(void*)F, function_annotations)
|
function_inscribe(#F,intern(#F),(void*)F, function_annotations)
|
||||||
|
|
||||||
#define STRUCT(T, type, member, member_annotations) \
|
#define STRUCT(T, type, member, member_annotations) \
|
||||||
struct_inscribe(#T,intern(#T),sizeof(T),ifdef(objapi,OBJTYPE_##T,0),NULL), \
|
struct_inscribe(#T,intern(#T),sizeof(T),OBJTYPE(T),NULL), \
|
||||||
type_inscribe(#type,intern(#type),sizeof(((T){0}).member),member_annotations), \
|
type_inscribe(#type,intern(#type),sizeof(((T){0}).member),member_annotations), \
|
||||||
member_inscribe(intern(#T), #member,intern(#member),(uintptr_t)&((T*)0)->member, member_annotations, #type )
|
member_inscribe(intern(#T), #member,intern(#member),(uintptr_t)&((T*)0)->member, member_annotations, #type )
|
||||||
|
|
||||||
|
@ -16628,8 +16655,9 @@ API void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,u
|
||||||
API void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type);
|
API void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type);
|
||||||
API void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos);
|
API void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos);
|
||||||
|
|
||||||
API void reflected_printf(reflect_t *r);
|
API void reflect_print(const char *symbol);
|
||||||
API void reflected_printf_all();
|
API void reflect_dump(const char *mask);
|
||||||
|
API void reflect_init();
|
||||||
#line 0
|
#line 0
|
||||||
|
|
||||||
#line 1 "engine/split/v4k_render.h"
|
#line 1 "engine/split/v4k_render.h"
|
||||||
|
@ -331987,9 +332015,9 @@ const struct in6_addr in6addr_loopback; /* ::1 */
|
||||||
#define chdir ifdef(cl, _chdir, chdir)
|
#define chdir ifdef(cl, _chdir, chdir)
|
||||||
#if is(cl) || is(tcc)
|
#if is(cl) || is(tcc)
|
||||||
#define ftruncate _chsize_s
|
#define ftruncate _chsize_s
|
||||||
#define flockfile ifdef(cl,_lock_file,(void))
|
|
||||||
#define funlockfile ifdef(cl,_unlock_file,(void))
|
|
||||||
#endif
|
#endif
|
||||||
|
#define flockfile ifdef(cl,_lock_file,ifdef(mingw,_lock_file,(void)))
|
||||||
|
#define funlockfile ifdef(cl,_unlock_file,ifdef(mingw,_unlock_file,(void)))
|
||||||
#else // gcc
|
#else // gcc
|
||||||
//#include <alloca.h> // mingw64 does not have it
|
//#include <alloca.h> // mingw64 does not have it
|
||||||
#include <strings.h> // strncasecmp
|
#include <strings.h> // strncasecmp
|
||||||
|
@ -343824,42 +343852,40 @@ AUTORUN {
|
||||||
static map(unsigned, reflect_t) reflects;
|
static map(unsigned, reflect_t) reflects;
|
||||||
static map(unsigned, array(reflect_t)) members;
|
static map(unsigned, array(reflect_t)) members;
|
||||||
|
|
||||||
void reflected_printf(reflect_t *r) {
|
void reflect_init() {
|
||||||
printf("name:%s info:'%s' id:%u objtype:%u sz:%u addr:%p parent:%u type:%s",
|
if(!reflects) map_init_int(reflects);
|
||||||
r->name ? r->name : "", r->info ? r->info : "", r->id, r->objtype, r->sz, r->addr, r->parent, r->type ? r->type : "");
|
|
||||||
}
|
|
||||||
void reflected_printf_all() {
|
|
||||||
for each_map_ptr(reflects, unsigned, k, reflect_t, p) {
|
|
||||||
reflected_printf(p);
|
|
||||||
puts("");
|
|
||||||
}
|
}
|
||||||
|
AUTORUN {
|
||||||
|
reflect_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos) {
|
void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos) {
|
||||||
if(!reflects) map_init_int(reflects);
|
reflect_init();
|
||||||
map_find_or_add(reflects, TYid, ((reflect_t){TYid, 0, TYsz, TY, infos}));
|
map_find_or_add(reflects, TYid, ((reflect_t){TYid, 0, TYsz, TY, infos}));
|
||||||
}
|
}
|
||||||
void enum_inscribe(const char *E,unsigned Eid,unsigned Eval,const char *infos) {
|
void enum_inscribe(const char *E,unsigned Eid,unsigned Eval,const char *infos) {
|
||||||
if(!reflects) map_init_int(reflects);
|
reflect_init();
|
||||||
map_find_or_add(reflects, Eid, ((reflect_t){Eid,0, Eval, E,infos}));
|
map_find_or_add(reflects, Eid, ((reflect_t){Eid,0, Eval, E,infos}));
|
||||||
}
|
}
|
||||||
unsigned enum_find(const char *E) {
|
unsigned enum_find(const char *E) {
|
||||||
|
reflect_init();
|
||||||
return map_find(reflects, intern(E))->sz;
|
return map_find(reflects, intern(E))->sz;
|
||||||
}
|
}
|
||||||
void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos) {
|
void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos) {
|
||||||
if(!reflects) map_init_int(reflects);
|
reflect_init();
|
||||||
map_find_or_add(reflects, Fid, ((reflect_t){Fid,0, 0, F,infos, func}));
|
map_find_or_add(reflects, Fid, ((reflect_t){Fid,0, 0, F,infos, func}));
|
||||||
reflect_t *found = map_find(reflects,Fid);
|
reflect_t *found = map_find(reflects,Fid);
|
||||||
}
|
}
|
||||||
void *function_find(const char *F) {
|
void *function_find(const char *F) {
|
||||||
|
reflect_init();
|
||||||
return map_find(reflects, intern(F))->addr;
|
return map_find(reflects, intern(F))->addr;
|
||||||
}
|
}
|
||||||
void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos) {
|
void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos) {
|
||||||
if(!reflects) map_init_int(reflects);
|
reflect_init();
|
||||||
map_find_or_add(reflects, Tid, ((reflect_t){Tid, OBJTYPEid, Tsz, T, infos}));
|
map_find_or_add(reflects, Tid, ((reflect_t){Tid, OBJTYPEid, Tsz, T, infos}));
|
||||||
}
|
}
|
||||||
void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type) {
|
void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type) {
|
||||||
if(!reflects) map_init_int(reflects);
|
reflect_init();
|
||||||
map_find_or_add(reflects, (Mid<<16)|Tid, ((reflect_t){Mid, 0, Msz, M, infos, NULL, Tid, type }));
|
map_find_or_add(reflects, (Mid<<16)|Tid, ((reflect_t){Mid, 0, Msz, M, infos, NULL, Tid, type }));
|
||||||
// add member separately as well
|
// add member separately as well
|
||||||
if(!members) map_init_int(members);
|
if(!members) map_init_int(members);
|
||||||
|
@ -343867,15 +343893,52 @@ void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, cons
|
||||||
array_push(*found, ((reflect_t){Mid, 0, Msz, M, infos, NULL, Tid, type }));
|
array_push(*found, ((reflect_t){Mid, 0, Msz, M, infos, NULL, Tid, type }));
|
||||||
}
|
}
|
||||||
reflect_t member_find(const char *T, const char *M) {
|
reflect_t member_find(const char *T, const char *M) {
|
||||||
|
reflect_init();
|
||||||
return *map_find(reflects, (intern(M)<<16)|intern(T));
|
return *map_find(reflects, (intern(M)<<16)|intern(T));
|
||||||
}
|
}
|
||||||
void *member_findptr(void *obj, const char *T, const char *M) {
|
void *member_findptr(void *obj, const char *T, const char *M) {
|
||||||
|
reflect_init();
|
||||||
return (char*)obj + member_find(T,M).sz;
|
return (char*)obj + member_find(T,M).sz;
|
||||||
}
|
}
|
||||||
array(reflect_t) members_find(const char *T) {
|
array(reflect_t) members_find(const char *T) {
|
||||||
|
reflect_init();
|
||||||
return *map_find(members, intern(T));
|
return *map_find(members, intern(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void reflect_dump(const char *mask) {
|
||||||
|
for each_map_ptr(reflects, unsigned, k, reflect_t, R) {
|
||||||
|
if( strmatchi(R->name, mask))
|
||||||
|
printf("name:%s info:'%s' id:%u objtype:%u sz:%u addr:%p parent:%u type:%s\n",
|
||||||
|
R->name ? R->name : "", R->info ? R->info : "", R->id, R->objtype, R->sz, R->addr, R->parent, R->type ? R->type : "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reflect_print_(const reflect_t *R) {
|
||||||
|
static __thread int tabs = 0;
|
||||||
|
printf("%*.s", 4 * (tabs++), "");
|
||||||
|
unsigned symbol_q = intern(R->name);
|
||||||
|
{
|
||||||
|
array(reflect_t) *RR = map_find(members, symbol_q);
|
||||||
|
/**/ if( RR ) { printf("struct %s: %s%s\n", R->name, R->info ? "// ":"", R->info ? R->info : ""); for each_array_ptr(*RR, reflect_t, it) reflect_print_(it); }
|
||||||
|
else if( R->addr ) printf("func %s(); %s%s\n", R->name, R->info ? "// ":"", R->info ? R->info : "");
|
||||||
|
else if( !R->parent ) printf("enum %s = %d; %s%s\n", R->name, R->sz, R->info ? "// ":"", R->info ? R->info : "");
|
||||||
|
else printf("%s %s; %s%s\n", R->type, R->name, R->info ? "// ":"", R->info ? R->info : "");
|
||||||
|
/*
|
||||||
|
ifdef(debug,
|
||||||
|
printf("%.*sname:%s info:'%s' id:%u objtype:%u sz:%u addr:%p parent:%u type:%s\n",
|
||||||
|
tabs, "", R->name ? R->name : "", R->info ? R->info : "", R->id, R->objtype, R->sz, R->addr, R->parent, R->type ? R->type : "");
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
--tabs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reflect_print(const char *symbol) {
|
||||||
|
reflect_t *found = map_find(reflects, intern(symbol));
|
||||||
|
if( found ) reflect_print_(found);
|
||||||
|
}
|
||||||
|
|
||||||
// -- tests
|
// -- tests
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -343889,7 +343952,7 @@ typedef struct MyVec4 {
|
||||||
float x,y,z,w;
|
float x,y,z,w;
|
||||||
} MyVec4;
|
} MyVec4;
|
||||||
|
|
||||||
ifdef(objapi, enum { OBJTYPE_MyVec4 = 0x100 });
|
enum { OBJTYPE_MyVec4 = 0x01 };
|
||||||
|
|
||||||
AUTOTEST {
|
AUTOTEST {
|
||||||
// register structs, enums and functions
|
// register structs, enums and functions
|
||||||
|
@ -343922,7 +343985,11 @@ AUTOTEST {
|
||||||
// printf("+%s MyVec4.%s // %s\n", R->type, R->name, R->info);
|
// printf("+%s MyVec4.%s // %s\n", R->type, R->name, R->info);
|
||||||
}
|
}
|
||||||
|
|
||||||
// reflected_printf_all();
|
// reflect_print("puts");
|
||||||
|
// reflect_print("MYVALUE0");
|
||||||
|
// reflect_print("MyVec4");
|
||||||
|
|
||||||
|
// reflect_dump("*");
|
||||||
}
|
}
|
||||||
#line 0
|
#line 0
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,9 @@ const struct in6_addr in6addr_loopback; /* ::1 */
|
||||||
#define chdir ifdef(cl, _chdir, chdir)
|
#define chdir ifdef(cl, _chdir, chdir)
|
||||||
#if is(cl) || is(tcc)
|
#if is(cl) || is(tcc)
|
||||||
#define ftruncate _chsize_s
|
#define ftruncate _chsize_s
|
||||||
#define flockfile ifdef(cl,_lock_file,(void))
|
|
||||||
#define funlockfile ifdef(cl,_unlock_file,(void))
|
|
||||||
#endif
|
#endif
|
||||||
|
#define flockfile ifdef(cl,_lock_file,ifdef(mingw,_lock_file,(void)))
|
||||||
|
#define funlockfile ifdef(cl,_unlock_file,ifdef(mingw,_unlock_file,(void)))
|
||||||
#else // gcc
|
#else // gcc
|
||||||
//#include <alloca.h> // mingw64 does not have it
|
//#include <alloca.h> // mingw64 does not have it
|
||||||
#include <strings.h> // strncasecmp
|
#include <strings.h> // strncasecmp
|
||||||
|
|
|
@ -210,6 +210,22 @@
|
||||||
#define EXPAND_ARGS(args) EXPAND_RETURN_COUNT args ///-
|
#define EXPAND_ARGS(args) EXPAND_RETURN_COUNT args ///-
|
||||||
#define EXPAND_RETURN_COUNT(_1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, _9_, count, ...) count ///-
|
#define EXPAND_RETURN_COUNT(_1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, _9_, count, ...) count ///-
|
||||||
|
|
||||||
|
// expands to the first argument
|
||||||
|
#define VA_FIRST(...) VA_F1RST(__VA_ARGS__, throwaway)
|
||||||
|
#define VA_F1RST(first, ...) first ///-
|
||||||
|
// if there's only one argument, expands to nothing. if there is more
|
||||||
|
// than one argument, expands to a comma followed by everything but
|
||||||
|
// the first argument. only supports up to 9 arguments but can be expanded.
|
||||||
|
#define VA_REST(...) VA_R3ST(VA_NUM(__VA_ARGS__), __VA_ARGS__)
|
||||||
|
#define VA_R3ST(qty, ...) VA_R3S7(qty, __VA_ARGS__) ///-
|
||||||
|
#define VA_R3S7(qty, ...) VA_R3S7_##qty(__VA_ARGS__) ///-
|
||||||
|
#define VA_R3S7_ONE(first) ///-
|
||||||
|
#define VA_R3S7_TWOORMORE(first, ...) , __VA_ARGS__ ///-
|
||||||
|
#define VA_NUM(...) VA_SELECT_10TH(__VA_ARGS__, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway) ///-
|
||||||
|
#define VA_SELECT_10TH(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, ...) A10
|
||||||
|
// VA_SPLIT() expands to A) 1 item OR B) 1 item + ',' + va_args[1..N]
|
||||||
|
#define VA_SPLIT(...) VA_FIRST(__VA_ARGS__) VA_REST(__VA_ARGS__)
|
||||||
|
|
||||||
#if is(cl) && !is(cpp)
|
#if is(cl) && !is(cpp)
|
||||||
#define INLINE __inline
|
#define INLINE __inline
|
||||||
#else
|
#else
|
||||||
|
@ -234,6 +250,21 @@
|
||||||
// typedef union vec2 { float X,Y; }; vec2 a = {0,1}, b = vec2(0,1);
|
// typedef union vec2 { float X,Y; }; vec2 a = {0,1}, b = vec2(0,1);
|
||||||
#define C_CAST(type, ...) ( ifdef(c,(type),type) { __VA_ARGS__ } )
|
#define C_CAST(type, ...) ( ifdef(c,(type),type) { __VA_ARGS__ } )
|
||||||
|
|
||||||
|
// create a WARNING(...) macro
|
||||||
|
// usage: WARNING("this is displayed at compile time")
|
||||||
|
#if is(gcc)
|
||||||
|
# define WARNING(msg) WARN1NG( message( msg ) )
|
||||||
|
# define WARN1NG(msg) _Pragma(#msg)
|
||||||
|
#elif is(cl)
|
||||||
|
# define WARNING(msg) __pragma( message( msg ) )
|
||||||
|
#else
|
||||||
|
# define WARNING(msg)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// document todos and fixmes via compiler warnings
|
||||||
|
#define TODO(str) ifdef(debug,WARNING("TO DO: " str " (" FILELINE ")"))
|
||||||
|
#define FIXME(str) ifdef(debug,WARNING("FIXME: " str " (" FILELINE ")"))
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// autorun initializers for C
|
// autorun initializers for C
|
||||||
// - rlyeh, public domain
|
// - rlyeh, public domain
|
||||||
|
@ -242,29 +273,25 @@
|
||||||
// note: XIU for C initializers, XCU for C++ initializers, XTU for C deinitializers
|
// note: XIU for C initializers, XCU for C++ initializers, XTU for C deinitializers
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#define AUTORUN \
|
#define AUTORUN_(fn) \
|
||||||
static void AUTORUN_U(f)(void); \
|
static void fn(void); \
|
||||||
static const int AUTORUN_J(AUTORUN_U(f),__1) = (AUTORUN_U(f)(), 1); \
|
static const int concat(fn,__1) = (fn(), 1); \
|
||||||
static void AUTORUN_U(f)(void)
|
static void fn(void)
|
||||||
#elif defined _MSC_VER && !defined(__clang__) // cl, but not clang-cl
|
#elif defined _MSC_VER && !defined(__clang__) // cl, but not clang-cl
|
||||||
#define AUTORUN \
|
#define AUTORUN_(fn) \
|
||||||
static void AUTORUN_U(f)(void); \
|
static void fn(void); \
|
||||||
static int AUTORUN_J(AUTORUN_U(f),__1) (){ AUTORUN_U(f)(); return 0; } \
|
static int concat(fn,__1) (){ fn(); return 0; } \
|
||||||
__pragma(section(".CRT$XIU", long, read)) \
|
__pragma(section(".CRT$XIU", long, read)) \
|
||||||
__declspec(allocate(".CRT$XIU")) \
|
__declspec(allocate(".CRT$XIU")) \
|
||||||
static int(* AUTORUN_J(AUTORUN_U(f),__2) )() = AUTORUN_J(AUTORUN_U(f),__1); \
|
static int(* concat(fn,__2) )() = concat(fn,__1); \
|
||||||
static void AUTORUN_U(f)(void)
|
static void fn(void)
|
||||||
#else // gcc,tcc,clang,clang-cl...
|
#else // gcc,tcc,clang,clang-cl...
|
||||||
#define AUTORUN \
|
#define AUTORUN_(fn) \
|
||||||
__attribute__((constructor)) \
|
__attribute__((constructor)) \
|
||||||
static void AUTORUN_U(f)(void)
|
static void fn(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// join + unique macro utils
|
#define AUTORUN AUTORUN_( concat(concat(concat(fn_L,__LINE__),_),__COUNTER__) )
|
||||||
|
|
||||||
#define AUTORUN_j(a, b) a##b
|
|
||||||
#define AUTORUN_J(a, b) AUTORUN_j(a, b)
|
|
||||||
#define AUTORUN_U(x) AUTORUN_J(x, __LINE__)
|
|
||||||
|
|
||||||
#if 0 // autorun demo
|
#if 0 // autorun demo
|
||||||
void byebye(void) { puts("seen after main()"); }
|
void byebye(void) { puts("seen after main()"); }
|
||||||
|
|
|
@ -7,42 +7,40 @@
|
||||||
static map(unsigned, reflect_t) reflects;
|
static map(unsigned, reflect_t) reflects;
|
||||||
static map(unsigned, array(reflect_t)) members;
|
static map(unsigned, array(reflect_t)) members;
|
||||||
|
|
||||||
void reflected_printf(reflect_t *r) {
|
void reflect_init() {
|
||||||
printf("name:%s info:'%s' id:%u objtype:%u sz:%u addr:%p parent:%u type:%s",
|
if(!reflects) map_init_int(reflects);
|
||||||
r->name ? r->name : "", r->info ? r->info : "", r->id, r->objtype, r->sz, r->addr, r->parent, r->type ? r->type : "");
|
|
||||||
}
|
|
||||||
void reflected_printf_all() {
|
|
||||||
for each_map_ptr(reflects, unsigned, k, reflect_t, p) {
|
|
||||||
reflected_printf(p);
|
|
||||||
puts("");
|
|
||||||
}
|
}
|
||||||
|
AUTORUN {
|
||||||
|
reflect_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos) {
|
void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos) {
|
||||||
if(!reflects) map_init_int(reflects);
|
reflect_init();
|
||||||
map_find_or_add(reflects, TYid, ((reflect_t){TYid, 0, TYsz, TY, infos}));
|
map_find_or_add(reflects, TYid, ((reflect_t){TYid, 0, TYsz, TY, infos}));
|
||||||
}
|
}
|
||||||
void enum_inscribe(const char *E,unsigned Eid,unsigned Eval,const char *infos) {
|
void enum_inscribe(const char *E,unsigned Eid,unsigned Eval,const char *infos) {
|
||||||
if(!reflects) map_init_int(reflects);
|
reflect_init();
|
||||||
map_find_or_add(reflects, Eid, ((reflect_t){Eid,0, Eval, E,infos}));
|
map_find_or_add(reflects, Eid, ((reflect_t){Eid,0, Eval, E,infos}));
|
||||||
}
|
}
|
||||||
unsigned enum_find(const char *E) {
|
unsigned enum_find(const char *E) {
|
||||||
|
reflect_init();
|
||||||
return map_find(reflects, intern(E))->sz;
|
return map_find(reflects, intern(E))->sz;
|
||||||
}
|
}
|
||||||
void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos) {
|
void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos) {
|
||||||
if(!reflects) map_init_int(reflects);
|
reflect_init();
|
||||||
map_find_or_add(reflects, Fid, ((reflect_t){Fid,0, 0, F,infos, func}));
|
map_find_or_add(reflects, Fid, ((reflect_t){Fid,0, 0, F,infos, func}));
|
||||||
reflect_t *found = map_find(reflects,Fid);
|
reflect_t *found = map_find(reflects,Fid);
|
||||||
}
|
}
|
||||||
void *function_find(const char *F) {
|
void *function_find(const char *F) {
|
||||||
|
reflect_init();
|
||||||
return map_find(reflects, intern(F))->addr;
|
return map_find(reflects, intern(F))->addr;
|
||||||
}
|
}
|
||||||
void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos) {
|
void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos) {
|
||||||
if(!reflects) map_init_int(reflects);
|
reflect_init();
|
||||||
map_find_or_add(reflects, Tid, ((reflect_t){Tid, OBJTYPEid, Tsz, T, infos}));
|
map_find_or_add(reflects, Tid, ((reflect_t){Tid, OBJTYPEid, Tsz, T, infos}));
|
||||||
}
|
}
|
||||||
void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type) {
|
void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type) {
|
||||||
if(!reflects) map_init_int(reflects);
|
reflect_init();
|
||||||
map_find_or_add(reflects, (Mid<<16)|Tid, ((reflect_t){Mid, 0, Msz, M, infos, NULL, Tid, type }));
|
map_find_or_add(reflects, (Mid<<16)|Tid, ((reflect_t){Mid, 0, Msz, M, infos, NULL, Tid, type }));
|
||||||
// add member separately as well
|
// add member separately as well
|
||||||
if(!members) map_init_int(members);
|
if(!members) map_init_int(members);
|
||||||
|
@ -50,15 +48,52 @@ void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, cons
|
||||||
array_push(*found, ((reflect_t){Mid, 0, Msz, M, infos, NULL, Tid, type }));
|
array_push(*found, ((reflect_t){Mid, 0, Msz, M, infos, NULL, Tid, type }));
|
||||||
}
|
}
|
||||||
reflect_t member_find(const char *T, const char *M) {
|
reflect_t member_find(const char *T, const char *M) {
|
||||||
|
reflect_init();
|
||||||
return *map_find(reflects, (intern(M)<<16)|intern(T));
|
return *map_find(reflects, (intern(M)<<16)|intern(T));
|
||||||
}
|
}
|
||||||
void *member_findptr(void *obj, const char *T, const char *M) {
|
void *member_findptr(void *obj, const char *T, const char *M) {
|
||||||
|
reflect_init();
|
||||||
return (char*)obj + member_find(T,M).sz;
|
return (char*)obj + member_find(T,M).sz;
|
||||||
}
|
}
|
||||||
array(reflect_t) members_find(const char *T) {
|
array(reflect_t) members_find(const char *T) {
|
||||||
|
reflect_init();
|
||||||
return *map_find(members, intern(T));
|
return *map_find(members, intern(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void reflect_dump(const char *mask) {
|
||||||
|
for each_map_ptr(reflects, unsigned, k, reflect_t, R) {
|
||||||
|
if( strmatchi(R->name, mask))
|
||||||
|
printf("name:%s info:'%s' id:%u objtype:%u sz:%u addr:%p parent:%u type:%s\n",
|
||||||
|
R->name ? R->name : "", R->info ? R->info : "", R->id, R->objtype, R->sz, R->addr, R->parent, R->type ? R->type : "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reflect_print_(const reflect_t *R) {
|
||||||
|
static __thread int tabs = 0;
|
||||||
|
printf("%*.s", 4 * (tabs++), "");
|
||||||
|
unsigned symbol_q = intern(R->name);
|
||||||
|
{
|
||||||
|
array(reflect_t) *RR = map_find(members, symbol_q);
|
||||||
|
/**/ if( RR ) { printf("struct %s: %s%s\n", R->name, R->info ? "// ":"", R->info ? R->info : ""); for each_array_ptr(*RR, reflect_t, it) reflect_print_(it); }
|
||||||
|
else if( R->addr ) printf("func %s(); %s%s\n", R->name, R->info ? "// ":"", R->info ? R->info : "");
|
||||||
|
else if( !R->parent ) printf("enum %s = %d; %s%s\n", R->name, R->sz, R->info ? "// ":"", R->info ? R->info : "");
|
||||||
|
else printf("%s %s; %s%s\n", R->type, R->name, R->info ? "// ":"", R->info ? R->info : "");
|
||||||
|
/*
|
||||||
|
ifdef(debug,
|
||||||
|
printf("%.*sname:%s info:'%s' id:%u objtype:%u sz:%u addr:%p parent:%u type:%s\n",
|
||||||
|
tabs, "", R->name ? R->name : "", R->info ? R->info : "", R->id, R->objtype, R->sz, R->addr, R->parent, R->type ? R->type : "");
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
--tabs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reflect_print(const char *symbol) {
|
||||||
|
reflect_t *found = map_find(reflects, intern(symbol));
|
||||||
|
if( found ) reflect_print_(found);
|
||||||
|
}
|
||||||
|
|
||||||
// -- tests
|
// -- tests
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -72,7 +107,7 @@ typedef struct MyVec4 {
|
||||||
float x,y,z,w;
|
float x,y,z,w;
|
||||||
} MyVec4;
|
} MyVec4;
|
||||||
|
|
||||||
ifdef(objapi, enum { OBJTYPE_MyVec4 = 0x100 });
|
enum { OBJTYPE_MyVec4 = 0x01 };
|
||||||
|
|
||||||
AUTOTEST {
|
AUTOTEST {
|
||||||
// register structs, enums and functions
|
// register structs, enums and functions
|
||||||
|
@ -105,5 +140,9 @@ AUTOTEST {
|
||||||
// printf("+%s MyVec4.%s // %s\n", R->type, R->name, R->info);
|
// printf("+%s MyVec4.%s // %s\n", R->type, R->name, R->info);
|
||||||
}
|
}
|
||||||
|
|
||||||
// reflected_printf_all();
|
// reflect_print("puts");
|
||||||
|
// reflect_print("MYVALUE0");
|
||||||
|
// reflect_print("MyVec4");
|
||||||
|
|
||||||
|
// reflect_dump("*");
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
// @todo: nested structs? pointers in members?
|
// @todo: nested structs? pointers in members?
|
||||||
// @todo: declare TYPEDEF(vec3, float[3]), TYPEDEF(mat4, vec4[4]/*float[16]*/)
|
// @todo: declare TYPEDEF(vec3, float[3]), TYPEDEF(mat4, vec4[4]/*float[16]*/)
|
||||||
|
|
||||||
#ifndef ifdef_objapi
|
#ifndef OBJTYPE
|
||||||
#define ifdef_objapi(T,...) __VA_ARGS__
|
#define OBJTYPE(T) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct reflect_t {
|
typedef struct reflect_t {
|
||||||
|
@ -27,7 +27,7 @@ typedef struct reflect_t {
|
||||||
function_inscribe(#F,intern(#F),(void*)F, function_annotations)
|
function_inscribe(#F,intern(#F),(void*)F, function_annotations)
|
||||||
|
|
||||||
#define STRUCT(T, type, member, member_annotations) \
|
#define STRUCT(T, type, member, member_annotations) \
|
||||||
struct_inscribe(#T,intern(#T),sizeof(T),ifdef(objapi,OBJTYPE_##T,0),NULL), \
|
struct_inscribe(#T,intern(#T),sizeof(T),OBJTYPE(T),NULL), \
|
||||||
type_inscribe(#type,intern(#type),sizeof(((T){0}).member),member_annotations), \
|
type_inscribe(#type,intern(#type),sizeof(((T){0}).member),member_annotations), \
|
||||||
member_inscribe(intern(#T), #member,intern(#member),(uintptr_t)&((T*)0)->member, member_annotations, #type )
|
member_inscribe(intern(#T), #member,intern(#member),(uintptr_t)&((T*)0)->member, member_annotations, #type )
|
||||||
|
|
||||||
|
@ -55,5 +55,6 @@ API void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,u
|
||||||
API void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type);
|
API void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type);
|
||||||
API void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos);
|
API void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos);
|
||||||
|
|
||||||
API void reflected_printf(reflect_t *r);
|
API void reflect_print(const char *symbol);
|
||||||
API void reflected_printf_all();
|
API void reflect_dump(const char *mask);
|
||||||
|
API void reflect_init();
|
||||||
|
|
73
engine/v4k.c
73
engine/v4k.c
|
@ -947,9 +947,9 @@ const struct in6_addr in6addr_loopback; /* ::1 */
|
||||||
#define chdir ifdef(cl, _chdir, chdir)
|
#define chdir ifdef(cl, _chdir, chdir)
|
||||||
#if is(cl) || is(tcc)
|
#if is(cl) || is(tcc)
|
||||||
#define ftruncate _chsize_s
|
#define ftruncate _chsize_s
|
||||||
#define flockfile ifdef(cl,_lock_file,(void))
|
|
||||||
#define funlockfile ifdef(cl,_unlock_file,(void))
|
|
||||||
#endif
|
#endif
|
||||||
|
#define flockfile ifdef(cl,_lock_file,ifdef(mingw,_lock_file,(void)))
|
||||||
|
#define funlockfile ifdef(cl,_unlock_file,ifdef(mingw,_unlock_file,(void)))
|
||||||
#else // gcc
|
#else // gcc
|
||||||
//#include <alloca.h> // mingw64 does not have it
|
//#include <alloca.h> // mingw64 does not have it
|
||||||
#include <strings.h> // strncasecmp
|
#include <strings.h> // strncasecmp
|
||||||
|
@ -12784,42 +12784,40 @@ AUTORUN {
|
||||||
static map(unsigned, reflect_t) reflects;
|
static map(unsigned, reflect_t) reflects;
|
||||||
static map(unsigned, array(reflect_t)) members;
|
static map(unsigned, array(reflect_t)) members;
|
||||||
|
|
||||||
void reflected_printf(reflect_t *r) {
|
void reflect_init() {
|
||||||
printf("name:%s info:'%s' id:%u objtype:%u sz:%u addr:%p parent:%u type:%s",
|
if(!reflects) map_init_int(reflects);
|
||||||
r->name ? r->name : "", r->info ? r->info : "", r->id, r->objtype, r->sz, r->addr, r->parent, r->type ? r->type : "");
|
|
||||||
}
|
|
||||||
void reflected_printf_all() {
|
|
||||||
for each_map_ptr(reflects, unsigned, k, reflect_t, p) {
|
|
||||||
reflected_printf(p);
|
|
||||||
puts("");
|
|
||||||
}
|
}
|
||||||
|
AUTORUN {
|
||||||
|
reflect_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos) {
|
void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos) {
|
||||||
if(!reflects) map_init_int(reflects);
|
reflect_init();
|
||||||
map_find_or_add(reflects, TYid, ((reflect_t){TYid, 0, TYsz, TY, infos}));
|
map_find_or_add(reflects, TYid, ((reflect_t){TYid, 0, TYsz, TY, infos}));
|
||||||
}
|
}
|
||||||
void enum_inscribe(const char *E,unsigned Eid,unsigned Eval,const char *infos) {
|
void enum_inscribe(const char *E,unsigned Eid,unsigned Eval,const char *infos) {
|
||||||
if(!reflects) map_init_int(reflects);
|
reflect_init();
|
||||||
map_find_or_add(reflects, Eid, ((reflect_t){Eid,0, Eval, E,infos}));
|
map_find_or_add(reflects, Eid, ((reflect_t){Eid,0, Eval, E,infos}));
|
||||||
}
|
}
|
||||||
unsigned enum_find(const char *E) {
|
unsigned enum_find(const char *E) {
|
||||||
|
reflect_init();
|
||||||
return map_find(reflects, intern(E))->sz;
|
return map_find(reflects, intern(E))->sz;
|
||||||
}
|
}
|
||||||
void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos) {
|
void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos) {
|
||||||
if(!reflects) map_init_int(reflects);
|
reflect_init();
|
||||||
map_find_or_add(reflects, Fid, ((reflect_t){Fid,0, 0, F,infos, func}));
|
map_find_or_add(reflects, Fid, ((reflect_t){Fid,0, 0, F,infos, func}));
|
||||||
reflect_t *found = map_find(reflects,Fid);
|
reflect_t *found = map_find(reflects,Fid);
|
||||||
}
|
}
|
||||||
void *function_find(const char *F) {
|
void *function_find(const char *F) {
|
||||||
|
reflect_init();
|
||||||
return map_find(reflects, intern(F))->addr;
|
return map_find(reflects, intern(F))->addr;
|
||||||
}
|
}
|
||||||
void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos) {
|
void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos) {
|
||||||
if(!reflects) map_init_int(reflects);
|
reflect_init();
|
||||||
map_find_or_add(reflects, Tid, ((reflect_t){Tid, OBJTYPEid, Tsz, T, infos}));
|
map_find_or_add(reflects, Tid, ((reflect_t){Tid, OBJTYPEid, Tsz, T, infos}));
|
||||||
}
|
}
|
||||||
void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type) {
|
void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type) {
|
||||||
if(!reflects) map_init_int(reflects);
|
reflect_init();
|
||||||
map_find_or_add(reflects, (Mid<<16)|Tid, ((reflect_t){Mid, 0, Msz, M, infos, NULL, Tid, type }));
|
map_find_or_add(reflects, (Mid<<16)|Tid, ((reflect_t){Mid, 0, Msz, M, infos, NULL, Tid, type }));
|
||||||
// add member separately as well
|
// add member separately as well
|
||||||
if(!members) map_init_int(members);
|
if(!members) map_init_int(members);
|
||||||
|
@ -12827,15 +12825,52 @@ void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, cons
|
||||||
array_push(*found, ((reflect_t){Mid, 0, Msz, M, infos, NULL, Tid, type }));
|
array_push(*found, ((reflect_t){Mid, 0, Msz, M, infos, NULL, Tid, type }));
|
||||||
}
|
}
|
||||||
reflect_t member_find(const char *T, const char *M) {
|
reflect_t member_find(const char *T, const char *M) {
|
||||||
|
reflect_init();
|
||||||
return *map_find(reflects, (intern(M)<<16)|intern(T));
|
return *map_find(reflects, (intern(M)<<16)|intern(T));
|
||||||
}
|
}
|
||||||
void *member_findptr(void *obj, const char *T, const char *M) {
|
void *member_findptr(void *obj, const char *T, const char *M) {
|
||||||
|
reflect_init();
|
||||||
return (char*)obj + member_find(T,M).sz;
|
return (char*)obj + member_find(T,M).sz;
|
||||||
}
|
}
|
||||||
array(reflect_t) members_find(const char *T) {
|
array(reflect_t) members_find(const char *T) {
|
||||||
|
reflect_init();
|
||||||
return *map_find(members, intern(T));
|
return *map_find(members, intern(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void reflect_dump(const char *mask) {
|
||||||
|
for each_map_ptr(reflects, unsigned, k, reflect_t, R) {
|
||||||
|
if( strmatchi(R->name, mask))
|
||||||
|
printf("name:%s info:'%s' id:%u objtype:%u sz:%u addr:%p parent:%u type:%s\n",
|
||||||
|
R->name ? R->name : "", R->info ? R->info : "", R->id, R->objtype, R->sz, R->addr, R->parent, R->type ? R->type : "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reflect_print_(const reflect_t *R) {
|
||||||
|
static __thread int tabs = 0;
|
||||||
|
printf("%*.s", 4 * (tabs++), "");
|
||||||
|
unsigned symbol_q = intern(R->name);
|
||||||
|
{
|
||||||
|
array(reflect_t) *RR = map_find(members, symbol_q);
|
||||||
|
/**/ if( RR ) { printf("struct %s: %s%s\n", R->name, R->info ? "// ":"", R->info ? R->info : ""); for each_array_ptr(*RR, reflect_t, it) reflect_print_(it); }
|
||||||
|
else if( R->addr ) printf("func %s(); %s%s\n", R->name, R->info ? "// ":"", R->info ? R->info : "");
|
||||||
|
else if( !R->parent ) printf("enum %s = %d; %s%s\n", R->name, R->sz, R->info ? "// ":"", R->info ? R->info : "");
|
||||||
|
else printf("%s %s; %s%s\n", R->type, R->name, R->info ? "// ":"", R->info ? R->info : "");
|
||||||
|
/*
|
||||||
|
ifdef(debug,
|
||||||
|
printf("%.*sname:%s info:'%s' id:%u objtype:%u sz:%u addr:%p parent:%u type:%s\n",
|
||||||
|
tabs, "", R->name ? R->name : "", R->info ? R->info : "", R->id, R->objtype, R->sz, R->addr, R->parent, R->type ? R->type : "");
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
--tabs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reflect_print(const char *symbol) {
|
||||||
|
reflect_t *found = map_find(reflects, intern(symbol));
|
||||||
|
if( found ) reflect_print_(found);
|
||||||
|
}
|
||||||
|
|
||||||
// -- tests
|
// -- tests
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -12849,7 +12884,7 @@ typedef struct MyVec4 {
|
||||||
float x,y,z,w;
|
float x,y,z,w;
|
||||||
} MyVec4;
|
} MyVec4;
|
||||||
|
|
||||||
ifdef(objapi, enum { OBJTYPE_MyVec4 = 0x100 });
|
enum { OBJTYPE_MyVec4 = 0x01 };
|
||||||
|
|
||||||
AUTOTEST {
|
AUTOTEST {
|
||||||
// register structs, enums and functions
|
// register structs, enums and functions
|
||||||
|
@ -12882,7 +12917,11 @@ AUTOTEST {
|
||||||
// printf("+%s MyVec4.%s // %s\n", R->type, R->name, R->info);
|
// printf("+%s MyVec4.%s // %s\n", R->type, R->name, R->info);
|
||||||
}
|
}
|
||||||
|
|
||||||
// reflected_printf_all();
|
// reflect_print("puts");
|
||||||
|
// reflect_print("MYVALUE0");
|
||||||
|
// reflect_print("MyVec4");
|
||||||
|
|
||||||
|
// reflect_dump("*");
|
||||||
}
|
}
|
||||||
#line 0
|
#line 0
|
||||||
|
|
||||||
|
|
70
engine/v4k.h
70
engine/v4k.h
|
@ -308,6 +308,22 @@ extern "C" {
|
||||||
#define EXPAND_ARGS(args) EXPAND_RETURN_COUNT args ///-
|
#define EXPAND_ARGS(args) EXPAND_RETURN_COUNT args ///-
|
||||||
#define EXPAND_RETURN_COUNT(_1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, _9_, count, ...) count ///-
|
#define EXPAND_RETURN_COUNT(_1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, _9_, count, ...) count ///-
|
||||||
|
|
||||||
|
// expands to the first argument
|
||||||
|
#define VA_FIRST(...) VA_F1RST(__VA_ARGS__, throwaway)
|
||||||
|
#define VA_F1RST(first, ...) first ///-
|
||||||
|
// if there's only one argument, expands to nothing. if there is more
|
||||||
|
// than one argument, expands to a comma followed by everything but
|
||||||
|
// the first argument. only supports up to 9 arguments but can be expanded.
|
||||||
|
#define VA_REST(...) VA_R3ST(VA_NUM(__VA_ARGS__), __VA_ARGS__)
|
||||||
|
#define VA_R3ST(qty, ...) VA_R3S7(qty, __VA_ARGS__) ///-
|
||||||
|
#define VA_R3S7(qty, ...) VA_R3S7_##qty(__VA_ARGS__) ///-
|
||||||
|
#define VA_R3S7_ONE(first) ///-
|
||||||
|
#define VA_R3S7_TWOORMORE(first, ...) , __VA_ARGS__ ///-
|
||||||
|
#define VA_NUM(...) VA_SELECT_10TH(__VA_ARGS__, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway) ///-
|
||||||
|
#define VA_SELECT_10TH(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, ...) A10
|
||||||
|
// VA_SPLIT() expands to A) 1 item OR B) 1 item + ',' + va_args[1..N]
|
||||||
|
#define VA_SPLIT(...) VA_FIRST(__VA_ARGS__) VA_REST(__VA_ARGS__)
|
||||||
|
|
||||||
#if is(cl) && !is(cpp)
|
#if is(cl) && !is(cpp)
|
||||||
#define INLINE __inline
|
#define INLINE __inline
|
||||||
#else
|
#else
|
||||||
|
@ -332,6 +348,21 @@ extern "C" {
|
||||||
// typedef union vec2 { float X,Y; }; vec2 a = {0,1}, b = vec2(0,1);
|
// typedef union vec2 { float X,Y; }; vec2 a = {0,1}, b = vec2(0,1);
|
||||||
#define C_CAST(type, ...) ( ifdef(c,(type),type) { __VA_ARGS__ } )
|
#define C_CAST(type, ...) ( ifdef(c,(type),type) { __VA_ARGS__ } )
|
||||||
|
|
||||||
|
// create a WARNING(...) macro
|
||||||
|
// usage: WARNING("this is displayed at compile time")
|
||||||
|
#if is(gcc)
|
||||||
|
# define WARNING(msg) WARN1NG( message( msg ) )
|
||||||
|
# define WARN1NG(msg) _Pragma(#msg)
|
||||||
|
#elif is(cl)
|
||||||
|
# define WARNING(msg) __pragma( message( msg ) )
|
||||||
|
#else
|
||||||
|
# define WARNING(msg)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// document todos and fixmes via compiler warnings
|
||||||
|
#define TODO(str) ifdef(debug,WARNING("TO DO: " str " (" FILELINE ")"))
|
||||||
|
#define FIXME(str) ifdef(debug,WARNING("FIXME: " str " (" FILELINE ")"))
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// autorun initializers for C
|
// autorun initializers for C
|
||||||
// - rlyeh, public domain
|
// - rlyeh, public domain
|
||||||
|
@ -340,29 +371,25 @@ extern "C" {
|
||||||
// note: XIU for C initializers, XCU for C++ initializers, XTU for C deinitializers
|
// note: XIU for C initializers, XCU for C++ initializers, XTU for C deinitializers
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#define AUTORUN \
|
#define AUTORUN_(fn) \
|
||||||
static void AUTORUN_U(f)(void); \
|
static void fn(void); \
|
||||||
static const int AUTORUN_J(AUTORUN_U(f),__1) = (AUTORUN_U(f)(), 1); \
|
static const int concat(fn,__1) = (fn(), 1); \
|
||||||
static void AUTORUN_U(f)(void)
|
static void fn(void)
|
||||||
#elif defined _MSC_VER && !defined(__clang__) // cl, but not clang-cl
|
#elif defined _MSC_VER && !defined(__clang__) // cl, but not clang-cl
|
||||||
#define AUTORUN \
|
#define AUTORUN_(fn) \
|
||||||
static void AUTORUN_U(f)(void); \
|
static void fn(void); \
|
||||||
static int AUTORUN_J(AUTORUN_U(f),__1) (){ AUTORUN_U(f)(); return 0; } \
|
static int concat(fn,__1) (){ fn(); return 0; } \
|
||||||
__pragma(section(".CRT$XIU", long, read)) \
|
__pragma(section(".CRT$XIU", long, read)) \
|
||||||
__declspec(allocate(".CRT$XIU")) \
|
__declspec(allocate(".CRT$XIU")) \
|
||||||
static int(* AUTORUN_J(AUTORUN_U(f),__2) )() = AUTORUN_J(AUTORUN_U(f),__1); \
|
static int(* concat(fn,__2) )() = concat(fn,__1); \
|
||||||
static void AUTORUN_U(f)(void)
|
static void fn(void)
|
||||||
#else // gcc,tcc,clang,clang-cl...
|
#else // gcc,tcc,clang,clang-cl...
|
||||||
#define AUTORUN \
|
#define AUTORUN_(fn) \
|
||||||
__attribute__((constructor)) \
|
__attribute__((constructor)) \
|
||||||
static void AUTORUN_U(f)(void)
|
static void fn(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// join + unique macro utils
|
#define AUTORUN AUTORUN_( concat(concat(concat(fn_L,__LINE__),_),__COUNTER__) )
|
||||||
|
|
||||||
#define AUTORUN_j(a, b) a##b
|
|
||||||
#define AUTORUN_J(a, b) AUTORUN_j(a, b)
|
|
||||||
#define AUTORUN_U(x) AUTORUN_J(x, __LINE__)
|
|
||||||
|
|
||||||
#if 0 // autorun demo
|
#if 0 // autorun demo
|
||||||
void byebye(void) { puts("seen after main()"); }
|
void byebye(void) { puts("seen after main()"); }
|
||||||
|
@ -2644,8 +2671,8 @@ extern API int profiler_enabled; ///-
|
||||||
// @todo: nested structs? pointers in members?
|
// @todo: nested structs? pointers in members?
|
||||||
// @todo: declare TYPEDEF(vec3, float[3]), TYPEDEF(mat4, vec4[4]/*float[16]*/)
|
// @todo: declare TYPEDEF(vec3, float[3]), TYPEDEF(mat4, vec4[4]/*float[16]*/)
|
||||||
|
|
||||||
#ifndef ifdef_objapi
|
#ifndef OBJTYPE
|
||||||
#define ifdef_objapi(T,...) __VA_ARGS__
|
#define OBJTYPE(T) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct reflect_t {
|
typedef struct reflect_t {
|
||||||
|
@ -2667,7 +2694,7 @@ typedef struct reflect_t {
|
||||||
function_inscribe(#F,intern(#F),(void*)F, function_annotations)
|
function_inscribe(#F,intern(#F),(void*)F, function_annotations)
|
||||||
|
|
||||||
#define STRUCT(T, type, member, member_annotations) \
|
#define STRUCT(T, type, member, member_annotations) \
|
||||||
struct_inscribe(#T,intern(#T),sizeof(T),ifdef(objapi,OBJTYPE_##T,0),NULL), \
|
struct_inscribe(#T,intern(#T),sizeof(T),OBJTYPE(T),NULL), \
|
||||||
type_inscribe(#type,intern(#type),sizeof(((T){0}).member),member_annotations), \
|
type_inscribe(#type,intern(#type),sizeof(((T){0}).member),member_annotations), \
|
||||||
member_inscribe(intern(#T), #member,intern(#member),(uintptr_t)&((T*)0)->member, member_annotations, #type )
|
member_inscribe(intern(#T), #member,intern(#member),(uintptr_t)&((T*)0)->member, member_annotations, #type )
|
||||||
|
|
||||||
|
@ -2695,8 +2722,9 @@ API void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,u
|
||||||
API void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type);
|
API void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type);
|
||||||
API void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos);
|
API void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos);
|
||||||
|
|
||||||
API void reflected_printf(reflect_t *r);
|
API void reflect_print(const char *symbol);
|
||||||
API void reflected_printf_all();
|
API void reflect_dump(const char *mask);
|
||||||
|
API void reflect_init();
|
||||||
#line 0
|
#line 0
|
||||||
|
|
||||||
#line 1 "engine/split/v4k_render.h"
|
#line 1 "engine/split/v4k_render.h"
|
||||||
|
|
Loading…
Reference in New Issue