main
Dominik Madarász 2023-10-16 17:15:59 +02:00
parent 7ec8d2aba7
commit d822f4f16d
10 changed files with 366 additions and 117 deletions

@ -1 +1 @@
Subproject commit 15f0bafa8d6b428bea1a0931861e891e8d6017e7
Subproject commit a23d27f206b89c4971803fdc74ac0d3a7b65217a

View File

@ -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 );

47
demos/99-cart.c 100644
View File

@ -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++) {
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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()"); }

View File

@ -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("*");
}

View File

@ -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();

View File

@ -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

View File

@ -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"