diff --git a/_mirror b/_mirror index a23d27f..27e24e6 160000 --- a/_mirror +++ b/_mirror @@ -1 +1 @@ -Subproject commit a23d27f206b89c4971803fdc74ac0d3a7b65217a +Subproject commit 27e24e603f1d1405c74c3fc9b241ed6c26185ba2 diff --git a/bind/v4k.lua b/bind/v4k.lua index dadfbf0..005563f 100644 --- a/bind/v4k.lua +++ b/bind/v4k.lua @@ -2251,7 +2251,7 @@ typedef uint16_t half; uint64_t pack64iv( uint8_t *buffer, int64_t value_ ); uint64_t unpack64iv( const uint8_t *buffer, int64_t *value ); int msgpack(const char *fmt, ... ); - bool msgunpack(const char *fmt, ... ); + int msgunpack(const char *fmt, ... ); int msgpack_new(uint8_t *w, size_t l); int msgpack_nil(); int msgpack_chr(bool n); @@ -2440,12 +2440,17 @@ extern profiler_t profiler; extern int profiler_enabled; typedef struct reflect_t { unsigned id, objtype; +union { unsigned sz; +unsigned member_offset; +unsigned enum_value; +}; const char *name; const char *info; void *addr; unsigned parent; const char *type; +unsigned bytes; } reflect_t; unsigned enum_find(const char *E); void * function_find(const char *F); @@ -2455,7 +2460,7 @@ const char *type; void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos); void enum_inscribe(const char *E,unsigned Eid,unsigned Eval,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, unsigned bytes); void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos); void reflect_print(const char *symbol); void reflect_dump(const char *mask); diff --git a/engine/joint/v4k.h b/engine/joint/v4k.h index 057b76f..d4273fa 100644 --- a/engine/joint/v4k.h +++ b/engine/joint/v4k.h @@ -14202,7 +14202,8 @@ extern "C" { #define macro(name) concat(name, __LINE__) #define defer(begin,end) for(int macro(i) = ((begin), 0); !macro(i); macro(i) = ((end), 1)) #define scope(end) defer((void)0, end) -#define benchmark for(double macro(i) = 1, macro(t) = -time_ss(); macro(i); macro(t)+=time_ss(), macro(i)=0, printf("%.4fs %2.f%% (" FILELINE ")\n", macro(t), macro(t)*100/0.0166667 )) +#define benchmark for(double macro(i) = 1, macro(t) = (time_ss(),-time_ss()); macro(i); macro(t)+=time_ss(), macro(i)=0, printf("%.4fs %2.f%% (" FILELINE ")\n", macro(t), macro(t)*100/0.0166667 )) +#define benchmark_ms for(double macro(i) = 1, macro(t) = (time_ss(),-time_ss()); macro(i); macro(t)+=time_ss(), macro(i)=0, printf("%.2fms %2.f%% (" FILELINE ")\n", macro(t)*1000, macro(t)*100/0.016666667 )) #define do_once static int macro(once) = 0; for(;!macro(once);macro(once)=1) #if is(cl) @@ -14318,7 +14319,7 @@ extern "C" { static void fn(void) #else // gcc,tcc,clang,clang-cl... #define AUTORUN_(fn) \ - __attribute__((constructor)) \ + __attribute__((constructor(__COUNTER__+101))) \ static void fn(void) #endif @@ -16128,8 +16129,8 @@ API uint64_t unpack64iv( const uint8_t *buffer, int64_t *value ); // api v2 -API int msgpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{" -API bool msgunpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{" +API int msgpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{". returns number of written bytes +API int msgunpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{". returns number of parsed args // api v1 @@ -16610,26 +16611,31 @@ extern API int profiler_enabled; ///- typedef struct reflect_t { unsigned id, objtype; + union { unsigned sz; + unsigned member_offset; + unsigned enum_value; + }; const char *name; const char *info; void *addr; unsigned parent; const char *type; + unsigned bytes; } reflect_t; // inscribe api -#define ENUM(V, value_annotations) \ - enum_inscribe(#V,intern(#V),V, value_annotations) +#define ENUM(V, .../*value_annotations*/) \ + enum_inscribe(#V,intern(#V),V, "" __VA_ARGS__/*value_annotations*/) -#define FUNCTION(F, function_annotations) \ - function_inscribe(#F,intern(#F),(void*)F, function_annotations) +#define FUNCTION(F, .../*function_annotations*/) \ + function_inscribe(#F,intern(#F),(void*)F, "" __VA_ARGS__/*function_annotations*/) -#define STRUCT(T, type, member, member_annotations) \ +#define STRUCT(T, type, member, .../*member_annotations*/) \ 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 ) + type_inscribe(#type,intern(#type),sizeof(((T){0}).member),"" __VA_ARGS__/*member_annotations*/), \ + member_inscribe(intern(#T), #member,intern(#member),(uintptr_t)&((T*)0)->member, "" __VA_ARGS__/*member_annotations*/, #type, sizeof(((T){0}).member) ) // find api @@ -16637,7 +16643,7 @@ API unsigned enum_find(const char *E); API void * function_find(const char *F); API reflect_t member_find(const char *T, const char *M); /// find specific member -API void * member_findptr(void *obj, const char *T, const char *M); +API void * member_findptr(void *obj, const char *T, const char *M); // @deprecate API array(reflect_t) members_find(const char *T); // iterate members in a struct @@ -16652,7 +16658,7 @@ API array(reflect_t) members_find(const char *T); API void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos); API void enum_inscribe(const char *E,unsigned Eid,unsigned Eval,const char *infos); API void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos); -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, unsigned bytes); API void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos); API void reflect_print(const char *symbol); @@ -343085,7 +343091,7 @@ int msgpack(const char *fmt, ... ) { va_end(vl); return count; } -bool msgunpack(const char *fmt, ... ) { +int msgunpack(const char *fmt, ... ) { int count = 0; va_list vl; va_start(vl, fmt); @@ -343100,7 +343106,7 @@ bool msgunpack(const char *fmt, ... ) { // break; case 'b': { bool *v = !!va_arg(vl, bool*); count += msgunpack_chr(v); } // break; case 'e': { uint8_t k = va_arg(vl, uint64_t); void *v = va_arg(vl, void*); size_t l = va_arg(vl, uint64_t); count += msgunpack_ext( k, v, l ); } // break; case 'n': { count += msgunpack_nil(); } -// break; case 'p': { void *p = va_arg(vl, void*); size_t l = va_arg(vl, uint64_t); count += msgunpack_bin( p, l ); } + break; case 'p': { void *p = va_arg(vl, void*); uint64_t l = va_arg(vl, uint64_t); count += msgunpack_bin( p, &l ); } // break; case 'u': { uint64_t v = va_arg(vl, uint64_t); count += msgunpack_uns(v); } // break; case 'd': case 'i': { int64_t v = va_arg(vl, int64_t); count += msgunpack_int(v); } default: /*count = 0;*/ break; @@ -343886,13 +343892,13 @@ void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, 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) { +void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type, unsigned bytes) { 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); array(reflect_t) *found = map_find_or_add(members, Tid, 0); - 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, bytes })); } reflect_t member_find(const char *T, const char *M) { reflect_init(); @@ -343943,53 +343949,42 @@ void reflect_print(const char *symbol) { // -- tests -enum { - MYVALUE0 = 0, - MYVALUE1, - MYVALUE2, - MYVALUEA = 123, -}; - -typedef struct MyVec4 { - float x,y,z,w; -} MyVec4; - -enum { OBJTYPE_MyVec4 = 0x01 }; +// type0 is reserved (no type) +// type1 reserved for objs +// type2 reserved for entities +// @todo: type3 and 4 likely reserved for components and systems?? +// enum { OBJTYPE_vec3 = 0x03 }; AUTOTEST { - // register structs, enums and functions + // register structs, enums and functions. with and without comments+tags - STRUCT( MyVec4, float, x, "Right" ); - STRUCT( MyVec4, float, y, "Forward" ); - STRUCT( MyVec4, float, z, "Up" ); - STRUCT( MyVec4, float, w, "W" ); + STRUCT( vec3, float, x ); + STRUCT( vec3, float, y ); + STRUCT( vec3, float, z, "Up" ); - ENUM( MYVALUE0, "bla bla #0" ); - ENUM( MYVALUE1, "bla bla #1" ); - ENUM( MYVALUE2, "bla bla #2" ); - ENUM( MYVALUEA, "bla bla (A)" ); + ENUM( IMAGE_RGB ); + ENUM( TEXTURE_RGB, "3-channel Red+Green+Blue texture flag" ); + ENUM( TEXTURE_RGBA, "4-channel Red+Green+Blue+Alpha texture flag" ); - FUNCTION( puts, "handy function that I use a lot" ); - FUNCTION( printf, "handy function that I use a lot" ); + FUNCTION( puts ); + FUNCTION( printf, "function that prints formatted text to stdout" ); // verify some reflected infos test( function_find("puts") == puts ); test( function_find("printf") == printf ); - test( enum_find("MYVALUE0") == MYVALUE0 ); - test( enum_find("MYVALUE1") == MYVALUE1 ); - test( enum_find("MYVALUE2") == MYVALUE2 ); - test( enum_find("MYVALUEA") == MYVALUEA ); + test( enum_find("TEXTURE_RGB") == TEXTURE_RGB ); + test( enum_find("TEXTURE_RGBA") == TEXTURE_RGBA ); // iterate reflected struct - for each_member("MyVec4", R) { - // printf("+%s MyVec4.%s // %s\n", R->type, R->name, R->info); + for each_member("vec3", R) { + //printf("+%s vec3.%s (+%x) // %s\n", R->type, R->name, R->member_offset, R->info); } // reflect_print("puts"); - // reflect_print("MYVALUE0"); - // reflect_print("MyVec4"); + //reflect_print("TEXTURE_RGBA"); + //reflect_print("vec3"); // reflect_dump("*"); } @@ -354705,6 +354700,8 @@ void glNewFrame() { } bool window_create_from_handle(void *handle, float scale, unsigned flags) { + ifdef(debug, if( flag("--tests") ) exit(0)); + glfw_init(); v4k_init(); if(!t) t = glfwGetTime(); diff --git a/engine/split/v4k_config.h b/engine/split/v4k_config.h index 1c7f0c0..e0a1ee6 100644 --- a/engine/split/v4k_config.h +++ b/engine/split/v4k_config.h @@ -171,7 +171,8 @@ #define macro(name) concat(name, __LINE__) #define defer(begin,end) for(int macro(i) = ((begin), 0); !macro(i); macro(i) = ((end), 1)) #define scope(end) defer((void)0, end) -#define benchmark for(double macro(i) = 1, macro(t) = -time_ss(); macro(i); macro(t)+=time_ss(), macro(i)=0, printf("%.4fs %2.f%% (" FILELINE ")\n", macro(t), macro(t)*100/0.0166667 )) +#define benchmark for(double macro(i) = 1, macro(t) = (time_ss(),-time_ss()); macro(i); macro(t)+=time_ss(), macro(i)=0, printf("%.4fs %2.f%% (" FILELINE ")\n", macro(t), macro(t)*100/0.0166667 )) +#define benchmark_ms for(double macro(i) = 1, macro(t) = (time_ss(),-time_ss()); macro(i); macro(t)+=time_ss(), macro(i)=0, printf("%.2fms %2.f%% (" FILELINE ")\n", macro(t)*1000, macro(t)*100/0.016666667 )) #define do_once static int macro(once) = 0; for(;!macro(once);macro(once)=1) #if is(cl) @@ -287,7 +288,7 @@ static void fn(void) #else // gcc,tcc,clang,clang-cl... #define AUTORUN_(fn) \ - __attribute__((constructor)) \ + __attribute__((constructor(__COUNTER__+101))) \ static void fn(void) #endif diff --git a/engine/split/v4k_pack.c b/engine/split/v4k_pack.c index f43c135..6bbb353 100644 --- a/engine/split/v4k_pack.c +++ b/engine/split/v4k_pack.c @@ -773,7 +773,7 @@ int msgpack(const char *fmt, ... ) { va_end(vl); return count; } -bool msgunpack(const char *fmt, ... ) { +int msgunpack(const char *fmt, ... ) { int count = 0; va_list vl; va_start(vl, fmt); @@ -788,7 +788,7 @@ bool msgunpack(const char *fmt, ... ) { // break; case 'b': { bool *v = !!va_arg(vl, bool*); count += msgunpack_chr(v); } // break; case 'e': { uint8_t k = va_arg(vl, uint64_t); void *v = va_arg(vl, void*); size_t l = va_arg(vl, uint64_t); count += msgunpack_ext( k, v, l ); } // break; case 'n': { count += msgunpack_nil(); } -// break; case 'p': { void *p = va_arg(vl, void*); size_t l = va_arg(vl, uint64_t); count += msgunpack_bin( p, l ); } + break; case 'p': { void *p = va_arg(vl, void*); uint64_t l = va_arg(vl, uint64_t); count += msgunpack_bin( p, &l ); } // break; case 'u': { uint64_t v = va_arg(vl, uint64_t); count += msgunpack_uns(v); } // break; case 'd': case 'i': { int64_t v = va_arg(vl, int64_t); count += msgunpack_int(v); } default: /*count = 0;*/ break; diff --git a/engine/split/v4k_pack.h b/engine/split/v4k_pack.h index adf2ea3..d46da1d 100644 --- a/engine/split/v4k_pack.h +++ b/engine/split/v4k_pack.h @@ -152,8 +152,8 @@ API uint64_t unpack64iv( const uint8_t *buffer, int64_t *value ); // api v2 -API int msgpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{" -API bool msgunpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{" +API int msgpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{". returns number of written bytes +API int msgunpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{". returns number of parsed args // api v1 diff --git a/engine/split/v4k_reflect.c b/engine/split/v4k_reflect.c index c74aeaa..4fe42b4 100644 --- a/engine/split/v4k_reflect.c +++ b/engine/split/v4k_reflect.c @@ -39,13 +39,13 @@ void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, 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) { +void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type, unsigned bytes) { 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); array(reflect_t) *found = map_find_or_add(members, Tid, 0); - 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, bytes })); } reflect_t member_find(const char *T, const char *M) { reflect_init(); @@ -96,53 +96,42 @@ void reflect_print(const char *symbol) { // -- tests -enum { - MYVALUE0 = 0, - MYVALUE1, - MYVALUE2, - MYVALUEA = 123, -}; - -typedef struct MyVec4 { - float x,y,z,w; -} MyVec4; - -enum { OBJTYPE_MyVec4 = 0x01 }; +// type0 is reserved (no type) +// type1 reserved for objs +// type2 reserved for entities +// @todo: type3 and 4 likely reserved for components and systems?? +// enum { OBJTYPE_vec3 = 0x03 }; AUTOTEST { - // register structs, enums and functions + // register structs, enums and functions. with and without comments+tags - STRUCT( MyVec4, float, x, "Right" ); - STRUCT( MyVec4, float, y, "Forward" ); - STRUCT( MyVec4, float, z, "Up" ); - STRUCT( MyVec4, float, w, "W" ); + STRUCT( vec3, float, x ); + STRUCT( vec3, float, y ); + STRUCT( vec3, float, z, "Up" ); - ENUM( MYVALUE0, "bla bla #0" ); - ENUM( MYVALUE1, "bla bla #1" ); - ENUM( MYVALUE2, "bla bla #2" ); - ENUM( MYVALUEA, "bla bla (A)" ); + ENUM( IMAGE_RGB ); + ENUM( TEXTURE_RGB, "3-channel Red+Green+Blue texture flag" ); + ENUM( TEXTURE_RGBA, "4-channel Red+Green+Blue+Alpha texture flag" ); - FUNCTION( puts, "handy function that I use a lot" ); - FUNCTION( printf, "handy function that I use a lot" ); + FUNCTION( puts ); + FUNCTION( printf, "function that prints formatted text to stdout" ); // verify some reflected infos test( function_find("puts") == puts ); test( function_find("printf") == printf ); - test( enum_find("MYVALUE0") == MYVALUE0 ); - test( enum_find("MYVALUE1") == MYVALUE1 ); - test( enum_find("MYVALUE2") == MYVALUE2 ); - test( enum_find("MYVALUEA") == MYVALUEA ); + test( enum_find("TEXTURE_RGB") == TEXTURE_RGB ); + test( enum_find("TEXTURE_RGBA") == TEXTURE_RGBA ); // iterate reflected struct - for each_member("MyVec4", R) { - // printf("+%s MyVec4.%s // %s\n", R->type, R->name, R->info); + for each_member("vec3", R) { + //printf("+%s vec3.%s (+%x) // %s\n", R->type, R->name, R->member_offset, R->info); } // reflect_print("puts"); - // reflect_print("MYVALUE0"); - // reflect_print("MyVec4"); + //reflect_print("TEXTURE_RGBA"); + //reflect_print("vec3"); // reflect_dump("*"); } diff --git a/engine/split/v4k_reflect.h b/engine/split/v4k_reflect.h index b4fb77a..bf3a169 100644 --- a/engine/split/v4k_reflect.h +++ b/engine/split/v4k_reflect.h @@ -10,26 +10,31 @@ typedef struct reflect_t { unsigned id, objtype; + union { unsigned sz; + unsigned member_offset; + unsigned enum_value; + }; const char *name; const char *info; void *addr; unsigned parent; const char *type; + unsigned bytes; } reflect_t; // inscribe api -#define ENUM(V, value_annotations) \ - enum_inscribe(#V,intern(#V),V, value_annotations) +#define ENUM(V, .../*value_annotations*/) \ + enum_inscribe(#V,intern(#V),V, "" __VA_ARGS__/*value_annotations*/) -#define FUNCTION(F, function_annotations) \ - function_inscribe(#F,intern(#F),(void*)F, function_annotations) +#define FUNCTION(F, .../*function_annotations*/) \ + function_inscribe(#F,intern(#F),(void*)F, "" __VA_ARGS__/*function_annotations*/) -#define STRUCT(T, type, member, member_annotations) \ +#define STRUCT(T, type, member, .../*member_annotations*/) \ 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 ) + type_inscribe(#type,intern(#type),sizeof(((T){0}).member),"" __VA_ARGS__/*member_annotations*/), \ + member_inscribe(intern(#T), #member,intern(#member),(uintptr_t)&((T*)0)->member, "" __VA_ARGS__/*member_annotations*/, #type, sizeof(((T){0}).member) ) // find api @@ -37,7 +42,7 @@ API unsigned enum_find(const char *E); API void * function_find(const char *F); API reflect_t member_find(const char *T, const char *M); /// find specific member -API void * member_findptr(void *obj, const char *T, const char *M); +API void * member_findptr(void *obj, const char *T, const char *M); // @deprecate API array(reflect_t) members_find(const char *T); // iterate members in a struct @@ -52,7 +57,7 @@ API array(reflect_t) members_find(const char *T); API void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos); API void enum_inscribe(const char *E,unsigned Eid,unsigned Eval,const char *infos); API void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos); -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, unsigned bytes); API void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos); API void reflect_print(const char *symbol); diff --git a/engine/split/v4k_window.c b/engine/split/v4k_window.c index 1e156b0..70dc0c0 100644 --- a/engine/split/v4k_window.c +++ b/engine/split/v4k_window.c @@ -271,6 +271,8 @@ void glNewFrame() { } bool window_create_from_handle(void *handle, float scale, unsigned flags) { + ifdef(debug, if( flag("--tests") ) exit(0)); + glfw_init(); v4k_init(); if(!t) t = glfwGetTime(); diff --git a/engine/v4k.c b/engine/v4k.c index 6fa9995..504c381 100644 --- a/engine/v4k.c +++ b/engine/v4k.c @@ -12017,7 +12017,7 @@ int msgpack(const char *fmt, ... ) { va_end(vl); return count; } -bool msgunpack(const char *fmt, ... ) { +int msgunpack(const char *fmt, ... ) { int count = 0; va_list vl; va_start(vl, fmt); @@ -12032,7 +12032,7 @@ bool msgunpack(const char *fmt, ... ) { // break; case 'b': { bool *v = !!va_arg(vl, bool*); count += msgunpack_chr(v); } // break; case 'e': { uint8_t k = va_arg(vl, uint64_t); void *v = va_arg(vl, void*); size_t l = va_arg(vl, uint64_t); count += msgunpack_ext( k, v, l ); } // break; case 'n': { count += msgunpack_nil(); } -// break; case 'p': { void *p = va_arg(vl, void*); size_t l = va_arg(vl, uint64_t); count += msgunpack_bin( p, l ); } + break; case 'p': { void *p = va_arg(vl, void*); uint64_t l = va_arg(vl, uint64_t); count += msgunpack_bin( p, &l ); } // break; case 'u': { uint64_t v = va_arg(vl, uint64_t); count += msgunpack_uns(v); } // break; case 'd': case 'i': { int64_t v = va_arg(vl, int64_t); count += msgunpack_int(v); } default: /*count = 0;*/ break; @@ -12818,13 +12818,13 @@ void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, 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) { +void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type, unsigned bytes) { 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); array(reflect_t) *found = map_find_or_add(members, Tid, 0); - 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, bytes })); } reflect_t member_find(const char *T, const char *M) { reflect_init(); @@ -12875,53 +12875,42 @@ void reflect_print(const char *symbol) { // -- tests -enum { - MYVALUE0 = 0, - MYVALUE1, - MYVALUE2, - MYVALUEA = 123, -}; - -typedef struct MyVec4 { - float x,y,z,w; -} MyVec4; - -enum { OBJTYPE_MyVec4 = 0x01 }; +// type0 is reserved (no type) +// type1 reserved for objs +// type2 reserved for entities +// @todo: type3 and 4 likely reserved for components and systems?? +// enum { OBJTYPE_vec3 = 0x03 }; AUTOTEST { - // register structs, enums and functions + // register structs, enums and functions. with and without comments+tags - STRUCT( MyVec4, float, x, "Right" ); - STRUCT( MyVec4, float, y, "Forward" ); - STRUCT( MyVec4, float, z, "Up" ); - STRUCT( MyVec4, float, w, "W" ); + STRUCT( vec3, float, x ); + STRUCT( vec3, float, y ); + STRUCT( vec3, float, z, "Up" ); - ENUM( MYVALUE0, "bla bla #0" ); - ENUM( MYVALUE1, "bla bla #1" ); - ENUM( MYVALUE2, "bla bla #2" ); - ENUM( MYVALUEA, "bla bla (A)" ); + ENUM( IMAGE_RGB ); + ENUM( TEXTURE_RGB, "3-channel Red+Green+Blue texture flag" ); + ENUM( TEXTURE_RGBA, "4-channel Red+Green+Blue+Alpha texture flag" ); - FUNCTION( puts, "handy function that I use a lot" ); - FUNCTION( printf, "handy function that I use a lot" ); + FUNCTION( puts ); + FUNCTION( printf, "function that prints formatted text to stdout" ); // verify some reflected infos test( function_find("puts") == puts ); test( function_find("printf") == printf ); - test( enum_find("MYVALUE0") == MYVALUE0 ); - test( enum_find("MYVALUE1") == MYVALUE1 ); - test( enum_find("MYVALUE2") == MYVALUE2 ); - test( enum_find("MYVALUEA") == MYVALUEA ); + test( enum_find("TEXTURE_RGB") == TEXTURE_RGB ); + test( enum_find("TEXTURE_RGBA") == TEXTURE_RGBA ); // iterate reflected struct - for each_member("MyVec4", R) { - // printf("+%s MyVec4.%s // %s\n", R->type, R->name, R->info); + for each_member("vec3", R) { + //printf("+%s vec3.%s (+%x) // %s\n", R->type, R->name, R->member_offset, R->info); } // reflect_print("puts"); - // reflect_print("MYVALUE0"); - // reflect_print("MyVec4"); + //reflect_print("TEXTURE_RGBA"); + //reflect_print("vec3"); // reflect_dump("*"); } @@ -23637,6 +23626,8 @@ void glNewFrame() { } bool window_create_from_handle(void *handle, float scale, unsigned flags) { + ifdef(debug, if( flag("--tests") ) exit(0)); + glfw_init(); v4k_init(); if(!t) t = glfwGetTime(); diff --git a/engine/v4k.h b/engine/v4k.h index b0f8928..070b8e5 100644 --- a/engine/v4k.h +++ b/engine/v4k.h @@ -269,7 +269,8 @@ extern "C" { #define macro(name) concat(name, __LINE__) #define defer(begin,end) for(int macro(i) = ((begin), 0); !macro(i); macro(i) = ((end), 1)) #define scope(end) defer((void)0, end) -#define benchmark for(double macro(i) = 1, macro(t) = -time_ss(); macro(i); macro(t)+=time_ss(), macro(i)=0, printf("%.4fs %2.f%% (" FILELINE ")\n", macro(t), macro(t)*100/0.0166667 )) +#define benchmark for(double macro(i) = 1, macro(t) = (time_ss(),-time_ss()); macro(i); macro(t)+=time_ss(), macro(i)=0, printf("%.4fs %2.f%% (" FILELINE ")\n", macro(t), macro(t)*100/0.0166667 )) +#define benchmark_ms for(double macro(i) = 1, macro(t) = (time_ss(),-time_ss()); macro(i); macro(t)+=time_ss(), macro(i)=0, printf("%.2fms %2.f%% (" FILELINE ")\n", macro(t)*1000, macro(t)*100/0.016666667 )) #define do_once static int macro(once) = 0; for(;!macro(once);macro(once)=1) #if is(cl) @@ -385,7 +386,7 @@ extern "C" { static void fn(void) #else // gcc,tcc,clang,clang-cl... #define AUTORUN_(fn) \ - __attribute__((constructor)) \ + __attribute__((constructor(__COUNTER__+101))) \ static void fn(void) #endif @@ -2195,8 +2196,8 @@ API uint64_t unpack64iv( const uint8_t *buffer, int64_t *value ); // api v2 -API int msgpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{" -API bool msgunpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{" +API int msgpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{". returns number of written bytes +API int msgunpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{". returns number of parsed args // api v1 @@ -2677,26 +2678,31 @@ extern API int profiler_enabled; ///- typedef struct reflect_t { unsigned id, objtype; + union { unsigned sz; + unsigned member_offset; + unsigned enum_value; + }; const char *name; const char *info; void *addr; unsigned parent; const char *type; + unsigned bytes; } reflect_t; // inscribe api -#define ENUM(V, value_annotations) \ - enum_inscribe(#V,intern(#V),V, value_annotations) +#define ENUM(V, .../*value_annotations*/) \ + enum_inscribe(#V,intern(#V),V, "" __VA_ARGS__/*value_annotations*/) -#define FUNCTION(F, function_annotations) \ - function_inscribe(#F,intern(#F),(void*)F, function_annotations) +#define FUNCTION(F, .../*function_annotations*/) \ + function_inscribe(#F,intern(#F),(void*)F, "" __VA_ARGS__/*function_annotations*/) -#define STRUCT(T, type, member, member_annotations) \ +#define STRUCT(T, type, member, .../*member_annotations*/) \ 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 ) + type_inscribe(#type,intern(#type),sizeof(((T){0}).member),"" __VA_ARGS__/*member_annotations*/), \ + member_inscribe(intern(#T), #member,intern(#member),(uintptr_t)&((T*)0)->member, "" __VA_ARGS__/*member_annotations*/, #type, sizeof(((T){0}).member) ) // find api @@ -2704,7 +2710,7 @@ API unsigned enum_find(const char *E); API void * function_find(const char *F); API reflect_t member_find(const char *T, const char *M); /// find specific member -API void * member_findptr(void *obj, const char *T, const char *M); +API void * member_findptr(void *obj, const char *T, const char *M); // @deprecate API array(reflect_t) members_find(const char *T); // iterate members in a struct @@ -2719,7 +2725,7 @@ API array(reflect_t) members_find(const char *T); API void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos); API void enum_inscribe(const char *E,unsigned Eid,unsigned Eval,const char *infos); API void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos); -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, unsigned bytes); API void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos); API void reflect_print(const char *symbol);