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 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 reflected_printf(reflect_t *r);
|
||||
void reflected_printf_all();
|
||||
void reflect_print(const char *symbol);
|
||||
void reflect_dump(const char *mask);
|
||||
void reflect_init();
|
||||
typedef unsigned handle;
|
||||
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 );
|
||||
|
|
|
@ -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_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)
|
||||
#define INLINE __inline
|
||||
#else
|
||||
|
@ -14265,6 +14281,21 @@ extern "C" {
|
|||
// typedef union vec2 { float X,Y; }; vec2 a = {0,1}, b = vec2(0,1);
|
||||
#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
|
||||
// - rlyeh, public domain
|
||||
|
@ -14273,29 +14304,25 @@ extern "C" {
|
|||
// note: XIU for C initializers, XCU for C++ initializers, XTU for C deinitializers
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define AUTORUN \
|
||||
static void AUTORUN_U(f)(void); \
|
||||
static const int AUTORUN_J(AUTORUN_U(f),__1) = (AUTORUN_U(f)(), 1); \
|
||||
static void AUTORUN_U(f)(void)
|
||||
#define AUTORUN_(fn) \
|
||||
static void fn(void); \
|
||||
static const int concat(fn,__1) = (fn(), 1); \
|
||||
static void fn(void)
|
||||
#elif defined _MSC_VER && !defined(__clang__) // cl, but not clang-cl
|
||||
#define AUTORUN \
|
||||
static void AUTORUN_U(f)(void); \
|
||||
static int AUTORUN_J(AUTORUN_U(f),__1) (){ AUTORUN_U(f)(); return 0; } \
|
||||
#define AUTORUN_(fn) \
|
||||
static void fn(void); \
|
||||
static int concat(fn,__1) (){ fn(); return 0; } \
|
||||
__pragma(section(".CRT$XIU", long, read)) \
|
||||
__declspec(allocate(".CRT$XIU")) \
|
||||
static int(* AUTORUN_J(AUTORUN_U(f),__2) )() = AUTORUN_J(AUTORUN_U(f),__1); \
|
||||
static void AUTORUN_U(f)(void)
|
||||
static int(* concat(fn,__2) )() = concat(fn,__1); \
|
||||
static void fn(void)
|
||||
#else // gcc,tcc,clang,clang-cl...
|
||||
#define AUTORUN \
|
||||
#define AUTORUN_(fn) \
|
||||
__attribute__((constructor)) \
|
||||
static void AUTORUN_U(f)(void)
|
||||
static void fn(void)
|
||||
#endif
|
||||
|
||||
// join + unique macro utils
|
||||
|
||||
#define AUTORUN_j(a, b) a##b
|
||||
#define AUTORUN_J(a, b) AUTORUN_j(a, b)
|
||||
#define AUTORUN_U(x) AUTORUN_J(x, __LINE__)
|
||||
#define AUTORUN AUTORUN_( concat(concat(concat(fn_L,__LINE__),_),__COUNTER__) )
|
||||
|
||||
#if 0 // autorun demo
|
||||
void byebye(void) { puts("seen after main()"); }
|
||||
|
@ -16577,8 +16604,8 @@ extern API int profiler_enabled; ///-
|
|||
// @todo: nested structs? pointers in members?
|
||||
// @todo: declare TYPEDEF(vec3, float[3]), TYPEDEF(mat4, vec4[4]/*float[16]*/)
|
||||
|
||||
#ifndef ifdef_objapi
|
||||
#define ifdef_objapi(T,...) __VA_ARGS__
|
||||
#ifndef OBJTYPE
|
||||
#define OBJTYPE(T) 0
|
||||
#endif
|
||||
|
||||
typedef struct reflect_t {
|
||||
|
@ -16600,7 +16627,7 @@ typedef struct reflect_t {
|
|||
function_inscribe(#F,intern(#F),(void*)F, function_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), \
|
||||
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 function_inscribe(const char *F,unsigned Fid,void *func,const char *infos);
|
||||
|
||||
API void reflected_printf(reflect_t *r);
|
||||
API void reflected_printf_all();
|
||||
API void reflect_print(const char *symbol);
|
||||
API void reflect_dump(const char *mask);
|
||||
API void reflect_init();
|
||||
#line 0
|
||||
|
||||
#line 1 "engine/split/v4k_render.h"
|
||||
|
@ -331987,9 +332015,9 @@ const struct in6_addr in6addr_loopback; /* ::1 */
|
|||
#define chdir ifdef(cl, _chdir, chdir)
|
||||
#if is(cl) || is(tcc)
|
||||
#define ftruncate _chsize_s
|
||||
#define flockfile ifdef(cl,_lock_file,(void))
|
||||
#define funlockfile ifdef(cl,_unlock_file,(void))
|
||||
#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
|
||||
//#include <alloca.h> // mingw64 does not have it
|
||||
#include <strings.h> // strncasecmp
|
||||
|
@ -343824,42 +343852,40 @@ AUTORUN {
|
|||
static map(unsigned, reflect_t) reflects;
|
||||
static map(unsigned, array(reflect_t)) members;
|
||||
|
||||
void reflected_printf(reflect_t *r) {
|
||||
printf("name:%s info:'%s' id:%u objtype:%u sz:%u addr:%p parent:%u type:%s",
|
||||
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("");
|
||||
void reflect_init() {
|
||||
if(!reflects) map_init_int(reflects);
|
||||
}
|
||||
AUTORUN {
|
||||
reflect_init();
|
||||
}
|
||||
|
||||
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}));
|
||||
}
|
||||
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}));
|
||||
}
|
||||
unsigned enum_find(const char *E) {
|
||||
reflect_init();
|
||||
return map_find(reflects, intern(E))->sz;
|
||||
}
|
||||
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}));
|
||||
reflect_t *found = map_find(reflects,Fid);
|
||||
}
|
||||
void *function_find(const char *F) {
|
||||
reflect_init();
|
||||
return map_find(reflects, intern(F))->addr;
|
||||
}
|
||||
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}));
|
||||
}
|
||||
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 }));
|
||||
// add member separately as well
|
||||
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 }));
|
||||
}
|
||||
reflect_t member_find(const char *T, const char *M) {
|
||||
reflect_init();
|
||||
return *map_find(reflects, (intern(M)<<16)|intern(T));
|
||||
}
|
||||
void *member_findptr(void *obj, const char *T, const char *M) {
|
||||
reflect_init();
|
||||
return (char*)obj + member_find(T,M).sz;
|
||||
}
|
||||
array(reflect_t) members_find(const char *T) {
|
||||
reflect_init();
|
||||
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
|
||||
|
||||
enum {
|
||||
|
@ -343889,7 +343952,7 @@ typedef struct MyVec4 {
|
|||
float x,y,z,w;
|
||||
} MyVec4;
|
||||
|
||||
ifdef(objapi, enum { OBJTYPE_MyVec4 = 0x100 });
|
||||
enum { OBJTYPE_MyVec4 = 0x01 };
|
||||
|
||||
AUTOTEST {
|
||||
// register structs, enums and functions
|
||||
|
@ -343922,7 +343985,11 @@ AUTOTEST {
|
|||
// 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
|
||||
|
||||
|
|
|
@ -31,9 +31,9 @@ const struct in6_addr in6addr_loopback; /* ::1 */
|
|||
#define chdir ifdef(cl, _chdir, chdir)
|
||||
#if is(cl) || is(tcc)
|
||||
#define ftruncate _chsize_s
|
||||
#define flockfile ifdef(cl,_lock_file,(void))
|
||||
#define funlockfile ifdef(cl,_unlock_file,(void))
|
||||
#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
|
||||
//#include <alloca.h> // mingw64 does not have it
|
||||
#include <strings.h> // strncasecmp
|
||||
|
|
|
@ -210,6 +210,22 @@
|
|||
#define EXPAND_ARGS(args) EXPAND_RETURN_COUNT args ///-
|
||||
#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)
|
||||
#define INLINE __inline
|
||||
#else
|
||||
|
@ -234,6 +250,21 @@
|
|||
// typedef union vec2 { float X,Y; }; vec2 a = {0,1}, b = vec2(0,1);
|
||||
#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
|
||||
// - rlyeh, public domain
|
||||
|
@ -242,29 +273,25 @@
|
|||
// note: XIU for C initializers, XCU for C++ initializers, XTU for C deinitializers
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define AUTORUN \
|
||||
static void AUTORUN_U(f)(void); \
|
||||
static const int AUTORUN_J(AUTORUN_U(f),__1) = (AUTORUN_U(f)(), 1); \
|
||||
static void AUTORUN_U(f)(void)
|
||||
#define AUTORUN_(fn) \
|
||||
static void fn(void); \
|
||||
static const int concat(fn,__1) = (fn(), 1); \
|
||||
static void fn(void)
|
||||
#elif defined _MSC_VER && !defined(__clang__) // cl, but not clang-cl
|
||||
#define AUTORUN \
|
||||
static void AUTORUN_U(f)(void); \
|
||||
static int AUTORUN_J(AUTORUN_U(f),__1) (){ AUTORUN_U(f)(); return 0; } \
|
||||
#define AUTORUN_(fn) \
|
||||
static void fn(void); \
|
||||
static int concat(fn,__1) (){ fn(); return 0; } \
|
||||
__pragma(section(".CRT$XIU", long, read)) \
|
||||
__declspec(allocate(".CRT$XIU")) \
|
||||
static int(* AUTORUN_J(AUTORUN_U(f),__2) )() = AUTORUN_J(AUTORUN_U(f),__1); \
|
||||
static void AUTORUN_U(f)(void)
|
||||
static int(* concat(fn,__2) )() = concat(fn,__1); \
|
||||
static void fn(void)
|
||||
#else // gcc,tcc,clang,clang-cl...
|
||||
#define AUTORUN \
|
||||
#define AUTORUN_(fn) \
|
||||
__attribute__((constructor)) \
|
||||
static void AUTORUN_U(f)(void)
|
||||
static void fn(void)
|
||||
#endif
|
||||
|
||||
// join + unique macro utils
|
||||
|
||||
#define AUTORUN_j(a, b) a##b
|
||||
#define AUTORUN_J(a, b) AUTORUN_j(a, b)
|
||||
#define AUTORUN_U(x) AUTORUN_J(x, __LINE__)
|
||||
#define AUTORUN AUTORUN_( concat(concat(concat(fn_L,__LINE__),_),__COUNTER__) )
|
||||
|
||||
#if 0 // autorun demo
|
||||
void byebye(void) { puts("seen after main()"); }
|
||||
|
|
|
@ -7,42 +7,40 @@
|
|||
static map(unsigned, reflect_t) reflects;
|
||||
static map(unsigned, array(reflect_t)) members;
|
||||
|
||||
void reflected_printf(reflect_t *r) {
|
||||
printf("name:%s info:'%s' id:%u objtype:%u sz:%u addr:%p parent:%u type:%s",
|
||||
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("");
|
||||
void reflect_init() {
|
||||
if(!reflects) map_init_int(reflects);
|
||||
}
|
||||
AUTORUN {
|
||||
reflect_init();
|
||||
}
|
||||
|
||||
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}));
|
||||
}
|
||||
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}));
|
||||
}
|
||||
unsigned enum_find(const char *E) {
|
||||
reflect_init();
|
||||
return map_find(reflects, intern(E))->sz;
|
||||
}
|
||||
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}));
|
||||
reflect_t *found = map_find(reflects,Fid);
|
||||
}
|
||||
void *function_find(const char *F) {
|
||||
reflect_init();
|
||||
return map_find(reflects, intern(F))->addr;
|
||||
}
|
||||
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}));
|
||||
}
|
||||
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 }));
|
||||
// add member separately as well
|
||||
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 }));
|
||||
}
|
||||
reflect_t member_find(const char *T, const char *M) {
|
||||
reflect_init();
|
||||
return *map_find(reflects, (intern(M)<<16)|intern(T));
|
||||
}
|
||||
void *member_findptr(void *obj, const char *T, const char *M) {
|
||||
reflect_init();
|
||||
return (char*)obj + member_find(T,M).sz;
|
||||
}
|
||||
array(reflect_t) members_find(const char *T) {
|
||||
reflect_init();
|
||||
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
|
||||
|
||||
enum {
|
||||
|
@ -72,7 +107,7 @@ typedef struct MyVec4 {
|
|||
float x,y,z,w;
|
||||
} MyVec4;
|
||||
|
||||
ifdef(objapi, enum { OBJTYPE_MyVec4 = 0x100 });
|
||||
enum { OBJTYPE_MyVec4 = 0x01 };
|
||||
|
||||
AUTOTEST {
|
||||
// register structs, enums and functions
|
||||
|
@ -105,5 +140,9 @@ AUTOTEST {
|
|||
// 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: declare TYPEDEF(vec3, float[3]), TYPEDEF(mat4, vec4[4]/*float[16]*/)
|
||||
|
||||
#ifndef ifdef_objapi
|
||||
#define ifdef_objapi(T,...) __VA_ARGS__
|
||||
#ifndef OBJTYPE
|
||||
#define OBJTYPE(T) 0
|
||||
#endif
|
||||
|
||||
typedef struct reflect_t {
|
||||
|
@ -27,7 +27,7 @@ typedef struct reflect_t {
|
|||
function_inscribe(#F,intern(#F),(void*)F, function_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), \
|
||||
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 function_inscribe(const char *F,unsigned Fid,void *func,const char *infos);
|
||||
|
||||
API void reflected_printf(reflect_t *r);
|
||||
API void reflected_printf_all();
|
||||
API void reflect_print(const char *symbol);
|
||||
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)
|
||||
#if is(cl) || is(tcc)
|
||||
#define ftruncate _chsize_s
|
||||
#define flockfile ifdef(cl,_lock_file,(void))
|
||||
#define funlockfile ifdef(cl,_unlock_file,(void))
|
||||
#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
|
||||
//#include <alloca.h> // mingw64 does not have it
|
||||
#include <strings.h> // strncasecmp
|
||||
|
@ -12784,42 +12784,40 @@ AUTORUN {
|
|||
static map(unsigned, reflect_t) reflects;
|
||||
static map(unsigned, array(reflect_t)) members;
|
||||
|
||||
void reflected_printf(reflect_t *r) {
|
||||
printf("name:%s info:'%s' id:%u objtype:%u sz:%u addr:%p parent:%u type:%s",
|
||||
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("");
|
||||
void reflect_init() {
|
||||
if(!reflects) map_init_int(reflects);
|
||||
}
|
||||
AUTORUN {
|
||||
reflect_init();
|
||||
}
|
||||
|
||||
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}));
|
||||
}
|
||||
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}));
|
||||
}
|
||||
unsigned enum_find(const char *E) {
|
||||
reflect_init();
|
||||
return map_find(reflects, intern(E))->sz;
|
||||
}
|
||||
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}));
|
||||
reflect_t *found = map_find(reflects,Fid);
|
||||
}
|
||||
void *function_find(const char *F) {
|
||||
reflect_init();
|
||||
return map_find(reflects, intern(F))->addr;
|
||||
}
|
||||
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}));
|
||||
}
|
||||
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 }));
|
||||
// add member separately as well
|
||||
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 }));
|
||||
}
|
||||
reflect_t member_find(const char *T, const char *M) {
|
||||
reflect_init();
|
||||
return *map_find(reflects, (intern(M)<<16)|intern(T));
|
||||
}
|
||||
void *member_findptr(void *obj, const char *T, const char *M) {
|
||||
reflect_init();
|
||||
return (char*)obj + member_find(T,M).sz;
|
||||
}
|
||||
array(reflect_t) members_find(const char *T) {
|
||||
reflect_init();
|
||||
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
|
||||
|
||||
enum {
|
||||
|
@ -12849,7 +12884,7 @@ typedef struct MyVec4 {
|
|||
float x,y,z,w;
|
||||
} MyVec4;
|
||||
|
||||
ifdef(objapi, enum { OBJTYPE_MyVec4 = 0x100 });
|
||||
enum { OBJTYPE_MyVec4 = 0x01 };
|
||||
|
||||
AUTOTEST {
|
||||
// register structs, enums and functions
|
||||
|
@ -12882,7 +12917,11 @@ AUTOTEST {
|
|||
// 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
|
||||
|
||||
|
|
70
engine/v4k.h
70
engine/v4k.h
|
@ -308,6 +308,22 @@ extern "C" {
|
|||
#define EXPAND_ARGS(args) EXPAND_RETURN_COUNT args ///-
|
||||
#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)
|
||||
#define INLINE __inline
|
||||
#else
|
||||
|
@ -332,6 +348,21 @@ extern "C" {
|
|||
// typedef union vec2 { float X,Y; }; vec2 a = {0,1}, b = vec2(0,1);
|
||||
#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
|
||||
// - rlyeh, public domain
|
||||
|
@ -340,29 +371,25 @@ extern "C" {
|
|||
// note: XIU for C initializers, XCU for C++ initializers, XTU for C deinitializers
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define AUTORUN \
|
||||
static void AUTORUN_U(f)(void); \
|
||||
static const int AUTORUN_J(AUTORUN_U(f),__1) = (AUTORUN_U(f)(), 1); \
|
||||
static void AUTORUN_U(f)(void)
|
||||
#define AUTORUN_(fn) \
|
||||
static void fn(void); \
|
||||
static const int concat(fn,__1) = (fn(), 1); \
|
||||
static void fn(void)
|
||||
#elif defined _MSC_VER && !defined(__clang__) // cl, but not clang-cl
|
||||
#define AUTORUN \
|
||||
static void AUTORUN_U(f)(void); \
|
||||
static int AUTORUN_J(AUTORUN_U(f),__1) (){ AUTORUN_U(f)(); return 0; } \
|
||||
#define AUTORUN_(fn) \
|
||||
static void fn(void); \
|
||||
static int concat(fn,__1) (){ fn(); return 0; } \
|
||||
__pragma(section(".CRT$XIU", long, read)) \
|
||||
__declspec(allocate(".CRT$XIU")) \
|
||||
static int(* AUTORUN_J(AUTORUN_U(f),__2) )() = AUTORUN_J(AUTORUN_U(f),__1); \
|
||||
static void AUTORUN_U(f)(void)
|
||||
static int(* concat(fn,__2) )() = concat(fn,__1); \
|
||||
static void fn(void)
|
||||
#else // gcc,tcc,clang,clang-cl...
|
||||
#define AUTORUN \
|
||||
#define AUTORUN_(fn) \
|
||||
__attribute__((constructor)) \
|
||||
static void AUTORUN_U(f)(void)
|
||||
static void fn(void)
|
||||
#endif
|
||||
|
||||
// join + unique macro utils
|
||||
|
||||
#define AUTORUN_j(a, b) a##b
|
||||
#define AUTORUN_J(a, b) AUTORUN_j(a, b)
|
||||
#define AUTORUN_U(x) AUTORUN_J(x, __LINE__)
|
||||
#define AUTORUN AUTORUN_( concat(concat(concat(fn_L,__LINE__),_),__COUNTER__) )
|
||||
|
||||
#if 0 // autorun demo
|
||||
void byebye(void) { puts("seen after main()"); }
|
||||
|
@ -2644,8 +2671,8 @@ extern API int profiler_enabled; ///-
|
|||
// @todo: nested structs? pointers in members?
|
||||
// @todo: declare TYPEDEF(vec3, float[3]), TYPEDEF(mat4, vec4[4]/*float[16]*/)
|
||||
|
||||
#ifndef ifdef_objapi
|
||||
#define ifdef_objapi(T,...) __VA_ARGS__
|
||||
#ifndef OBJTYPE
|
||||
#define OBJTYPE(T) 0
|
||||
#endif
|
||||
|
||||
typedef struct reflect_t {
|
||||
|
@ -2667,7 +2694,7 @@ typedef struct reflect_t {
|
|||
function_inscribe(#F,intern(#F),(void*)F, function_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), \
|
||||
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 function_inscribe(const char *F,unsigned Fid,void *func,const char *infos);
|
||||
|
||||
API void reflected_printf(reflect_t *r);
|
||||
API void reflected_printf_all();
|
||||
API void reflect_print(const char *symbol);
|
||||
API void reflect_dump(const char *mask);
|
||||
API void reflect_init();
|
||||
#line 0
|
||||
|
||||
#line 1 "engine/split/v4k_render.h"
|
||||
|
|
Loading…
Reference in New Issue