sync fwk
parent
e8bfb4bfb5
commit
49c41fb90e
28
MAKE.bat
28
MAKE.bat
|
@ -729,25 +729,25 @@ if "!v4k!"=="yes" (
|
|||
rem editor
|
||||
if "!editor!"=="yes" (
|
||||
set edit=-DCOOK_ON_DEMAND -DUI_LESSER_SPACING -DUI_ICONS_SMALL
|
||||
rem if "!vis!"=="yes" echo !cc! !o! editor.exe tools\editor\editor.c !edit! !import! !args!
|
||||
rem !echo! editor && !cc! !o! editor.exe tools\editor\editor.c !edit! !import! !args! || set rc=1
|
||||
rem !echo! editor2 && !cc! !o! editor2.exe tools\editor\editor2.c !edit! !args! || set rc=1
|
||||
if "!vis!"=="yes" echo !cc! !o! editor.exe tools\editor\editor.c !edit! !import! !args!
|
||||
!echo! editor && !cc! !o! editor.exe tools\editor\editor.c !edit! !import! !args! || set rc=1
|
||||
!echo! editor3 && !cc! !o! editor3.exe tools\editor\editor3.c !edit! -Iengine/joint !args! || set rc=1
|
||||
|
||||
!echo! v4k && !cc! engine\v4k.c !export! !edit! !args! || set rc=1
|
||||
|
||||
if "!cc!"=="cl" (
|
||||
set plug_export=/LD
|
||||
) else if "!cc!"=="clang-cl" (
|
||||
set plug_export=/LD
|
||||
) else (
|
||||
set plug_export=-shared
|
||||
)
|
||||
rem if "!cc!"=="cl" (
|
||||
rem set plug_export=/LD
|
||||
rem ) else if "!cc!"=="clang-cl" (
|
||||
rem set plug_export=/LD
|
||||
rem ) else (
|
||||
rem set plug_export=-shared
|
||||
rem )
|
||||
|
||||
for %%f in ("workbench\plugins\*.c") do (
|
||||
!echo! %%~nf && !cc! !o! %%~nf.dll %%f -Iworkbench !plug_export! !args! !import! || set rc=1
|
||||
)
|
||||
rem for %%f in ("workbench\plugins\*.c") do (
|
||||
rem !echo! %%~nf && !cc! !o! %%~nf.dll %%f -Iworkbench !plug_export! !args! !import! || set rc=1
|
||||
rem )
|
||||
|
||||
!echo! workbench && !cc! !o! workbench.exe workbench\workbench.c -Iworkbench !args! !import! || set rc=1
|
||||
rem !echo! workbench && !cc! !o! workbench.exe workbench\workbench.c -Iworkbench !args! !import! || set rc=1
|
||||
)
|
||||
|
||||
rem demos
|
||||
|
|
17
bind/v4k.lua
17
bind/v4k.lua
|
@ -2453,8 +2453,8 @@ enum { NETWORK_USERID = 7, NETWORK_COUNT , NETWORK_CAPACITY };
|
|||
void server_send_bin(int64_t handle, const void *ptr, int len);
|
||||
void server_drop(int64_t handle);
|
||||
int64_t client_join(const char *ip, int port);
|
||||
typedef struct obj { struct { union { uintptr_t objheader; struct { uintptr_t objtype:8; uintptr_t objheap:1; uintptr_t objsizew:7; uintptr_t objrefs:8; uintptr_t objcomps:1; uintptr_t objnameid:16; uintptr_t objid:16+3; uintptr_t objunused:64-8-7-1-1-8-16-16-3; }; }; }; } obj;
|
||||
typedef struct entity { struct { union { uintptr_t objheader; struct { uintptr_t objtype:8; uintptr_t objheap:1; uintptr_t objsizew:7; uintptr_t objrefs:8; uintptr_t objcomps:1; uintptr_t objnameid:16; uintptr_t objid:16+3; uintptr_t objunused:64-8-7-1-1-8-16-16-3; }; }; union { struct { uintptr_t objenabled:32, objflagged:32; }; uintptr_t cflags; }; void *c[32]; }; } entity;
|
||||
typedef struct obj { struct { union { uintptr_t objheader; struct { uintptr_t objtype:8; uintptr_t objsizew:8; uintptr_t objrefs:8; uintptr_t objheap:1; uintptr_t objcomps:1; uintptr_t objunused:64-8-8-8-1-1-16-3; uintptr_t objid:16+3; }; }; }; } obj;
|
||||
typedef struct entity { struct { union { uintptr_t objheader; struct { uintptr_t objtype:8; uintptr_t objsizew:8; uintptr_t objrefs:8; uintptr_t objheap:1; uintptr_t objcomps:1; uintptr_t objunused:64-8-8-8-1-1-16-3; uintptr_t objid:16+3; }; }; union { struct { uintptr_t objenabled:32, objflagged:32; }; uintptr_t cflags; }; void *c[32]; }; } entity;
|
||||
obj *objtmp;
|
||||
void* obj_malloc(unsigned sz);
|
||||
void* obj_free(void *o);
|
||||
|
@ -2471,9 +2471,8 @@ void* obj_free(void *o);
|
|||
extern int (*obj_edit[256])();
|
||||
uintptr_t obj_header(const void *o);
|
||||
uintptr_t obj_id(const void *o);
|
||||
const char* obj_name(const void *o);
|
||||
unsigned obj_typeid(const void *o);
|
||||
const char* obj_type(const void *o);
|
||||
unsigned obj_typeid(const void *o);
|
||||
int obj_sizeof(const void *o);
|
||||
int obj_size(const void *o);
|
||||
char* obj_data(void *o);
|
||||
|
@ -2489,8 +2488,10 @@ void* obj_free(void *o);
|
|||
obj***obj_children(const void *o);
|
||||
obj***obj_siblings(const void *o);
|
||||
int obj_dumptree(const void *o);
|
||||
const char* obj_metaset(const void *o, const char *key, const char *value);
|
||||
const char* obj_metaget(const void *o, const char *key);
|
||||
void* obj_setmeta(void *o, const char *key, const char *value);
|
||||
const char* obj_meta(const void *o, const char *key);
|
||||
void* obj_setname(void *o, const char *name);
|
||||
const char* obj_name(const void *o);
|
||||
void* obj_swap(void *dst, void *src);
|
||||
void* obj_copy_fast(void *dst, const void *src);
|
||||
void* obj_copy(void *dst, const void *src);
|
||||
|
@ -2571,9 +2572,7 @@ unsigned bytes;
|
|||
void struct_inscribe(const char *T,unsigned Tsz,unsigned OBJTYPEid, const char *infos);
|
||||
void member_inscribe(const char *T, const char *M,unsigned Msz, const char *infos, const char *type, unsigned bytes);
|
||||
void function_inscribe(const char *F,void *func,const char *infos);
|
||||
void reflect_print(const char *symbol);
|
||||
void reflect_dump(const char *mask);
|
||||
void reflect_init();
|
||||
int ui_reflect(const char *mask);
|
||||
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,6 +47,10 @@ int main() {
|
|||
"}\n";
|
||||
const void *colors = font_colorize(source, "void,int,char", "if,else,for,do,while,return,switch,case,break,default,");
|
||||
|
||||
// read input file with strings to display
|
||||
array(char*) lines = 0;
|
||||
for each_substring( vfs_read("pangrams.txt"), "\r\n", it ) array_push(lines, STRDUP(it));
|
||||
|
||||
// demo loop
|
||||
while( window_swap() && !input(KEY_ESC) ) {
|
||||
ddraw_grid(0);
|
||||
|
@ -89,7 +93,6 @@ int main() {
|
|||
|
||||
// i18n: pangrams.txt file, line browser
|
||||
static int counter = 0;
|
||||
static array(char*) lines; do_once lines = strsplit( vfs_read("pangrams.txt"), "\r\n" );
|
||||
counter += input_down(KEY_RIGHT)-input_down(KEY_LEFT);
|
||||
counter += counter < 0 ? array_count(lines) : 0;
|
||||
font_print( va("<< %s >>\n", lines[counter % array_count(lines)]) );
|
||||
|
|
|
@ -12,17 +12,17 @@ int main() {
|
|||
// controls
|
||||
if(input_down(KEY_SPACE)) spin^=1;
|
||||
|
||||
// setup scene
|
||||
cam.fov = 30;
|
||||
cam.position = vec3(180,180,180);
|
||||
camera_enable(&cam);
|
||||
|
||||
// spin 2nd camera
|
||||
double t = window_time(), c = cos(t), s = sin(t);
|
||||
if(spin)
|
||||
camera_teleport(&cam2, vec3(c * 100, 100, s * 100));
|
||||
camera_lookat(&cam2, vec3(0,0,0));
|
||||
|
||||
// setup scene
|
||||
cam.fov = 30;
|
||||
cam.position = vec3(180,180,180);
|
||||
camera_enable(&cam);
|
||||
|
||||
// render world (ground and cubes only in frustum of cam2)
|
||||
mat44 projview; multiply44x2(projview, cam2.proj, cam2.view);
|
||||
frustum f = frustum_build(projview);
|
||||
|
|
|
@ -61,7 +61,6 @@ int main() {
|
|||
|
||||
// camera
|
||||
camera_t cam = camera();
|
||||
cam.speed = 0.2f;
|
||||
|
||||
// demo loop
|
||||
while (window_swap())
|
||||
|
@ -81,7 +80,7 @@ int main() {
|
|||
|
||||
// queue model scale bounces
|
||||
float t = fmod(window_time(), 0.3) / 0.3;
|
||||
float s = 1.0;//0.01f * ease_ping_pong(t, ease_in_cubic,ease_out_cubic);
|
||||
float s = 0.01f * ease_ping_pong(t, EASE_IN|EASE_CUBIC,EASE_OUT|EASE_CUBIC);
|
||||
object_scale(obj1, vec3(0.20f - s,0.20f + s,0.20f - s));
|
||||
object_scale(obj2, vec3(0.20f - s,0.20f + s,0.20f - s));
|
||||
|
||||
|
@ -128,11 +127,6 @@ int main() {
|
|||
fx_end();
|
||||
|
||||
// queue ui
|
||||
if( ui_panel("Camera", 0)) {
|
||||
if( ui_float("Speed", &cam.speed) ) {}
|
||||
if( ui_float3("Position", &cam.position.x) ) {}
|
||||
ui_panel_end();
|
||||
}
|
||||
if( ui_panel("Scene", 0)) {
|
||||
if(ui_toggle("Billboard X", &do_billboard_x)) {}
|
||||
if(ui_toggle("Billboard Y", &do_billboard_y)) {}
|
||||
|
|
|
@ -7,7 +7,7 @@ int main() {
|
|||
window_create(75, 0); // WINDOW_MSAA8);
|
||||
|
||||
array(char*) list = 0;
|
||||
for each_array( file_list("demos/art/shadertoys/**.fs"), char*, dir ) {
|
||||
for each_array( vfs_list("demos/art/shadertoys/**.fs"), char*, dir ) {
|
||||
array_push(list, STRDUP(file_name(dir)));
|
||||
}
|
||||
|
||||
|
|
|
@ -354,7 +354,7 @@ void node_blend_create(struct node_editor *editor, struct nk_vec2 position) {
|
|||
/* ================================= */
|
||||
|
||||
#define NK_RGB3(r,g,b) {r,g,b,255}
|
||||
#define BG_COLOR ((struct nk_color){0,0,0,80}) // nk_rgba(0,0,0,192)
|
||||
#define BG_COLOR ((struct nk_color){60,60,60,192}) // nk_rgba(0,0,0,192)
|
||||
|
||||
static
|
||||
struct editor_node_style {
|
||||
|
@ -376,10 +376,13 @@ struct editor_node_style {
|
|||
#define COLOR_FLOW_HI styles[type_flow].color_hover
|
||||
#define COLOR_FLOW_LO styles[type_flow].color_idle
|
||||
|
||||
#define GRID_SIZE 32.0f
|
||||
#define GRID_COLOR ((struct nk_color)NK_RGB3(60,60,80))
|
||||
#define GRID_SIZE 64.0f
|
||||
#define GRID_COLOR ((struct nk_color)NK_RGB3(80,80,120))
|
||||
#define GRID_THICKNESS 1.0f
|
||||
|
||||
// 4 colors: top-left, top-right, bottom-right, bottom-left
|
||||
#define GRID_BG_COLORS ((struct nk_color){30,30,30,255}), ((struct nk_color){40,20,0,255}), ((struct nk_color){30,30,30,255}), ((struct nk_color){20,30,40,255})
|
||||
|
||||
#define LINK_THICKNESS 1.0f
|
||||
#define LINK_DRAW(POINT_A,POINT_B,COLOR) do { \
|
||||
vec2 a = (POINT_A); \
|
||||
|
@ -616,6 +619,9 @@ static int node_editor(struct node_editor *editor) {
|
|||
struct nk_rect size = nk_layout_space_bounds(ui_ctx);
|
||||
struct nk_panel *nodePanel = 0;
|
||||
|
||||
//nk_fill_rect(canvas, size, 0/*rounding*/, ((struct nk_color){30,30,30,255})); // 20,30,40,255
|
||||
nk_fill_rect_multi_color(canvas, size, GRID_BG_COLORS);
|
||||
|
||||
if (editor->show_grid) {
|
||||
/* display grid */
|
||||
for (float x = (float)fmod(size.x - editor->scrolling.x, GRID_SIZE); x < size.w; x += GRID_SIZE)
|
||||
|
|
|
@ -661,4 +661,4 @@ int main() {
|
|||
ui_panel_end();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
2
depot
2
depot
|
@ -1 +1 @@
|
|||
Subproject commit 616f75f5bb015fefd6e3321621b0f178637535b5
|
||||
Subproject commit 55dfe191dcfca2c39969eaacbf283b75b11df31a
|
|
@ -16592,9 +16592,10 @@ API int64_t client_join(const char *ip, int port);
|
|||
|
||||
/* /!\ if you plan to use pragma pack(1) on any struct, you need #define OBJ_MIN_PRAGMAPACK_BITS 0 at the expense of max class size /!\ */
|
||||
#ifndef OBJ_MIN_PRAGMAPACK_BITS
|
||||
//#define OBJ_MIN_PRAGMAPACK_BITS 3 // allows pragma packs >= 8. objsizew becomes 7<<3, so 1024 bytes max per class (default)
|
||||
#define OBJ_MIN_PRAGMAPACK_BITS 1 // allows pragma packs >= 2. objsizew becomes 7<<1, so 256 bytes max per class
|
||||
//#define OBJ_MIN_PRAGMAPACK_BITS 0 // allows pragma packs >= 1. objsizew becomes 7<<0, so 128 bytes max per class
|
||||
//#define OBJ_MIN_PRAGMAPACK_BITS 3 // allows pragma packs >= 8. objsizew becomes 8<<3, so 2048 bytes max per class (default)
|
||||
#define OBJ_MIN_PRAGMAPACK_BITS 2 // allows pragma packs >= 4. objsizew becomes 8<<2, so 1024 bytes max per class
|
||||
//#define OBJ_MIN_PRAGMAPACK_BITS 1 // allows pragma packs >= 2. objsizew becomes 8<<1, so 512 bytes max per class
|
||||
//#define OBJ_MIN_PRAGMAPACK_BITS 0 // allows pragma packs >= 1. objsizew becomes 8<<0, so 256 bytes max per class
|
||||
#endif
|
||||
|
||||
#define OBJHEADER \
|
||||
|
@ -16602,13 +16603,12 @@ API int64_t client_join(const char *ip, int port);
|
|||
uintptr_t objheader; \
|
||||
struct { \
|
||||
uintptr_t objtype:8; \
|
||||
uintptr_t objheap:1; \
|
||||
uintptr_t objsizew:7; \
|
||||
uintptr_t objsizew:8; \
|
||||
uintptr_t objrefs:8; \
|
||||
uintptr_t objheap:1; \
|
||||
uintptr_t objcomps:1; /* << can be removed? check payload ptr instead? */ \
|
||||
uintptr_t objnameid:16; \
|
||||
uintptr_t objunused:64-8-8-8-1-1-ID_INDEX_BITS-ID_COUNT_BITS; /*19*/ \
|
||||
uintptr_t objid:ID_INDEX_BITS+ID_COUNT_BITS; /*16+3*/ \
|
||||
uintptr_t objunused:64-8-7-1-1-8-16-ID_INDEX_BITS-ID_COUNT_BITS; /*4*/ \
|
||||
}; \
|
||||
};
|
||||
|
||||
|
@ -16628,7 +16628,7 @@ API int64_t client_join(const char *ip, int port);
|
|||
#define OBJTYPEDEF(NAME,N) \
|
||||
enum { OBJTYPE(NAME) = N }; \
|
||||
STATIC_ASSERT( N <= 255 ); \
|
||||
STATIC_ASSERT( (sizeof(NAME) & ((1<<OBJ_MIN_PRAGMAPACK_BITS)-1)) == 0 );
|
||||
STATIC_ASSERT( sizeof(NAME) == ((sizeof(NAME)>>OBJ_MIN_PRAGMAPACK_BITS)<<OBJ_MIN_PRAGMAPACK_BITS) ); // (sizeof(NAME) & ((1<<OBJ_MIN_PRAGMAPACK_BITS)-1)) == 0 );
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// objects
|
||||
|
@ -16666,28 +16666,25 @@ API int64_t client_join(const char *ip, int port);
|
|||
// heap/stack ctor/dtor
|
||||
|
||||
static __thread obj *objtmp;
|
||||
#define OBJ_CTOR_HDR(PTR,HEAP,OBJ_NAMEID,SIZEOF_OBJ,OBJ_TYPE) ( \
|
||||
#define OBJ_CTOR_HDR(PTR,HEAP,SIZEOF_OBJ,OBJ_TYPE) ( \
|
||||
(PTR)->objheader = HEAP ? id_make(PTR) : 0, /*should assign to .objid instead. however, id_make() returns shifted bits already*/ \
|
||||
(PTR)->objnameid = (OBJ_NAMEID), \
|
||||
(PTR)->objtype = (OBJ_TYPE), \
|
||||
(PTR)->objheap = (HEAP), \
|
||||
(PTR)->objsizew = (SIZEOF_OBJ>>OBJ_MIN_PRAGMAPACK_BITS))
|
||||
#define OBJ_CTOR_PTR(PTR,HEAP,OBJ_NAMEID,SIZEOF_OBJ,OBJ_TYPE) ( \
|
||||
OBJ_CTOR_HDR(PTR,HEAP,OBJ_NAMEID,SIZEOF_OBJ,OBJ_TYPE), \
|
||||
#define OBJ_CTOR_PTR(PTR,HEAP,SIZEOF_OBJ,OBJ_TYPE) ( \
|
||||
OBJ_CTOR_HDR(PTR,HEAP,SIZEOF_OBJ,OBJ_TYPE), \
|
||||
obj_ctor(PTR))
|
||||
#define OBJ_CTOR(TYPE, NAME, HEAP, PAYLOAD_SIZE, ...) (TYPE*)( \
|
||||
objtmp = (HEAP ? MALLOC(sizeof(TYPE)+(PAYLOAD_SIZE)) : ALLOCA(sizeof(TYPE)+(PAYLOAD_SIZE))), \
|
||||
*(TYPE*)objtmp = ((TYPE){ {0}, __VA_ARGS__}), \
|
||||
((PAYLOAD_SIZE) ? memset((char*)objtmp + sizeof(TYPE), 0, (PAYLOAD_SIZE)) : objtmp), \
|
||||
( OBJTYPES[ OBJTYPE(TYPE) ] = #TYPE ), \
|
||||
OBJ_CTOR_PTR(objtmp, HEAP,intern(NAME),sizeof(TYPE),OBJTYPE(TYPE)), \
|
||||
OBJ_CTOR_PTR(objtmp, HEAP,sizeof(TYPE),OBJTYPE(TYPE)), \
|
||||
ifdef(debug, (obj_printf)(objtmp, va("%s", callstack(+16))), 0), \
|
||||
objtmp)
|
||||
obj_setname(objtmp, NAME))
|
||||
|
||||
#define obj(TYPE, ...) obj_ext(TYPE, #TYPE, __VA_ARGS__)
|
||||
#define obj_ext(TYPE, NAME, ...) *OBJ_CTOR(TYPE, NAME, 0, sizeof(array(obj*)), __VA_ARGS__)
|
||||
|
||||
#define obj_new(TYPE, ...) obj_new_ext(TYPE, #TYPE, __VA_ARGS__)
|
||||
#define obj(TYPE, ...) *OBJ_CTOR(TYPE, #TYPE, 0, sizeof(array(obj*)), __VA_ARGS__)
|
||||
#define obj_new(TYPE, ...) OBJ_CTOR(TYPE, #TYPE, 1, sizeof(array(obj*)), __VA_ARGS__)
|
||||
#define obj_new_ext(TYPE, NAME, ...) OBJ_CTOR(TYPE, NAME, 1, sizeof(array(obj*)), __VA_ARGS__)
|
||||
|
||||
void* obj_malloc(unsigned sz);
|
||||
|
@ -16745,12 +16742,10 @@ API extern int (*obj_edit[256])(); ///-
|
|||
// core
|
||||
|
||||
API uintptr_t obj_header(const void *o);
|
||||
|
||||
API uintptr_t obj_id(const void *o);
|
||||
API const char* obj_name(const void *o);
|
||||
|
||||
API unsigned obj_typeid(const void *o);
|
||||
API const char* obj_type(const void *o);
|
||||
API unsigned obj_typeid(const void *o);
|
||||
|
||||
API int obj_sizeof(const void *o);
|
||||
API int obj_size(const void *o); // size of all members together in struct. may include padding bytes.
|
||||
|
@ -16770,27 +16765,29 @@ API void* obj_unref(void *oo);
|
|||
// ----------------------------------------------------------------------------
|
||||
// scene tree
|
||||
|
||||
// non-recursive
|
||||
#define each_objchild(p,t,o) \
|
||||
#define each_objchild(p,t,o) /*non-recursive*/ \
|
||||
(array(obj*)* children = obj_children(p); children; children = 0) \
|
||||
for(int _i = 1, _end = array_count(*children); _i < _end; ++_i) \
|
||||
for(t *o = (t *)((*children)[_i]); o && 0[*children]; o = 0)
|
||||
for(t *o = (t *)((*children)[_i]); o && (obj_parent(o) == p); o = 0)
|
||||
|
||||
API obj* obj_detach(void *c);
|
||||
API obj* obj_attach(void *o, void *c);
|
||||
|
||||
API obj* obj_root(const void *o);
|
||||
API obj* obj_parent(const void *o);
|
||||
API array(obj*)*obj_children(const void *o);
|
||||
API array(obj*)*obj_siblings(const void *o);
|
||||
API array(obj*)*obj_children(const void *o); // child[0]: parent, child[1]: 1st child, child[2]: 2nd child...
|
||||
API array(obj*)*obj_siblings(const void *o); // child[0]: grandpa, child[1]: sibling1, child[2]: sibling2...
|
||||
|
||||
API int obj_dumptree(const void *o);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// metadata
|
||||
|
||||
API const char* obj_metaset(const void *o, const char *key, const char *value);
|
||||
API const char* obj_metaget(const void *o, const char *key);
|
||||
API void* obj_setmeta(void *o, const char *key, const char *value);
|
||||
API const char* obj_meta(const void *o, const char *key);
|
||||
|
||||
API void* obj_setname(void *o, const char *name);
|
||||
API const char* obj_name(const void *o);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// stl
|
||||
|
@ -16856,7 +16853,7 @@ API char* entity_save(entity *self);
|
|||
// reflection
|
||||
|
||||
#define each_objmember(oo,TYPE,NAME,PTR) \
|
||||
(array(reflect_t) *found_ = members_find(quark(((obj*)oo)->objnameid)); found_; found_ = 0) \
|
||||
(array(reflect_t) *found_ = members_find(obj_type(oo)); found_; found_ = 0) \
|
||||
for(int it_ = 0, end_ = array_count(*found_); it_ != end_; ++it_ ) \
|
||||
for(reflect_t *R = &(*found_)[it_]; R; R = 0 ) \
|
||||
for(const char *NAME = R->name, *TYPE = R->type; NAME || TYPE; ) \
|
||||
|
@ -16945,16 +16942,16 @@ typedef struct reflect_t {
|
|||
|
||||
// inscribe api
|
||||
|
||||
#define ENUM(V, .../*value_annotations*/) \
|
||||
enum_inscribe(#V,V, "" __VA_ARGS__/*value_annotations*/)
|
||||
#define ENUM(V, ...) \
|
||||
enum_inscribe(#V,V, "E" __VA_ARGS__ " ("FILELINE")")
|
||||
|
||||
#define FUNCTION(F, .../*function_annotations*/) \
|
||||
function_inscribe(#F,(void*)F, "" __VA_ARGS__/*function_annotations*/)
|
||||
#define FUNCTION(F, ...) \
|
||||
function_inscribe(#F,(void*)F, "F" __VA_ARGS__ " ("FILELINE")")
|
||||
|
||||
#define STRUCT(T, type, member, .../*member_annotations*/) \
|
||||
struct_inscribe(#T,sizeof(T),OBJTYPE(T),NULL), \
|
||||
type_inscribe(#type,sizeof(((T){0}).member),"" __VA_ARGS__/*member_annotations*/), \
|
||||
member_inscribe(#T, #member,(uintptr_t)&((T*)0)->member, "" __VA_ARGS__/*member_annotations*/, #type, sizeof(((T){0}).member) )
|
||||
#define STRUCT(T, type, member, ...) \
|
||||
struct_inscribe(#T,sizeof(T),OBJTYPE(T),"S" " ("FILELINE")"), \
|
||||
type_inscribe(#type,sizeof(((T){0}).member),"T" __VA_ARGS__ " ("FILELINE")"), \
|
||||
member_inscribe(#T, #member,(uintptr_t)&((T*)0)->member, "M" __VA_ARGS__ " ("FILELINE")", #type, sizeof(((T){0}).member) )
|
||||
|
||||
// find api
|
||||
|
||||
|
@ -16980,9 +16977,7 @@ API void struct_inscribe(const char *T,unsigned Tsz,unsigned OBJTY
|
|||
API void member_inscribe(const char *T, const char *M,unsigned Msz, const char *infos, const char *type, unsigned bytes);
|
||||
API void function_inscribe(const char *F,void *func,const char *infos);
|
||||
|
||||
API void reflect_print(const char *symbol);
|
||||
API void reflect_dump(const char *mask);
|
||||
API void reflect_init();
|
||||
API int ui_reflect(const char *mask); // *, model* or NULL
|
||||
#line 0
|
||||
|
||||
#line 1 "engine/split/v4k_render.h"
|
||||
|
@ -240075,6 +240070,7 @@ nk_glfw3_render(struct nk_glfw* glfw, enum nk_anti_aliasing AA, int max_vertex_b
|
|||
|
||||
/* iterate over and execute each draw command */
|
||||
nk_draw_foreach(cmd, &glfw->ctx, &dev->cmds)
|
||||
if(glfw->height > 0) //< @r-lyeh: fix opengl/scissor error when win is minimized (h==0)
|
||||
{
|
||||
if (!cmd->elem_count) continue;
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id);
|
||||
|
@ -331991,8 +331987,16 @@ int main() {
|
|||
#endif
|
||||
|
||||
#define do_threadlock(mutexptr) \
|
||||
for( int init_ = !!(mutexptr) || (thread_mutex_init( (mutexptr) = CALLOC(1, sizeof(thread_mutex_t)) ), 1); init_; init_ = 0) \
|
||||
for( int lock_ = (thread_mutex_lock( mutexptr ), 1); lock_; lock_ = (thread_mutex_unlock( mutexptr ), 0) )
|
||||
for( int init_ = !!(mutexptr) || (thread_mutex_init( (mutexptr) = CALLOC(1, sizeof(thread_mutex_t)) ), 1); init_; init_ = 0) \
|
||||
for( int lock_ = (thread_mutex_lock( mutexptr ), 1); lock_; lock_ = (thread_mutex_unlock( mutexptr ), 0) )
|
||||
|
||||
API void *ui_handle();
|
||||
#define ui_push_hspace(px) \
|
||||
(int xx = px; xx; xx = 0) \
|
||||
for(struct nk_context *ctx = (struct nk_context*)ui_handle(); ctx; ctx = 0 ) \
|
||||
for(struct nk_panel *layout = ui_ctx->current->layout; layout; ) \
|
||||
for( xx = (layout->at_x += px, layout->bounds.w -= px, 0); layout; layout->at_x -= px, layout->bounds.w += px, layout = 0 )
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// C files
|
||||
|
@ -337707,7 +337711,7 @@ if( found && *found == 0 ) {
|
|||
}
|
||||
|
||||
// search (cache)
|
||||
if( !ptr ) {
|
||||
if( !ptr && ! is(osx) ) {
|
||||
ptr = cache_lookup(lookup_id, &size);
|
||||
}
|
||||
|
||||
|
@ -342083,7 +342087,7 @@ size_t dlmalloc_usable_size(void*); // __ANDROID_API__
|
|||
|
||||
// xrealloc --------------------------------------------------------------------
|
||||
|
||||
static __thread uint64_t xstats_current = 0, xstats_total = 0;
|
||||
static __thread uint64_t xstats_current = 0, xstats_total = 0, xstats_allocs = 0;
|
||||
|
||||
void* xrealloc(void* oldptr, size_t size) {
|
||||
// for stats
|
||||
|
@ -342102,8 +342106,10 @@ void* xrealloc(void* oldptr, size_t size) {
|
|||
// for stats
|
||||
if( oldptr ) {
|
||||
xstats_current += (int64_t)size - (int64_t)oldsize;
|
||||
xstats_allocs -= !size;
|
||||
} else {
|
||||
xstats_current += size;
|
||||
xstats_allocs += !!size;
|
||||
}
|
||||
if( xstats_current > xstats_total ) {
|
||||
xstats_total = xstats_current;
|
||||
|
@ -342116,7 +342122,8 @@ size_t xsize(void* p) {
|
|||
return 0;
|
||||
}
|
||||
char *xstats(void) {
|
||||
return va("%03u/%03uMB", (unsigned)xstats_current / 1024 / 1024, (unsigned)xstats_total / 1024 / 1024);
|
||||
uint64_t xtra = 0; // xstats_allocs * 65536; // assumes 64K pagesize for every alloc
|
||||
return va("%03u/%03uMB", (unsigned)((xstats_current+xtra) / 1024 / 1024), (unsigned)((xstats_total+xtra) / 1024 / 1024));
|
||||
}
|
||||
|
||||
// stack -----------------------------------------------------------------------
|
||||
|
@ -344853,38 +344860,45 @@ array(reflect_t)* members_find(const char *T) {
|
|||
return map_find(members, intern(T));
|
||||
}
|
||||
|
||||
static
|
||||
void ui_reflect_(const reflect_t *R, const char *filter, int mask) {
|
||||
// debug:
|
||||
// ui_label(va("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_dump(const char *mask) {
|
||||
if( mask == *R->info ) {
|
||||
static __thread char *buf = 0;
|
||||
if( buf ) *buf = '\0';
|
||||
|
||||
struct nk_context *ui_ctx = (struct nk_context *)ui_handle();
|
||||
for ui_push_hspace(16) {
|
||||
array(reflect_t) *T = map_find(members, intern(R->name));
|
||||
/**/ if( T ) {ui_label(strcatf(&buf,"S struct %s@%s", R->name, R->info+1)); for each_array_ptr(*T, reflect_t, it) if(strmatchi(it->name,filter)) ui_reflect_(it,filter,'M'); }
|
||||
else if( R->addr ) ui_label(strcatf(&buf,"F func %s()@%s", R->name, R->info+1));
|
||||
else if( !R->parent ) ui_label(strcatf(&buf,"E enum %s = %d@%s", R->name, R->sz, R->info+1));
|
||||
else ui_label(strcatf(&buf,"M %s %s@%s", R->type, R->name, R->info+1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
API void *ui_handle();
|
||||
int ui_reflect(const char *filter) {
|
||||
if( !filter ) filter = "*";
|
||||
|
||||
int enabled = ui_enabled();
|
||||
ui_disable();
|
||||
|
||||
// ENUMS, then FUNCTIONS, then STRUCTS
|
||||
unsigned masks[] = { 'E', 'F', 'S' };
|
||||
for( int i = 0; i < countof(masks); ++i )
|
||||
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 : "");
|
||||
if( strmatchi(R->name, filter)) {
|
||||
ui_reflect_(R, filter, masks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if( enabled ) ui_enable();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -- tests
|
||||
|
@ -354173,7 +354187,7 @@ if( font ) nk_style_pop_color(ui_ctx);
|
|||
if( font ) nk_style_pop_font(ui_ctx);
|
||||
|
||||
if (split && is_hovering && !ui_has_active_popups && nk_window_has_focus(ui_ctx)) {
|
||||
nk_tooltip(ui_ctx, split + 1);
|
||||
nk_tooltip(ui_ctx, split + 1); // @fixme: not working under ui_disable() state
|
||||
}
|
||||
|
||||
layout->at_x -= spacing;
|
||||
|
@ -355673,7 +355687,7 @@ void glNewFrame() {
|
|||
|
||||
bool window_create_from_handle(void *handle, float scale, unsigned flags) {
|
||||
// abort run if any test suite failed in unit-test mode
|
||||
ifdef(debug, if( flag("--test-only") ) exit( test_errors ? -test_errors : 0 ));
|
||||
ifdef(debug, if( flag("--test") ) exit( test_errors ? -test_errors : 0 ));
|
||||
|
||||
glfw_init();
|
||||
v4k_init();
|
||||
|
@ -356150,6 +356164,9 @@ int window_frame_begin() {
|
|||
if( choice == 2 ) editor_send("key_battery","1");
|
||||
}
|
||||
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_WATER " Reflection", "Debug.Reflect") {
|
||||
ui_reflect("*");
|
||||
}
|
||||
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_EXTENSION " Plugins", "Debug.Plugins") {
|
||||
// @todo. include VCS
|
||||
|
@ -356715,7 +356732,7 @@ const char *OBJTYPES[256] = { 0 }; // = { REPEAT256("") };
|
|||
void *obj_malloc(unsigned sz) {
|
||||
//sz = sizeof(obj) + sz + sizeof(array(obj*))); // useful?
|
||||
obj *ptr = CALLOC(1, sz);
|
||||
OBJ_CTOR_HDR(ptr,1,intern("obj"),sz,OBJTYPE_obj);
|
||||
OBJ_CTOR_HDR(ptr,1,sz,OBJTYPE_obj);
|
||||
return ptr;
|
||||
}
|
||||
void *obj_free(void *o) {
|
||||
|
@ -356745,9 +356762,9 @@ unsigned obj_typeid(const void *o) {
|
|||
const char *obj_type(const void *o) {
|
||||
return OBJTYPES[ (((obj*)o)->objtype) ];
|
||||
}
|
||||
const char *obj_name(const void *o) {
|
||||
return quark(((obj*)o)->objnameid);
|
||||
}
|
||||
//const char *obj_name(const void *o) {
|
||||
// return quark(((obj*)o)->objnameid);
|
||||
//}
|
||||
int obj_sizeof(const void *o) {
|
||||
return (int)( ((const obj*)o)->objsizew << OBJ_MIN_PRAGMAPACK_BITS );
|
||||
}
|
||||
|
@ -356797,8 +356814,8 @@ void test_obj_core() {
|
|||
test( obj_id(s) != 0 );
|
||||
test( obj_id(r) != obj_id(s) );
|
||||
|
||||
obj t = obj_ext(obj, "root");
|
||||
obj u = obj_ext(obj, "root");
|
||||
obj t = obj(obj); obj_setname(&t, "root");
|
||||
obj u = obj(obj); obj_setname(&u, "root");
|
||||
|
||||
test(&t);
|
||||
test( 0 == strcmp(obj_type(&t), "obj") );
|
||||
|
@ -356935,7 +356952,7 @@ void test_obj_scene() {
|
|||
obj_attach(c2, gc2); // +- gc2
|
||||
obj_attach(c2, gc3); // +- gc3
|
||||
|
||||
// obj_dumptree(r);
|
||||
obj_dumptree(r);
|
||||
// puts("---");
|
||||
|
||||
test( obj_parent(r) == 0 );
|
||||
|
@ -356972,16 +356989,16 @@ void test_obj_scene() {
|
|||
|
||||
static map(int,int) oms;
|
||||
static thread_mutex_t *oms_lock;
|
||||
const char *obj_metaset(const void *o, const char *key, const char *value) {
|
||||
void *obj_setmeta(void *o, const char *key, const char *value) {
|
||||
do_threadlock(oms_lock) {
|
||||
if(!oms) map_init_int(oms);
|
||||
int *q = map_find_or_add(oms, intern(va("%llu-%s",obj_id((obj*)o),key)), 0);
|
||||
if(!*q && !value[0]) {} else *q = intern(value);
|
||||
return quark(*q);
|
||||
return quark(*q), o;
|
||||
}
|
||||
return 0; // unreachable
|
||||
}
|
||||
const char* obj_metaget(const void *o, const char *key) {
|
||||
const char* obj_meta(const void *o, const char *key) {
|
||||
do_threadlock(oms_lock) {
|
||||
if(!oms) map_init_int(oms);
|
||||
int *q = map_find_or_add(oms, intern(va("%llu-%s",obj_id((obj*)o),key)), 0);
|
||||
|
@ -356990,12 +357007,21 @@ const char* obj_metaget(const void *o, const char *key) {
|
|||
return 0; // unreachable
|
||||
}
|
||||
|
||||
void *obj_setname(void *o, const char *name) {
|
||||
return obj_setmeta(o, "name", name);
|
||||
}
|
||||
const char *obj_name(const void *o) {
|
||||
const char *objname = obj_meta(o, "name");
|
||||
return objname[0] ? objname : "obj";
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void test_obj_metadatas( void *o1 ) {
|
||||
obj *o = (obj *)o1;
|
||||
test( !strcmp("", obj_metaget(o, "has_passed_test")) );
|
||||
test( !strcmp("yes", obj_metaset(o, "has_passed_test", "yes")) );
|
||||
test( !strcmp("yes", obj_metaget(o, "has_passed_test")) );
|
||||
test( !strcmp("", obj_meta(o, "has_passed_test")) );
|
||||
test( obj_setmeta(o, "has_passed_test", "yes") );
|
||||
test( !strcmp("yes", obj_meta(o, "has_passed_test")) );
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -357308,16 +357334,29 @@ obj *obj_loadmpack(void *o, const char *sav) { // @todo
|
|||
return obj_mergempack(obj_zero(o), sav);
|
||||
}
|
||||
|
||||
static __thread array(char*) obj_stack;
|
||||
static __thread map(void*,array(char*)) obj_stack;
|
||||
int obj_push(const void *o) {
|
||||
char *bin = STRDUP(obj_savebin(o));
|
||||
array_push(obj_stack, bin);
|
||||
if(!obj_stack) map_init_ptr(obj_stack);
|
||||
array(char*) *found = map_find_or_add(obj_stack,(void*)o,0);
|
||||
|
||||
char *bin = STRDUP(obj_saveini(o)); // @todo: savebin
|
||||
array_push(*found, bin);
|
||||
return 1;
|
||||
}
|
||||
int obj_pop(void *o) {
|
||||
char *bin = *array_pop(obj_stack);
|
||||
int rc = !!obj_loadbin(o, bin);
|
||||
return FREE(bin), rc;
|
||||
if(!obj_stack) map_init_ptr(obj_stack);
|
||||
array(char*) *found = map_find_or_add(obj_stack,(void*)o,0);
|
||||
|
||||
char **bin = array_back(*found);
|
||||
if( bin ) {
|
||||
int rc = !!obj_loadini(o, *bin); // @todo: loadbin
|
||||
if( array_count(*found) > 1 ) {
|
||||
FREE(*bin);
|
||||
array_pop(*found);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -357479,10 +357518,11 @@ void *obj_make(const char *str) {
|
|||
reflect_t *found = map_find(reflects, Tid);
|
||||
if(!found) return 0;
|
||||
|
||||
obj *ptr = CALLOC(1, found->sz + has_components * sizeof(array(obj*)));
|
||||
obj *ptr = CALLOC(1, found->sz + (has_components+1) * sizeof(array(obj*)));
|
||||
void *ret = (T == I ? obj_mergeini : obj_mergejson)(ptr, str);
|
||||
OBJTYPES[ found->objtype ] = found->name;
|
||||
OBJ_CTOR_PTR(ptr,1,found->id,found->sz,found->objtype);
|
||||
OBJ_CTOR_PTR(ptr,1,/*found->id,*/found->sz,found->objtype);
|
||||
obj_setname(ptr, name); // found->id);
|
||||
|
||||
return ptr; // returns partial construction as well. @todo: just return `ret` for a more strict built/failed policy
|
||||
}
|
||||
|
|
|
@ -319,6 +319,7 @@ nk_glfw3_render(struct nk_glfw* glfw, enum nk_anti_aliasing AA, int max_vertex_b
|
|||
|
||||
/* iterate over and execute each draw command */
|
||||
nk_draw_foreach(cmd, &glfw->ctx, &dev->cmds)
|
||||
if(glfw->height > 0) //< @r-lyeh: fix opengl/scissor error when win is minimized (h==0)
|
||||
{
|
||||
if (!cmd->elem_count) continue;
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id);
|
||||
|
|
|
@ -99,8 +99,16 @@
|
|||
#endif
|
||||
|
||||
#define do_threadlock(mutexptr) \
|
||||
for( int init_ = !!(mutexptr) || (thread_mutex_init( (mutexptr) = CALLOC(1, sizeof(thread_mutex_t)) ), 1); init_; init_ = 0) \
|
||||
for( int lock_ = (thread_mutex_lock( mutexptr ), 1); lock_; lock_ = (thread_mutex_unlock( mutexptr ), 0) )
|
||||
for( int init_ = !!(mutexptr) || (thread_mutex_init( (mutexptr) = CALLOC(1, sizeof(thread_mutex_t)) ), 1); init_; init_ = 0) \
|
||||
for( int lock_ = (thread_mutex_lock( mutexptr ), 1); lock_; lock_ = (thread_mutex_unlock( mutexptr ), 0) )
|
||||
|
||||
API void *ui_handle();
|
||||
#define ui_push_hspace(px) \
|
||||
(int xx = px; xx; xx = 0) \
|
||||
for(struct nk_context *ctx = (struct nk_context*)ui_handle(); ctx; ctx = 0 ) \
|
||||
for(struct nk_panel *layout = ui_ctx->current->layout; layout; ) \
|
||||
for( xx = (layout->at_x += px, layout->bounds.w -= px, 0); layout; layout->at_x -= px, layout->bounds.w += px, layout = 0 )
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// C files
|
||||
|
|
|
@ -15,7 +15,7 @@ size_t dlmalloc_usable_size(void*); // __ANDROID_API__
|
|||
|
||||
// xrealloc --------------------------------------------------------------------
|
||||
|
||||
static __thread uint64_t xstats_current = 0, xstats_total = 0;
|
||||
static __thread uint64_t xstats_current = 0, xstats_total = 0, xstats_allocs = 0;
|
||||
|
||||
void* xrealloc(void* oldptr, size_t size) {
|
||||
// for stats
|
||||
|
@ -34,8 +34,10 @@ void* xrealloc(void* oldptr, size_t size) {
|
|||
// for stats
|
||||
if( oldptr ) {
|
||||
xstats_current += (int64_t)size - (int64_t)oldsize;
|
||||
xstats_allocs -= !size;
|
||||
} else {
|
||||
xstats_current += size;
|
||||
xstats_allocs += !!size;
|
||||
}
|
||||
if( xstats_current > xstats_total ) {
|
||||
xstats_total = xstats_current;
|
||||
|
@ -48,7 +50,8 @@ size_t xsize(void* p) {
|
|||
return 0;
|
||||
}
|
||||
char *xstats(void) {
|
||||
return va("%03u/%03uMB", (unsigned)xstats_current / 1024 / 1024, (unsigned)xstats_total / 1024 / 1024);
|
||||
uint64_t xtra = 0; // xstats_allocs * 65536; // assumes 64K pagesize for every alloc
|
||||
return va("%03u/%03uMB", (unsigned)((xstats_current+xtra) / 1024 / 1024), (unsigned)((xstats_total+xtra) / 1024 / 1024));
|
||||
}
|
||||
|
||||
// stack -----------------------------------------------------------------------
|
||||
|
|
|
@ -28,7 +28,7 @@ const char *OBJTYPES[256] = { 0 }; // = { REPEAT256("") };
|
|||
void *obj_malloc(unsigned sz) {
|
||||
//sz = sizeof(obj) + sz + sizeof(array(obj*))); // useful?
|
||||
obj *ptr = CALLOC(1, sz);
|
||||
OBJ_CTOR_HDR(ptr,1,intern("obj"),sz,OBJTYPE_obj);
|
||||
OBJ_CTOR_HDR(ptr,1,sz,OBJTYPE_obj);
|
||||
return ptr;
|
||||
}
|
||||
void *obj_free(void *o) {
|
||||
|
@ -58,9 +58,9 @@ unsigned obj_typeid(const void *o) {
|
|||
const char *obj_type(const void *o) {
|
||||
return OBJTYPES[ (((obj*)o)->objtype) ];
|
||||
}
|
||||
const char *obj_name(const void *o) {
|
||||
return quark(((obj*)o)->objnameid);
|
||||
}
|
||||
//const char *obj_name(const void *o) {
|
||||
// return quark(((obj*)o)->objnameid);
|
||||
//}
|
||||
int obj_sizeof(const void *o) {
|
||||
return (int)( ((const obj*)o)->objsizew << OBJ_MIN_PRAGMAPACK_BITS );
|
||||
}
|
||||
|
@ -110,8 +110,8 @@ void test_obj_core() {
|
|||
test( obj_id(s) != 0 );
|
||||
test( obj_id(r) != obj_id(s) );
|
||||
|
||||
obj t = obj_ext(obj, "root");
|
||||
obj u = obj_ext(obj, "root");
|
||||
obj t = obj(obj); obj_setname(&t, "root");
|
||||
obj u = obj(obj); obj_setname(&u, "root");
|
||||
|
||||
test(&t);
|
||||
test( 0 == strcmp(obj_type(&t), "obj") );
|
||||
|
@ -248,7 +248,7 @@ void test_obj_scene() {
|
|||
obj_attach(c2, gc2); // +- gc2
|
||||
obj_attach(c2, gc3); // +- gc3
|
||||
|
||||
// obj_dumptree(r);
|
||||
obj_dumptree(r);
|
||||
// puts("---");
|
||||
|
||||
test( obj_parent(r) == 0 );
|
||||
|
@ -285,16 +285,16 @@ void test_obj_scene() {
|
|||
|
||||
static map(int,int) oms;
|
||||
static thread_mutex_t *oms_lock;
|
||||
const char *obj_metaset(const void *o, const char *key, const char *value) {
|
||||
void *obj_setmeta(void *o, const char *key, const char *value) {
|
||||
do_threadlock(oms_lock) {
|
||||
if(!oms) map_init_int(oms);
|
||||
int *q = map_find_or_add(oms, intern(va("%llu-%s",obj_id((obj*)o),key)), 0);
|
||||
if(!*q && !value[0]) {} else *q = intern(value);
|
||||
return quark(*q);
|
||||
return quark(*q), o;
|
||||
}
|
||||
return 0; // unreachable
|
||||
}
|
||||
const char* obj_metaget(const void *o, const char *key) {
|
||||
const char* obj_meta(const void *o, const char *key) {
|
||||
do_threadlock(oms_lock) {
|
||||
if(!oms) map_init_int(oms);
|
||||
int *q = map_find_or_add(oms, intern(va("%llu-%s",obj_id((obj*)o),key)), 0);
|
||||
|
@ -303,12 +303,21 @@ const char* obj_metaget(const void *o, const char *key) {
|
|||
return 0; // unreachable
|
||||
}
|
||||
|
||||
void *obj_setname(void *o, const char *name) {
|
||||
return obj_setmeta(o, "name", name);
|
||||
}
|
||||
const char *obj_name(const void *o) {
|
||||
const char *objname = obj_meta(o, "name");
|
||||
return objname[0] ? objname : "obj";
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void test_obj_metadatas( void *o1 ) {
|
||||
obj *o = (obj *)o1;
|
||||
test( !strcmp("", obj_metaget(o, "has_passed_test")) );
|
||||
test( !strcmp("yes", obj_metaset(o, "has_passed_test", "yes")) );
|
||||
test( !strcmp("yes", obj_metaget(o, "has_passed_test")) );
|
||||
test( !strcmp("", obj_meta(o, "has_passed_test")) );
|
||||
test( obj_setmeta(o, "has_passed_test", "yes") );
|
||||
test( !strcmp("yes", obj_meta(o, "has_passed_test")) );
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -621,16 +630,29 @@ obj *obj_loadmpack(void *o, const char *sav) { // @todo
|
|||
return obj_mergempack(obj_zero(o), sav);
|
||||
}
|
||||
|
||||
static __thread array(char*) obj_stack;
|
||||
static __thread map(void*,array(char*)) obj_stack;
|
||||
int obj_push(const void *o) {
|
||||
char *bin = STRDUP(obj_savebin(o));
|
||||
array_push(obj_stack, bin);
|
||||
if(!obj_stack) map_init_ptr(obj_stack);
|
||||
array(char*) *found = map_find_or_add(obj_stack,(void*)o,0);
|
||||
|
||||
char *bin = STRDUP(obj_saveini(o)); // @todo: savebin
|
||||
array_push(*found, bin);
|
||||
return 1;
|
||||
}
|
||||
int obj_pop(void *o) {
|
||||
char *bin = *array_pop(obj_stack);
|
||||
int rc = !!obj_loadbin(o, bin);
|
||||
return FREE(bin), rc;
|
||||
if(!obj_stack) map_init_ptr(obj_stack);
|
||||
array(char*) *found = map_find_or_add(obj_stack,(void*)o,0);
|
||||
|
||||
char **bin = array_back(*found);
|
||||
if( bin ) {
|
||||
int rc = !!obj_loadini(o, *bin); // @todo: loadbin
|
||||
if( array_count(*found) > 1 ) {
|
||||
FREE(*bin);
|
||||
array_pop(*found);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -792,10 +814,11 @@ void *obj_make(const char *str) {
|
|||
reflect_t *found = map_find(reflects, Tid);
|
||||
if(!found) return 0;
|
||||
|
||||
obj *ptr = CALLOC(1, found->sz + has_components * sizeof(array(obj*)));
|
||||
obj *ptr = CALLOC(1, found->sz + (has_components+1) * sizeof(array(obj*)));
|
||||
void *ret = (T == I ? obj_mergeini : obj_mergejson)(ptr, str);
|
||||
OBJTYPES[ found->objtype ] = found->name;
|
||||
OBJ_CTOR_PTR(ptr,1,found->id,found->sz,found->objtype);
|
||||
OBJ_CTOR_PTR(ptr,1,/*found->id,*/found->sz,found->objtype);
|
||||
obj_setname(ptr, name); // found->id);
|
||||
|
||||
return ptr; // returns partial construction as well. @todo: just return `ret` for a more strict built/failed policy
|
||||
}
|
||||
|
|
|
@ -13,9 +13,10 @@
|
|||
|
||||
/* /!\ if you plan to use pragma pack(1) on any struct, you need #define OBJ_MIN_PRAGMAPACK_BITS 0 at the expense of max class size /!\ */
|
||||
#ifndef OBJ_MIN_PRAGMAPACK_BITS
|
||||
//#define OBJ_MIN_PRAGMAPACK_BITS 3 // allows pragma packs >= 8. objsizew becomes 7<<3, so 1024 bytes max per class (default)
|
||||
#define OBJ_MIN_PRAGMAPACK_BITS 1 // allows pragma packs >= 2. objsizew becomes 7<<1, so 256 bytes max per class
|
||||
//#define OBJ_MIN_PRAGMAPACK_BITS 0 // allows pragma packs >= 1. objsizew becomes 7<<0, so 128 bytes max per class
|
||||
//#define OBJ_MIN_PRAGMAPACK_BITS 3 // allows pragma packs >= 8. objsizew becomes 8<<3, so 2048 bytes max per class (default)
|
||||
#define OBJ_MIN_PRAGMAPACK_BITS 2 // allows pragma packs >= 4. objsizew becomes 8<<2, so 1024 bytes max per class
|
||||
//#define OBJ_MIN_PRAGMAPACK_BITS 1 // allows pragma packs >= 2. objsizew becomes 8<<1, so 512 bytes max per class
|
||||
//#define OBJ_MIN_PRAGMAPACK_BITS 0 // allows pragma packs >= 1. objsizew becomes 8<<0, so 256 bytes max per class
|
||||
#endif
|
||||
|
||||
#define OBJHEADER \
|
||||
|
@ -23,13 +24,12 @@
|
|||
uintptr_t objheader; \
|
||||
struct { \
|
||||
uintptr_t objtype:8; \
|
||||
uintptr_t objheap:1; \
|
||||
uintptr_t objsizew:7; \
|
||||
uintptr_t objsizew:8; \
|
||||
uintptr_t objrefs:8; \
|
||||
uintptr_t objheap:1; \
|
||||
uintptr_t objcomps:1; /* << can be removed? check payload ptr instead? */ \
|
||||
uintptr_t objnameid:16; \
|
||||
uintptr_t objunused:64-8-8-8-1-1-ID_INDEX_BITS-ID_COUNT_BITS; /*19*/ \
|
||||
uintptr_t objid:ID_INDEX_BITS+ID_COUNT_BITS; /*16+3*/ \
|
||||
uintptr_t objunused:64-8-7-1-1-8-16-ID_INDEX_BITS-ID_COUNT_BITS; /*4*/ \
|
||||
}; \
|
||||
};
|
||||
|
||||
|
@ -49,7 +49,7 @@
|
|||
#define OBJTYPEDEF(NAME,N) \
|
||||
enum { OBJTYPE(NAME) = N }; \
|
||||
STATIC_ASSERT( N <= 255 ); \
|
||||
STATIC_ASSERT( (sizeof(NAME) & ((1<<OBJ_MIN_PRAGMAPACK_BITS)-1)) == 0 );
|
||||
STATIC_ASSERT( sizeof(NAME) == ((sizeof(NAME)>>OBJ_MIN_PRAGMAPACK_BITS)<<OBJ_MIN_PRAGMAPACK_BITS) ); // (sizeof(NAME) & ((1<<OBJ_MIN_PRAGMAPACK_BITS)-1)) == 0 );
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// objects
|
||||
|
@ -87,28 +87,25 @@
|
|||
// heap/stack ctor/dtor
|
||||
|
||||
static __thread obj *objtmp;
|
||||
#define OBJ_CTOR_HDR(PTR,HEAP,OBJ_NAMEID,SIZEOF_OBJ,OBJ_TYPE) ( \
|
||||
#define OBJ_CTOR_HDR(PTR,HEAP,SIZEOF_OBJ,OBJ_TYPE) ( \
|
||||
(PTR)->objheader = HEAP ? id_make(PTR) : 0, /*should assign to .objid instead. however, id_make() returns shifted bits already*/ \
|
||||
(PTR)->objnameid = (OBJ_NAMEID), \
|
||||
(PTR)->objtype = (OBJ_TYPE), \
|
||||
(PTR)->objheap = (HEAP), \
|
||||
(PTR)->objsizew = (SIZEOF_OBJ>>OBJ_MIN_PRAGMAPACK_BITS))
|
||||
#define OBJ_CTOR_PTR(PTR,HEAP,OBJ_NAMEID,SIZEOF_OBJ,OBJ_TYPE) ( \
|
||||
OBJ_CTOR_HDR(PTR,HEAP,OBJ_NAMEID,SIZEOF_OBJ,OBJ_TYPE), \
|
||||
#define OBJ_CTOR_PTR(PTR,HEAP,SIZEOF_OBJ,OBJ_TYPE) ( \
|
||||
OBJ_CTOR_HDR(PTR,HEAP,SIZEOF_OBJ,OBJ_TYPE), \
|
||||
obj_ctor(PTR))
|
||||
#define OBJ_CTOR(TYPE, NAME, HEAP, PAYLOAD_SIZE, ...) (TYPE*)( \
|
||||
objtmp = (HEAP ? MALLOC(sizeof(TYPE)+(PAYLOAD_SIZE)) : ALLOCA(sizeof(TYPE)+(PAYLOAD_SIZE))), \
|
||||
*(TYPE*)objtmp = ((TYPE){ {0}, __VA_ARGS__}), \
|
||||
((PAYLOAD_SIZE) ? memset((char*)objtmp + sizeof(TYPE), 0, (PAYLOAD_SIZE)) : objtmp), \
|
||||
( OBJTYPES[ OBJTYPE(TYPE) ] = #TYPE ), \
|
||||
OBJ_CTOR_PTR(objtmp, HEAP,intern(NAME),sizeof(TYPE),OBJTYPE(TYPE)), \
|
||||
OBJ_CTOR_PTR(objtmp, HEAP,sizeof(TYPE),OBJTYPE(TYPE)), \
|
||||
ifdef(debug, (obj_printf)(objtmp, va("%s", callstack(+16))), 0), \
|
||||
objtmp)
|
||||
obj_setname(objtmp, NAME))
|
||||
|
||||
#define obj(TYPE, ...) obj_ext(TYPE, #TYPE, __VA_ARGS__)
|
||||
#define obj_ext(TYPE, NAME, ...) *OBJ_CTOR(TYPE, NAME, 0, sizeof(array(obj*)), __VA_ARGS__)
|
||||
|
||||
#define obj_new(TYPE, ...) obj_new_ext(TYPE, #TYPE, __VA_ARGS__)
|
||||
#define obj(TYPE, ...) *OBJ_CTOR(TYPE, #TYPE, 0, sizeof(array(obj*)), __VA_ARGS__)
|
||||
#define obj_new(TYPE, ...) OBJ_CTOR(TYPE, #TYPE, 1, sizeof(array(obj*)), __VA_ARGS__)
|
||||
#define obj_new_ext(TYPE, NAME, ...) OBJ_CTOR(TYPE, NAME, 1, sizeof(array(obj*)), __VA_ARGS__)
|
||||
|
||||
void* obj_malloc(unsigned sz);
|
||||
|
@ -166,12 +163,10 @@ API extern int (*obj_edit[256])(); ///-
|
|||
// core
|
||||
|
||||
API uintptr_t obj_header(const void *o);
|
||||
|
||||
API uintptr_t obj_id(const void *o);
|
||||
API const char* obj_name(const void *o);
|
||||
|
||||
API unsigned obj_typeid(const void *o);
|
||||
API const char* obj_type(const void *o);
|
||||
API unsigned obj_typeid(const void *o);
|
||||
|
||||
API int obj_sizeof(const void *o);
|
||||
API int obj_size(const void *o); // size of all members together in struct. may include padding bytes.
|
||||
|
@ -191,27 +186,29 @@ API void* obj_unref(void *oo);
|
|||
// ----------------------------------------------------------------------------
|
||||
// scene tree
|
||||
|
||||
// non-recursive
|
||||
#define each_objchild(p,t,o) \
|
||||
#define each_objchild(p,t,o) /*non-recursive*/ \
|
||||
(array(obj*)* children = obj_children(p); children; children = 0) \
|
||||
for(int _i = 1, _end = array_count(*children); _i < _end; ++_i) \
|
||||
for(t *o = (t *)((*children)[_i]); o && 0[*children]; o = 0)
|
||||
for(t *o = (t *)((*children)[_i]); o && (obj_parent(o) == p); o = 0)
|
||||
|
||||
API obj* obj_detach(void *c);
|
||||
API obj* obj_attach(void *o, void *c);
|
||||
|
||||
API obj* obj_root(const void *o);
|
||||
API obj* obj_parent(const void *o);
|
||||
API array(obj*)*obj_children(const void *o);
|
||||
API array(obj*)*obj_siblings(const void *o);
|
||||
API array(obj*)*obj_children(const void *o); // child[0]: parent, child[1]: 1st child, child[2]: 2nd child...
|
||||
API array(obj*)*obj_siblings(const void *o); // child[0]: grandpa, child[1]: sibling1, child[2]: sibling2...
|
||||
|
||||
API int obj_dumptree(const void *o);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// metadata
|
||||
|
||||
API const char* obj_metaset(const void *o, const char *key, const char *value);
|
||||
API const char* obj_metaget(const void *o, const char *key);
|
||||
API void* obj_setmeta(void *o, const char *key, const char *value);
|
||||
API const char* obj_meta(const void *o, const char *key);
|
||||
|
||||
API void* obj_setname(void *o, const char *name);
|
||||
API const char* obj_name(const void *o);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// stl
|
||||
|
@ -277,7 +274,7 @@ API char* entity_save(entity *self);
|
|||
// reflection
|
||||
|
||||
#define each_objmember(oo,TYPE,NAME,PTR) \
|
||||
(array(reflect_t) *found_ = members_find(quark(((obj*)oo)->objnameid)); found_; found_ = 0) \
|
||||
(array(reflect_t) *found_ = members_find(obj_type(oo)); found_; found_ = 0) \
|
||||
for(int it_ = 0, end_ = array_count(*found_); it_ != end_; ++it_ ) \
|
||||
for(reflect_t *R = &(*found_)[it_]; R; R = 0 ) \
|
||||
for(const char *NAME = R->name, *TYPE = R->type; NAME || TYPE; ) \
|
||||
|
|
|
@ -85,38 +85,45 @@ array(reflect_t)* members_find(const char *T) {
|
|||
return map_find(members, intern(T));
|
||||
}
|
||||
|
||||
static
|
||||
void ui_reflect_(const reflect_t *R, const char *filter, int mask) {
|
||||
// debug:
|
||||
// ui_label(va("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_dump(const char *mask) {
|
||||
if( mask == *R->info ) {
|
||||
static __thread char *buf = 0;
|
||||
if( buf ) *buf = '\0';
|
||||
|
||||
struct nk_context *ui_ctx = (struct nk_context *)ui_handle();
|
||||
for ui_push_hspace(16) {
|
||||
array(reflect_t) *T = map_find(members, intern(R->name));
|
||||
/**/ if( T ) {ui_label(strcatf(&buf,"S struct %s@%s", R->name, R->info+1)); for each_array_ptr(*T, reflect_t, it) if(strmatchi(it->name,filter)) ui_reflect_(it,filter,'M'); }
|
||||
else if( R->addr ) ui_label(strcatf(&buf,"F func %s()@%s", R->name, R->info+1));
|
||||
else if( !R->parent ) ui_label(strcatf(&buf,"E enum %s = %d@%s", R->name, R->sz, R->info+1));
|
||||
else ui_label(strcatf(&buf,"M %s %s@%s", R->type, R->name, R->info+1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
API void *ui_handle();
|
||||
int ui_reflect(const char *filter) {
|
||||
if( !filter ) filter = "*";
|
||||
|
||||
int enabled = ui_enabled();
|
||||
ui_disable();
|
||||
|
||||
// ENUMS, then FUNCTIONS, then STRUCTS
|
||||
unsigned masks[] = { 'E', 'F', 'S' };
|
||||
for( int i = 0; i < countof(masks); ++i )
|
||||
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 : "");
|
||||
if( strmatchi(R->name, filter)) {
|
||||
ui_reflect_(R, filter, masks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if( enabled ) ui_enable();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -- tests
|
||||
|
|
|
@ -25,16 +25,16 @@ typedef struct reflect_t {
|
|||
|
||||
// inscribe api
|
||||
|
||||
#define ENUM(V, .../*value_annotations*/) \
|
||||
enum_inscribe(#V,V, "" __VA_ARGS__/*value_annotations*/)
|
||||
#define ENUM(V, ...) \
|
||||
enum_inscribe(#V,V, "E" __VA_ARGS__ " ("FILELINE")")
|
||||
|
||||
#define FUNCTION(F, .../*function_annotations*/) \
|
||||
function_inscribe(#F,(void*)F, "" __VA_ARGS__/*function_annotations*/)
|
||||
#define FUNCTION(F, ...) \
|
||||
function_inscribe(#F,(void*)F, "F" __VA_ARGS__ " ("FILELINE")")
|
||||
|
||||
#define STRUCT(T, type, member, .../*member_annotations*/) \
|
||||
struct_inscribe(#T,sizeof(T),OBJTYPE(T),NULL), \
|
||||
type_inscribe(#type,sizeof(((T){0}).member),"" __VA_ARGS__/*member_annotations*/), \
|
||||
member_inscribe(#T, #member,(uintptr_t)&((T*)0)->member, "" __VA_ARGS__/*member_annotations*/, #type, sizeof(((T){0}).member) )
|
||||
#define STRUCT(T, type, member, ...) \
|
||||
struct_inscribe(#T,sizeof(T),OBJTYPE(T),"S" " ("FILELINE")"), \
|
||||
type_inscribe(#type,sizeof(((T){0}).member),"T" __VA_ARGS__ " ("FILELINE")"), \
|
||||
member_inscribe(#T, #member,(uintptr_t)&((T*)0)->member, "M" __VA_ARGS__ " ("FILELINE")", #type, sizeof(((T){0}).member) )
|
||||
|
||||
// find api
|
||||
|
||||
|
@ -60,6 +60,4 @@ API void struct_inscribe(const char *T,unsigned Tsz,unsigned OBJTY
|
|||
API void member_inscribe(const char *T, const char *M,unsigned Msz, const char *infos, const char *type, unsigned bytes);
|
||||
API void function_inscribe(const char *F,void *func,const char *infos);
|
||||
|
||||
API void reflect_print(const char *symbol);
|
||||
API void reflect_dump(const char *mask);
|
||||
API void reflect_init();
|
||||
API int ui_reflect(const char *mask); // *, model* or NULL
|
||||
|
|
|
@ -1530,7 +1530,7 @@ if( font ) nk_style_pop_color(ui_ctx);
|
|||
if( font ) nk_style_pop_font(ui_ctx);
|
||||
|
||||
if (split && is_hovering && !ui_has_active_popups && nk_window_has_focus(ui_ctx)) {
|
||||
nk_tooltip(ui_ctx, split + 1);
|
||||
nk_tooltip(ui_ctx, split + 1); // @fixme: not working under ui_disable() state
|
||||
}
|
||||
|
||||
layout->at_x -= spacing;
|
||||
|
|
|
@ -272,7 +272,7 @@ void glNewFrame() {
|
|||
|
||||
bool window_create_from_handle(void *handle, float scale, unsigned flags) {
|
||||
// abort run if any test suite failed in unit-test mode
|
||||
ifdef(debug, if( flag("--test-only") ) exit( test_errors ? -test_errors : 0 ));
|
||||
ifdef(debug, if( flag("--test") ) exit( test_errors ? -test_errors : 0 ));
|
||||
|
||||
glfw_init();
|
||||
v4k_init();
|
||||
|
@ -749,6 +749,9 @@ int window_frame_begin() {
|
|||
if( choice == 2 ) editor_send("key_battery","1");
|
||||
}
|
||||
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_WATER " Reflection", "Debug.Reflect") {
|
||||
ui_reflect("*");
|
||||
}
|
||||
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_EXTENSION " Plugins", "Debug.Plugins") {
|
||||
// @todo. include VCS
|
||||
|
|
|
@ -221679,6 +221679,7 @@ nk_glfw3_render(struct nk_glfw* glfw, enum nk_anti_aliasing AA, int max_vertex_b
|
|||
|
||||
/* iterate over and execute each draw command */
|
||||
nk_draw_foreach(cmd, &glfw->ctx, &dev->cmds)
|
||||
if(glfw->height > 0) //< @r-lyeh: fix opengl/scissor error when win is minimized (h==0)
|
||||
{
|
||||
if (!cmd->elem_count) continue;
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id);
|
||||
|
|
152
engine/v4k.c
152
engine/v4k.c
|
@ -99,8 +99,16 @@
|
|||
#endif
|
||||
|
||||
#define do_threadlock(mutexptr) \
|
||||
for( int init_ = !!(mutexptr) || (thread_mutex_init( (mutexptr) = CALLOC(1, sizeof(thread_mutex_t)) ), 1); init_; init_ = 0) \
|
||||
for( int lock_ = (thread_mutex_lock( mutexptr ), 1); lock_; lock_ = (thread_mutex_unlock( mutexptr ), 0) )
|
||||
for( int init_ = !!(mutexptr) || (thread_mutex_init( (mutexptr) = CALLOC(1, sizeof(thread_mutex_t)) ), 1); init_; init_ = 0) \
|
||||
for( int lock_ = (thread_mutex_lock( mutexptr ), 1); lock_; lock_ = (thread_mutex_unlock( mutexptr ), 0) )
|
||||
|
||||
API void *ui_handle();
|
||||
#define ui_push_hspace(px) \
|
||||
(int xx = px; xx; xx = 0) \
|
||||
for(struct nk_context *ctx = (struct nk_context*)ui_handle(); ctx; ctx = 0 ) \
|
||||
for(struct nk_panel *layout = ui_ctx->current->layout; layout; ) \
|
||||
for( xx = (layout->at_x += px, layout->bounds.w -= px, 0); layout; layout->at_x -= px, layout->bounds.w += px, layout = 0 )
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// C files
|
||||
|
@ -10191,7 +10199,7 @@ size_t dlmalloc_usable_size(void*); // __ANDROID_API__
|
|||
|
||||
// xrealloc --------------------------------------------------------------------
|
||||
|
||||
static __thread uint64_t xstats_current = 0, xstats_total = 0;
|
||||
static __thread uint64_t xstats_current = 0, xstats_total = 0, xstats_allocs = 0;
|
||||
|
||||
void* xrealloc(void* oldptr, size_t size) {
|
||||
// for stats
|
||||
|
@ -10210,8 +10218,10 @@ void* xrealloc(void* oldptr, size_t size) {
|
|||
// for stats
|
||||
if( oldptr ) {
|
||||
xstats_current += (int64_t)size - (int64_t)oldsize;
|
||||
xstats_allocs -= !size;
|
||||
} else {
|
||||
xstats_current += size;
|
||||
xstats_allocs += !!size;
|
||||
}
|
||||
if( xstats_current > xstats_total ) {
|
||||
xstats_total = xstats_current;
|
||||
|
@ -10224,7 +10234,8 @@ size_t xsize(void* p) {
|
|||
return 0;
|
||||
}
|
||||
char *xstats(void) {
|
||||
return va("%03u/%03uMB", (unsigned)xstats_current / 1024 / 1024, (unsigned)xstats_total / 1024 / 1024);
|
||||
uint64_t xtra = 0; // xstats_allocs * 65536; // assumes 64K pagesize for every alloc
|
||||
return va("%03u/%03uMB", (unsigned)((xstats_current+xtra) / 1024 / 1024), (unsigned)((xstats_total+xtra) / 1024 / 1024));
|
||||
}
|
||||
|
||||
// stack -----------------------------------------------------------------------
|
||||
|
@ -12961,38 +12972,45 @@ array(reflect_t)* members_find(const char *T) {
|
|||
return map_find(members, intern(T));
|
||||
}
|
||||
|
||||
static
|
||||
void ui_reflect_(const reflect_t *R, const char *filter, int mask) {
|
||||
// debug:
|
||||
// ui_label(va("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_dump(const char *mask) {
|
||||
if( mask == *R->info ) {
|
||||
static __thread char *buf = 0;
|
||||
if( buf ) *buf = '\0';
|
||||
|
||||
struct nk_context *ui_ctx = (struct nk_context *)ui_handle();
|
||||
for ui_push_hspace(16) {
|
||||
array(reflect_t) *T = map_find(members, intern(R->name));
|
||||
/**/ if( T ) {ui_label(strcatf(&buf,"S struct %s@%s", R->name, R->info+1)); for each_array_ptr(*T, reflect_t, it) if(strmatchi(it->name,filter)) ui_reflect_(it,filter,'M'); }
|
||||
else if( R->addr ) ui_label(strcatf(&buf,"F func %s()@%s", R->name, R->info+1));
|
||||
else if( !R->parent ) ui_label(strcatf(&buf,"E enum %s = %d@%s", R->name, R->sz, R->info+1));
|
||||
else ui_label(strcatf(&buf,"M %s %s@%s", R->type, R->name, R->info+1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
API void *ui_handle();
|
||||
int ui_reflect(const char *filter) {
|
||||
if( !filter ) filter = "*";
|
||||
|
||||
int enabled = ui_enabled();
|
||||
ui_disable();
|
||||
|
||||
// ENUMS, then FUNCTIONS, then STRUCTS
|
||||
unsigned masks[] = { 'E', 'F', 'S' };
|
||||
for( int i = 0; i < countof(masks); ++i )
|
||||
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 : "");
|
||||
if( strmatchi(R->name, filter)) {
|
||||
ui_reflect_(R, filter, masks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if( enabled ) ui_enable();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -- tests
|
||||
|
@ -22281,7 +22299,7 @@ if( font ) nk_style_pop_color(ui_ctx);
|
|||
if( font ) nk_style_pop_font(ui_ctx);
|
||||
|
||||
if (split && is_hovering && !ui_has_active_popups && nk_window_has_focus(ui_ctx)) {
|
||||
nk_tooltip(ui_ctx, split + 1);
|
||||
nk_tooltip(ui_ctx, split + 1); // @fixme: not working under ui_disable() state
|
||||
}
|
||||
|
||||
layout->at_x -= spacing;
|
||||
|
@ -23781,7 +23799,7 @@ void glNewFrame() {
|
|||
|
||||
bool window_create_from_handle(void *handle, float scale, unsigned flags) {
|
||||
// abort run if any test suite failed in unit-test mode
|
||||
ifdef(debug, if( flag("--test-only") ) exit( test_errors ? -test_errors : 0 ));
|
||||
ifdef(debug, if( flag("--test") ) exit( test_errors ? -test_errors : 0 ));
|
||||
|
||||
glfw_init();
|
||||
v4k_init();
|
||||
|
@ -24258,6 +24276,9 @@ int window_frame_begin() {
|
|||
if( choice == 2 ) editor_send("key_battery","1");
|
||||
}
|
||||
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_WATER " Reflection", "Debug.Reflect") {
|
||||
ui_reflect("*");
|
||||
}
|
||||
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_EXTENSION " Plugins", "Debug.Plugins") {
|
||||
// @todo. include VCS
|
||||
|
@ -24823,7 +24844,7 @@ const char *OBJTYPES[256] = { 0 }; // = { REPEAT256("") };
|
|||
void *obj_malloc(unsigned sz) {
|
||||
//sz = sizeof(obj) + sz + sizeof(array(obj*))); // useful?
|
||||
obj *ptr = CALLOC(1, sz);
|
||||
OBJ_CTOR_HDR(ptr,1,intern("obj"),sz,OBJTYPE_obj);
|
||||
OBJ_CTOR_HDR(ptr,1,sz,OBJTYPE_obj);
|
||||
return ptr;
|
||||
}
|
||||
void *obj_free(void *o) {
|
||||
|
@ -24853,9 +24874,9 @@ unsigned obj_typeid(const void *o) {
|
|||
const char *obj_type(const void *o) {
|
||||
return OBJTYPES[ (((obj*)o)->objtype) ];
|
||||
}
|
||||
const char *obj_name(const void *o) {
|
||||
return quark(((obj*)o)->objnameid);
|
||||
}
|
||||
//const char *obj_name(const void *o) {
|
||||
// return quark(((obj*)o)->objnameid);
|
||||
//}
|
||||
int obj_sizeof(const void *o) {
|
||||
return (int)( ((const obj*)o)->objsizew << OBJ_MIN_PRAGMAPACK_BITS );
|
||||
}
|
||||
|
@ -24905,8 +24926,8 @@ void test_obj_core() {
|
|||
test( obj_id(s) != 0 );
|
||||
test( obj_id(r) != obj_id(s) );
|
||||
|
||||
obj t = obj_ext(obj, "root");
|
||||
obj u = obj_ext(obj, "root");
|
||||
obj t = obj(obj); obj_setname(&t, "root");
|
||||
obj u = obj(obj); obj_setname(&u, "root");
|
||||
|
||||
test(&t);
|
||||
test( 0 == strcmp(obj_type(&t), "obj") );
|
||||
|
@ -25043,7 +25064,7 @@ void test_obj_scene() {
|
|||
obj_attach(c2, gc2); // +- gc2
|
||||
obj_attach(c2, gc3); // +- gc3
|
||||
|
||||
// obj_dumptree(r);
|
||||
obj_dumptree(r);
|
||||
// puts("---");
|
||||
|
||||
test( obj_parent(r) == 0 );
|
||||
|
@ -25080,16 +25101,16 @@ void test_obj_scene() {
|
|||
|
||||
static map(int,int) oms;
|
||||
static thread_mutex_t *oms_lock;
|
||||
const char *obj_metaset(const void *o, const char *key, const char *value) {
|
||||
void *obj_setmeta(void *o, const char *key, const char *value) {
|
||||
do_threadlock(oms_lock) {
|
||||
if(!oms) map_init_int(oms);
|
||||
int *q = map_find_or_add(oms, intern(va("%llu-%s",obj_id((obj*)o),key)), 0);
|
||||
if(!*q && !value[0]) {} else *q = intern(value);
|
||||
return quark(*q);
|
||||
return quark(*q), o;
|
||||
}
|
||||
return 0; // unreachable
|
||||
}
|
||||
const char* obj_metaget(const void *o, const char *key) {
|
||||
const char* obj_meta(const void *o, const char *key) {
|
||||
do_threadlock(oms_lock) {
|
||||
if(!oms) map_init_int(oms);
|
||||
int *q = map_find_or_add(oms, intern(va("%llu-%s",obj_id((obj*)o),key)), 0);
|
||||
|
@ -25098,12 +25119,21 @@ const char* obj_metaget(const void *o, const char *key) {
|
|||
return 0; // unreachable
|
||||
}
|
||||
|
||||
void *obj_setname(void *o, const char *name) {
|
||||
return obj_setmeta(o, "name", name);
|
||||
}
|
||||
const char *obj_name(const void *o) {
|
||||
const char *objname = obj_meta(o, "name");
|
||||
return objname[0] ? objname : "obj";
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void test_obj_metadatas( void *o1 ) {
|
||||
obj *o = (obj *)o1;
|
||||
test( !strcmp("", obj_metaget(o, "has_passed_test")) );
|
||||
test( !strcmp("yes", obj_metaset(o, "has_passed_test", "yes")) );
|
||||
test( !strcmp("yes", obj_metaget(o, "has_passed_test")) );
|
||||
test( !strcmp("", obj_meta(o, "has_passed_test")) );
|
||||
test( obj_setmeta(o, "has_passed_test", "yes") );
|
||||
test( !strcmp("yes", obj_meta(o, "has_passed_test")) );
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -25416,16 +25446,29 @@ obj *obj_loadmpack(void *o, const char *sav) { // @todo
|
|||
return obj_mergempack(obj_zero(o), sav);
|
||||
}
|
||||
|
||||
static __thread array(char*) obj_stack;
|
||||
static __thread map(void*,array(char*)) obj_stack;
|
||||
int obj_push(const void *o) {
|
||||
char *bin = STRDUP(obj_savebin(o));
|
||||
array_push(obj_stack, bin);
|
||||
if(!obj_stack) map_init_ptr(obj_stack);
|
||||
array(char*) *found = map_find_or_add(obj_stack,(void*)o,0);
|
||||
|
||||
char *bin = STRDUP(obj_saveini(o)); // @todo: savebin
|
||||
array_push(*found, bin);
|
||||
return 1;
|
||||
}
|
||||
int obj_pop(void *o) {
|
||||
char *bin = *array_pop(obj_stack);
|
||||
int rc = !!obj_loadbin(o, bin);
|
||||
return FREE(bin), rc;
|
||||
if(!obj_stack) map_init_ptr(obj_stack);
|
||||
array(char*) *found = map_find_or_add(obj_stack,(void*)o,0);
|
||||
|
||||
char **bin = array_back(*found);
|
||||
if( bin ) {
|
||||
int rc = !!obj_loadini(o, *bin); // @todo: loadbin
|
||||
if( array_count(*found) > 1 ) {
|
||||
FREE(*bin);
|
||||
array_pop(*found);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -25587,10 +25630,11 @@ void *obj_make(const char *str) {
|
|||
reflect_t *found = map_find(reflects, Tid);
|
||||
if(!found) return 0;
|
||||
|
||||
obj *ptr = CALLOC(1, found->sz + has_components * sizeof(array(obj*)));
|
||||
obj *ptr = CALLOC(1, found->sz + (has_components+1) * sizeof(array(obj*)));
|
||||
void *ret = (T == I ? obj_mergeini : obj_mergejson)(ptr, str);
|
||||
OBJTYPES[ found->objtype ] = found->name;
|
||||
OBJ_CTOR_PTR(ptr,1,found->id,found->sz,found->objtype);
|
||||
OBJ_CTOR_PTR(ptr,1,/*found->id,*/found->sz,found->objtype);
|
||||
obj_setname(ptr, name); // found->id);
|
||||
|
||||
return ptr; // returns partial construction as well. @todo: just return `ret` for a more strict built/failed policy
|
||||
}
|
||||
|
|
75
engine/v4k.h
75
engine/v4k.h
|
@ -2659,9 +2659,10 @@ API int64_t client_join(const char *ip, int port);
|
|||
|
||||
/* /!\ if you plan to use pragma pack(1) on any struct, you need #define OBJ_MIN_PRAGMAPACK_BITS 0 at the expense of max class size /!\ */
|
||||
#ifndef OBJ_MIN_PRAGMAPACK_BITS
|
||||
//#define OBJ_MIN_PRAGMAPACK_BITS 3 // allows pragma packs >= 8. objsizew becomes 7<<3, so 1024 bytes max per class (default)
|
||||
#define OBJ_MIN_PRAGMAPACK_BITS 1 // allows pragma packs >= 2. objsizew becomes 7<<1, so 256 bytes max per class
|
||||
//#define OBJ_MIN_PRAGMAPACK_BITS 0 // allows pragma packs >= 1. objsizew becomes 7<<0, so 128 bytes max per class
|
||||
//#define OBJ_MIN_PRAGMAPACK_BITS 3 // allows pragma packs >= 8. objsizew becomes 8<<3, so 2048 bytes max per class (default)
|
||||
#define OBJ_MIN_PRAGMAPACK_BITS 2 // allows pragma packs >= 4. objsizew becomes 8<<2, so 1024 bytes max per class
|
||||
//#define OBJ_MIN_PRAGMAPACK_BITS 1 // allows pragma packs >= 2. objsizew becomes 8<<1, so 512 bytes max per class
|
||||
//#define OBJ_MIN_PRAGMAPACK_BITS 0 // allows pragma packs >= 1. objsizew becomes 8<<0, so 256 bytes max per class
|
||||
#endif
|
||||
|
||||
#define OBJHEADER \
|
||||
|
@ -2669,13 +2670,12 @@ API int64_t client_join(const char *ip, int port);
|
|||
uintptr_t objheader; \
|
||||
struct { \
|
||||
uintptr_t objtype:8; \
|
||||
uintptr_t objheap:1; \
|
||||
uintptr_t objsizew:7; \
|
||||
uintptr_t objsizew:8; \
|
||||
uintptr_t objrefs:8; \
|
||||
uintptr_t objheap:1; \
|
||||
uintptr_t objcomps:1; /* << can be removed? check payload ptr instead? */ \
|
||||
uintptr_t objnameid:16; \
|
||||
uintptr_t objunused:64-8-8-8-1-1-ID_INDEX_BITS-ID_COUNT_BITS; /*19*/ \
|
||||
uintptr_t objid:ID_INDEX_BITS+ID_COUNT_BITS; /*16+3*/ \
|
||||
uintptr_t objunused:64-8-7-1-1-8-16-ID_INDEX_BITS-ID_COUNT_BITS; /*4*/ \
|
||||
}; \
|
||||
};
|
||||
|
||||
|
@ -2695,7 +2695,7 @@ API int64_t client_join(const char *ip, int port);
|
|||
#define OBJTYPEDEF(NAME,N) \
|
||||
enum { OBJTYPE(NAME) = N }; \
|
||||
STATIC_ASSERT( N <= 255 ); \
|
||||
STATIC_ASSERT( (sizeof(NAME) & ((1<<OBJ_MIN_PRAGMAPACK_BITS)-1)) == 0 );
|
||||
STATIC_ASSERT( sizeof(NAME) == ((sizeof(NAME)>>OBJ_MIN_PRAGMAPACK_BITS)<<OBJ_MIN_PRAGMAPACK_BITS) ); // (sizeof(NAME) & ((1<<OBJ_MIN_PRAGMAPACK_BITS)-1)) == 0 );
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// objects
|
||||
|
@ -2733,28 +2733,25 @@ API int64_t client_join(const char *ip, int port);
|
|||
// heap/stack ctor/dtor
|
||||
|
||||
static __thread obj *objtmp;
|
||||
#define OBJ_CTOR_HDR(PTR,HEAP,OBJ_NAMEID,SIZEOF_OBJ,OBJ_TYPE) ( \
|
||||
#define OBJ_CTOR_HDR(PTR,HEAP,SIZEOF_OBJ,OBJ_TYPE) ( \
|
||||
(PTR)->objheader = HEAP ? id_make(PTR) : 0, /*should assign to .objid instead. however, id_make() returns shifted bits already*/ \
|
||||
(PTR)->objnameid = (OBJ_NAMEID), \
|
||||
(PTR)->objtype = (OBJ_TYPE), \
|
||||
(PTR)->objheap = (HEAP), \
|
||||
(PTR)->objsizew = (SIZEOF_OBJ>>OBJ_MIN_PRAGMAPACK_BITS))
|
||||
#define OBJ_CTOR_PTR(PTR,HEAP,OBJ_NAMEID,SIZEOF_OBJ,OBJ_TYPE) ( \
|
||||
OBJ_CTOR_HDR(PTR,HEAP,OBJ_NAMEID,SIZEOF_OBJ,OBJ_TYPE), \
|
||||
#define OBJ_CTOR_PTR(PTR,HEAP,SIZEOF_OBJ,OBJ_TYPE) ( \
|
||||
OBJ_CTOR_HDR(PTR,HEAP,SIZEOF_OBJ,OBJ_TYPE), \
|
||||
obj_ctor(PTR))
|
||||
#define OBJ_CTOR(TYPE, NAME, HEAP, PAYLOAD_SIZE, ...) (TYPE*)( \
|
||||
objtmp = (HEAP ? MALLOC(sizeof(TYPE)+(PAYLOAD_SIZE)) : ALLOCA(sizeof(TYPE)+(PAYLOAD_SIZE))), \
|
||||
*(TYPE*)objtmp = ((TYPE){ {0}, __VA_ARGS__}), \
|
||||
((PAYLOAD_SIZE) ? memset((char*)objtmp + sizeof(TYPE), 0, (PAYLOAD_SIZE)) : objtmp), \
|
||||
( OBJTYPES[ OBJTYPE(TYPE) ] = #TYPE ), \
|
||||
OBJ_CTOR_PTR(objtmp, HEAP,intern(NAME),sizeof(TYPE),OBJTYPE(TYPE)), \
|
||||
OBJ_CTOR_PTR(objtmp, HEAP,sizeof(TYPE),OBJTYPE(TYPE)), \
|
||||
ifdef(debug, (obj_printf)(objtmp, va("%s", callstack(+16))), 0), \
|
||||
objtmp)
|
||||
obj_setname(objtmp, NAME))
|
||||
|
||||
#define obj(TYPE, ...) obj_ext(TYPE, #TYPE, __VA_ARGS__)
|
||||
#define obj_ext(TYPE, NAME, ...) *OBJ_CTOR(TYPE, NAME, 0, sizeof(array(obj*)), __VA_ARGS__)
|
||||
|
||||
#define obj_new(TYPE, ...) obj_new_ext(TYPE, #TYPE, __VA_ARGS__)
|
||||
#define obj(TYPE, ...) *OBJ_CTOR(TYPE, #TYPE, 0, sizeof(array(obj*)), __VA_ARGS__)
|
||||
#define obj_new(TYPE, ...) OBJ_CTOR(TYPE, #TYPE, 1, sizeof(array(obj*)), __VA_ARGS__)
|
||||
#define obj_new_ext(TYPE, NAME, ...) OBJ_CTOR(TYPE, NAME, 1, sizeof(array(obj*)), __VA_ARGS__)
|
||||
|
||||
void* obj_malloc(unsigned sz);
|
||||
|
@ -2812,12 +2809,10 @@ API extern int (*obj_edit[256])(); ///-
|
|||
// core
|
||||
|
||||
API uintptr_t obj_header(const void *o);
|
||||
|
||||
API uintptr_t obj_id(const void *o);
|
||||
API const char* obj_name(const void *o);
|
||||
|
||||
API unsigned obj_typeid(const void *o);
|
||||
API const char* obj_type(const void *o);
|
||||
API unsigned obj_typeid(const void *o);
|
||||
|
||||
API int obj_sizeof(const void *o);
|
||||
API int obj_size(const void *o); // size of all members together in struct. may include padding bytes.
|
||||
|
@ -2837,27 +2832,29 @@ API void* obj_unref(void *oo);
|
|||
// ----------------------------------------------------------------------------
|
||||
// scene tree
|
||||
|
||||
// non-recursive
|
||||
#define each_objchild(p,t,o) \
|
||||
#define each_objchild(p,t,o) /*non-recursive*/ \
|
||||
(array(obj*)* children = obj_children(p); children; children = 0) \
|
||||
for(int _i = 1, _end = array_count(*children); _i < _end; ++_i) \
|
||||
for(t *o = (t *)((*children)[_i]); o && 0[*children]; o = 0)
|
||||
for(t *o = (t *)((*children)[_i]); o && (obj_parent(o) == p); o = 0)
|
||||
|
||||
API obj* obj_detach(void *c);
|
||||
API obj* obj_attach(void *o, void *c);
|
||||
|
||||
API obj* obj_root(const void *o);
|
||||
API obj* obj_parent(const void *o);
|
||||
API array(obj*)*obj_children(const void *o);
|
||||
API array(obj*)*obj_siblings(const void *o);
|
||||
API array(obj*)*obj_children(const void *o); // child[0]: parent, child[1]: 1st child, child[2]: 2nd child...
|
||||
API array(obj*)*obj_siblings(const void *o); // child[0]: grandpa, child[1]: sibling1, child[2]: sibling2...
|
||||
|
||||
API int obj_dumptree(const void *o);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// metadata
|
||||
|
||||
API const char* obj_metaset(const void *o, const char *key, const char *value);
|
||||
API const char* obj_metaget(const void *o, const char *key);
|
||||
API void* obj_setmeta(void *o, const char *key, const char *value);
|
||||
API const char* obj_meta(const void *o, const char *key);
|
||||
|
||||
API void* obj_setname(void *o, const char *name);
|
||||
API const char* obj_name(const void *o);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// stl
|
||||
|
@ -2923,7 +2920,7 @@ API char* entity_save(entity *self);
|
|||
// reflection
|
||||
|
||||
#define each_objmember(oo,TYPE,NAME,PTR) \
|
||||
(array(reflect_t) *found_ = members_find(quark(((obj*)oo)->objnameid)); found_; found_ = 0) \
|
||||
(array(reflect_t) *found_ = members_find(obj_type(oo)); found_; found_ = 0) \
|
||||
for(int it_ = 0, end_ = array_count(*found_); it_ != end_; ++it_ ) \
|
||||
for(reflect_t *R = &(*found_)[it_]; R; R = 0 ) \
|
||||
for(const char *NAME = R->name, *TYPE = R->type; NAME || TYPE; ) \
|
||||
|
@ -3012,16 +3009,16 @@ typedef struct reflect_t {
|
|||
|
||||
// inscribe api
|
||||
|
||||
#define ENUM(V, .../*value_annotations*/) \
|
||||
enum_inscribe(#V,V, "" __VA_ARGS__/*value_annotations*/)
|
||||
#define ENUM(V, ...) \
|
||||
enum_inscribe(#V,V, "E" __VA_ARGS__ " ("FILELINE")")
|
||||
|
||||
#define FUNCTION(F, .../*function_annotations*/) \
|
||||
function_inscribe(#F,(void*)F, "" __VA_ARGS__/*function_annotations*/)
|
||||
#define FUNCTION(F, ...) \
|
||||
function_inscribe(#F,(void*)F, "F" __VA_ARGS__ " ("FILELINE")")
|
||||
|
||||
#define STRUCT(T, type, member, .../*member_annotations*/) \
|
||||
struct_inscribe(#T,sizeof(T),OBJTYPE(T),NULL), \
|
||||
type_inscribe(#type,sizeof(((T){0}).member),"" __VA_ARGS__/*member_annotations*/), \
|
||||
member_inscribe(#T, #member,(uintptr_t)&((T*)0)->member, "" __VA_ARGS__/*member_annotations*/, #type, sizeof(((T){0}).member) )
|
||||
#define STRUCT(T, type, member, ...) \
|
||||
struct_inscribe(#T,sizeof(T),OBJTYPE(T),"S" " ("FILELINE")"), \
|
||||
type_inscribe(#type,sizeof(((T){0}).member),"T" __VA_ARGS__ " ("FILELINE")"), \
|
||||
member_inscribe(#T, #member,(uintptr_t)&((T*)0)->member, "M" __VA_ARGS__ " ("FILELINE")", #type, sizeof(((T){0}).member) )
|
||||
|
||||
// find api
|
||||
|
||||
|
@ -3047,9 +3044,7 @@ API void struct_inscribe(const char *T,unsigned Tsz,unsigned OBJTY
|
|||
API void member_inscribe(const char *T, const char *M,unsigned Msz, const char *infos, const char *type, unsigned bytes);
|
||||
API void function_inscribe(const char *F,void *func,const char *infos);
|
||||
|
||||
API void reflect_print(const char *symbol);
|
||||
API void reflect_dump(const char *mask);
|
||||
API void reflect_init();
|
||||
API int ui_reflect(const char *mask); // *, model* or NULL
|
||||
#line 0
|
||||
|
||||
#line 1 "engine/split/v4k_render.h"
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
// ### editor (v4)
|
||||
// Bring in remote datas into the editor.
|
||||
// Go social & marketplace. Allow others to expand, share, publish, subscribe, discuss their sub-editors within a small community.
|
||||
// I really like the way the way OpenFrameworks.cc does their addons, and I think we should do same: just discover and monitor github repos, and list everything on a website (fwk- prefix?).
|
||||
// I really like the way the way OpenFrameworks.cc does their addons, and I think we should do same: just discover and monitor github repos, and list everything on a website (v4k- prefix?).
|
||||
// Wishlist for a github-based community flow: discovery, transparent installs, publish on github, star there, watch commits & releases, track issues+discussions, etc
|
||||
//
|
||||
// We should have a generic, extensible, script/plugin-driven, working editor at this point (hopefully) that does not require maintenance.
|
||||
|
@ -153,7 +153,7 @@
|
|||
// - ecs: sys are modules, ecs: char *messaging, ecs: filesystem (e/dir,c/files,s/dll)
|
||||
// - world: streaming, migration
|
||||
|
||||
#include "fwk.h"
|
||||
#include "v4k.h"
|
||||
|
||||
// #include "labs.vm/ecs.c"
|
||||
|
||||
|
@ -839,10 +839,10 @@ void editor_obj_render_max_properties(void *obj, const char *mask) { // headless
|
|||
// main editor interface
|
||||
|
||||
void editor_render_menubar() {
|
||||
int alts = input(KEY_LALT) || input(KEY_RALT); // @todo: move to fwk.c
|
||||
int ctrls = input(KEY_LCTRL) || input(KEY_RCTRL); // @todo: move to fwk.c
|
||||
int shifts = input(KEY_LSHIFT) || input(KEY_RSHIFT); // @todo: move to fwk.c
|
||||
int mods = alts || ctrls || shifts; // @todo: move to fwk.c
|
||||
int alts = input(KEY_LALT) || input(KEY_RALT); // @todo: move to v4k.c
|
||||
int ctrls = input(KEY_LCTRL) || input(KEY_RCTRL); // @todo: move to v4k.c
|
||||
int shifts = input(KEY_LSHIFT) || input(KEY_RSHIFT); // @todo: move to v4k.c
|
||||
int mods = alts || ctrls || shifts; // @todo: move to v4k.c
|
||||
if( input_down(KEY_F5) ) editor_key = key_reload;
|
||||
if( input_down(KEY_F11) ) editor_key = key_fullscreen;
|
||||
if( input_down(KEY_PAUSE) ) editor_key = key_pause;
|
||||
|
@ -1022,8 +1022,8 @@ void editor_render_menubar() {
|
|||
}
|
||||
}
|
||||
|
||||
int do_context_cmd = 0;
|
||||
void *do_context_obj = 0;
|
||||
uint64_t do_context_cmd = 0;
|
||||
void *do_context_obj = 0;
|
||||
|
||||
void editor_obj_render_properties_recursively(void *obj, const char *mask) {
|
||||
array(void*) *found = map_find(editor_children, obj);
|
||||
|
@ -1573,7 +1573,7 @@ int main() {
|
|||
if( GAME_JUMP_DOWN ) if( jump_timer == 0 ) jump_timer = editor_ss();
|
||||
jump_delta = clampf(editor_ss() - jump_timer, 0, jump_ss) * (1.0/jump_ss);
|
||||
if( jump_delta >= 1 ) { jump_timer = 0; }
|
||||
float y = ease_ping_pong( jump_delta, ease_out_expo, ease_out_circ);
|
||||
float y = ease_ping_pong( jump_delta, EASE_OUT|EASE_EXPO, EASE_OUT|EASE_CIRC);
|
||||
girl_p.y = y * jump_h;
|
||||
|
||||
// punch controller
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
- [ ] Editor: GUI pass: timeline and data tracks, node graphs. <!-- worthy: will be reused into materials, animgraphs and blueprints -->
|
||||
*/
|
||||
|
||||
#include "fwk.c"
|
||||
#include "v4k.c"
|
||||
#include "editor2.h" // old editor interface
|
||||
|
||||
#define ui_push_hspace(px) \
|
||||
|
|
|
@ -155,10 +155,10 @@ enum editor_keys {
|
|||
void editor_menubar() {
|
||||
do_once editor_init();
|
||||
|
||||
int alts = input(KEY_LALT) || input(KEY_RALT); // @todo: move to fwk.c
|
||||
int ctrls = input(KEY_LCTRL) || input(KEY_RCTRL); // @todo: move to fwk.c
|
||||
int shifts = input(KEY_LSHIFT) || input(KEY_RSHIFT); // @todo: move to fwk.c
|
||||
int mods = alts || ctrls || shifts; // @todo: move to fwk.c
|
||||
int alts = input(KEY_LALT) || input(KEY_RALT); // @todo: move to v4k.c
|
||||
int ctrls = input(KEY_LCTRL) || input(KEY_RCTRL); // @todo: move to v4k.c
|
||||
int shifts = input(KEY_LSHIFT) || input(KEY_RSHIFT); // @todo: move to v4k.c
|
||||
int mods = alts || ctrls || shifts; // @todo: move to v4k.c
|
||||
if( input_down(KEY_F5) ) editor_key = key_reload;
|
||||
if( input_down(KEY_F11) ) editor_key = key_fullscreen;
|
||||
if( input_down(KEY_PAUSE) ) editor_key = key_pause;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//#define META_DEMO
|
||||
|
||||
#include "fwk.h"
|
||||
#include "v4k.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#define FWK_C
|
||||
#include "fwk.h"
|
||||
#define V4K_C
|
||||
#include "v4k.h"
|
||||
|
||||
bool parse_struct(const char *line) {
|
||||
return strstr(line, "s""truct ");
|
||||
|
|
|
@ -21,9 +21,9 @@ cl ..\editor2.c -I ..\..\tools -DCOOK_ON_DEMAND
|
|||
pushd ..\.. && call make amalgamation && popd
|
||||
|
||||
taskkill /im "oscedit.exe" > nul 2> nul
|
||||
call ..\..\tools\tcc oscgame.c -I ..\.. -DFWK_IMPLEMENTATION -DCOOK_ON_DEMAND %*
|
||||
call ..\..\tools\tcc oscsend.c -I ..\.. -DFWK_IMPLEMENTATION -DCOOK_ON_DEMAND %*
|
||||
call ..\..\tools\tcc oscedit.c -I ..\.. -DFWK_IMPLEMENTATION -DCOOK_ON_DEMAND %* && start oscedit.exe
|
||||
call ..\..\tools\tcc oscgame.c -I ..\.. -DV4K_IMPLEMENTATION -DCOOK_ON_DEMAND %*
|
||||
call ..\..\tools\tcc oscsend.c -I ..\.. -DV4K_IMPLEMENTATION -DCOOK_ON_DEMAND %*
|
||||
call ..\..\tools\tcc oscedit.c -I ..\.. -DV4K_IMPLEMENTATION -DCOOK_ON_DEMAND %* && start oscedit.exe
|
||||
|
||||
timeout 3
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "fwk.h"
|
||||
#include "v4k.h"
|
||||
#include "oscedit.h"
|
||||
|
||||
// demo
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "fwk.h"
|
||||
#include "v4k.h"
|
||||
#include "oscedit.h"
|
||||
|
||||
// game
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "fwk.h"
|
||||
#include "v4k.h"
|
||||
|
||||
#define OSCPACK_C
|
||||
#define OSCRECV_C
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// networked gui demo
|
||||
// - rlyeh, public domain
|
||||
|
||||
#include "fwk.h"
|
||||
#include "v4k.h"
|
||||
|
||||
#define OSCPACK_C
|
||||
#define OSCRECV_C
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "fwk.h"
|
||||
#include "v4k.h"
|
||||
#include "oscsend.h"
|
||||
#include "oscedit.h"
|
||||
int main(int argc, char **argv) {
|
||||
|
|
|
@ -3,7 +3,8 @@ given a string A, we want it to be B.
|
|||
A: hello world and thanks for the fish.
|
||||
B: hello cruel o_o world and thanks for the fish!
|
||||
|
||||
however, the instructions to reconstruct B must be as small as possible, to minimize transmission costs. this is why we dont send B entirely.
|
||||
however, the instructions to reconstruct B must be as small as possible, to minimize transmission costs.
|
||||
this is why we dont transmit B entirely.
|
||||
|
||||
different algorithms as follow:
|
||||
|
||||
|
@ -11,48 +12,57 @@ different algorithms as follow:
|
|||
|
||||
- identify the first mismatching character (S).
|
||||
|
||||
v-- 6(S)
|
||||
v-- S@6
|
||||
A: hello world and thanks for the fish.
|
||||
B: hello cruel o_o world and thanks for the fish!
|
||||
|
||||
- identify the last mismatch character (E).
|
||||
|
||||
v-- 0(E)
|
||||
v-- E@-0
|
||||
A: hello world and thanks for the fish.
|
||||
B: hello cruel o_o world and thanks for the fish!
|
||||
|
||||
- we construct the patch now with 3 numbers:
|
||||
- number of bytes to copy from beginning(A) till S(A)
|
||||
- number of bytes to copy from S(B) till E(B). plus the substring that is get copied.
|
||||
- number of bytes to copy from E(A) till end of string.
|
||||
- number of bytes to copy from A[0] till A[S] (not included)
|
||||
- number of bytes to copy from B[S] till B[E] (not included) + plus the substring that is get copied.
|
||||
- number of bytes to copy from A[E] till end of A string.
|
||||
|
||||
6 40 "cruel o_o world and thanks for the fish!" 0
|
||||
|
||||
- total patch size is 3 control bytes + 40 (string) = 43 bytes
|
||||
- total patch size is 3 control bytes [6,40,0] + 40 (string) = 43 bytes
|
||||
|
||||
## ALGORITHM 2
|
||||
|
||||
- We delta every character in both strings, from beginning to end, and from end to beginning.
|
||||
- We delta every character in both strings, from head to tail, and from tail to head.
|
||||
|
||||
A: hello world and thanks for the fish.0000000000
|
||||
B: hello cruel o_o world and thanks for the fish!
|
||||
B: hello cruel l_o world and thanks for the fish!
|
||||
C: 000000XXXXX0XXX0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX (-)
|
||||
|
||||
A: 0000000000hello world and thanks for the fish.
|
||||
B: hello cruel o_o world and thanks for the fish!
|
||||
C: XXXXXXXXXXXXXX0000000000000000000000000000000X (-)
|
||||
B: hello cruel l_o world and thanks for the fish!
|
||||
C: XXXXXXXXXXXX0X0000000000000000000000000000000X (-)
|
||||
|
||||
- Pick the option with most zeros (2nd). Aka, select the option with less Xs.
|
||||
- Pick the choice with most zeros (2nd choice) (aka, select the choice with less Xs).
|
||||
- On C lane, promote gaps of one or two `0`s into `X`s.
|
||||
|
||||
do { Encode every XXXX island in C as a positive operation indicating how many bytes to copy from.
|
||||
Run-length the number of zeros into a negative operation.
|
||||
} repeat till lane is exhausted.
|
||||
A: 0000000000hello world and thanks for the fish.\0
|
||||
B: hello cruel l_o world and thanks for the fish!\0
|
||||
C: XXXXXXXXXXXXXX0000000000000000000000000000000X 0 (-)
|
||||
^
|
||||
|
||||
XXXXXXXXXXXXXXX: +14 "hello cruel o_"
|
||||
0000000000000000000000000000000: -29
|
||||
- Do the number of leading Xs(C) - number of leading 0s(A) (14-10). If positive, write it [4].
|
||||
This number will be needed in the patch function.
|
||||
- Do { Encode every XXXX island in C as a positive number indicating how many bytes to copy from.
|
||||
Otherwise, run-length the number of zeros into a negative number.
|
||||
} repeat till lane is exhausted.
|
||||
|
||||
4
|
||||
XXXXXXXXXXXXXXX: +14 "hello cruel l_"
|
||||
0000000000000000000000000000000: -31
|
||||
X: +1 "!"
|
||||
|
||||
- Patch size is 3 control bytes + 14 (string) + 1 (string) = 18 bytes
|
||||
- Patch size is 4 control bytes [4,+14,-31,+1] + 14 (string) + 1 (string) = 19 bytes
|
||||
|
||||
## ALGORITHM 3
|
||||
|
||||
|
@ -83,4 +93,3 @@ B: -29 +1 >> hello cruel o_o world and thanks for the fish!
|
|||
+6 0 -6 +10 "cruel o_o " +24 -1 -29 +1 "!"
|
||||
|
||||
- total patch size is 8 control bytes + 10 (string) + 1 (string) = 19 bytes
|
||||
|
||||
|
|
|
@ -5,14 +5,14 @@ w=0.666667
|
|||
h=0.666667
|
||||
visible=1
|
||||
[Outliner]
|
||||
x=-0.000000
|
||||
y=0.107495
|
||||
w=0.249929
|
||||
h=0.333728
|
||||
x=0.000000
|
||||
y=0.106026
|
||||
w=0.295716
|
||||
h=0.893974
|
||||
visible=1
|
||||
[Properties]
|
||||
x=0.749973
|
||||
x=0.723415
|
||||
y=0.052117
|
||||
w=0.250028
|
||||
h=0.333860
|
||||
w=0.276585
|
||||
h=0.946236
|
||||
visible=1
|
||||
|
|
Loading…
Reference in New Issue