From 49c41fb90ed02e248bd513ede2005c1b21644c04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Madar=C3=A1sz?= Date: Mon, 23 Oct 2023 15:25:03 +0200 Subject: [PATCH] sync fwk --- MAKE.bat | 28 ++-- bind/v4k.lua | 17 +- demos/01-font.c | 5 +- demos/02-frustum.c | 10 +- demos/05-scene.c | 8 +- demos/09-shadertoy.c | 2 +- demos/99-nodes.c | 12 +- demos/99-pbr.c | 2 +- depot | 2 +- engine/joint/v4k.h | 230 ++++++++++++++++------------ engine/split/3rd_nuklear_glfw_gl3.h | 1 + engine/split/v4k.c.inl | 12 +- engine/split/v4k_memory.c | 7 +- engine/split/v4k_obj.c | 65 +++++--- engine/split/v4k_obj.h | 55 ++++--- engine/split/v4k_reflect.c | 61 ++++---- engine/split/v4k_reflect.h | 20 ++- engine/split/v4k_ui.c | 2 +- engine/split/v4k_window.c | 5 +- engine/v4k | 1 + engine/v4k.c | 152 +++++++++++------- engine/v4k.h | 75 +++++---- tools/editor/editor.c | 18 +-- tools/editor/editor2.c | 2 +- tools/editor/editor2.h | 8 +- tools/editor/labs.meta/meta_info.c | 2 +- tools/editor/labs.meta/meta_tool.c | 4 +- tools/editor/labs.osc/MAKE.bat | 6 +- tools/editor/labs.osc/oscedit.c | 2 +- tools/editor/labs.osc/oscgame.c | 2 +- tools/editor/labs.osc/osclab1.c | 2 +- tools/editor/labs.osc/osclab2.c | 2 +- tools/editor/labs.osc/oscsend.c | 2 +- tools/editor/labs.vm/fwk_diff.md | 47 +++--- tools/editor/windows.ini | 14 +- 35 files changed, 507 insertions(+), 376 deletions(-) diff --git a/MAKE.bat b/MAKE.bat index 6833f13..16fee28 100644 --- a/MAKE.bat +++ b/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 diff --git a/bind/v4k.lua b/bind/v4k.lua index 530ef50..2df2d3a 100644 --- a/bind/v4k.lua +++ b/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 ); diff --git a/demos/01-font.c b/demos/01-font.c index 747e74e..17be8e6 100644 --- a/demos/01-font.c +++ b/demos/01-font.c @@ -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)]) ); diff --git a/demos/02-frustum.c b/demos/02-frustum.c index 36eb6db..1d8776b 100644 --- a/demos/02-frustum.c +++ b/demos/02-frustum.c @@ -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); diff --git a/demos/05-scene.c b/demos/05-scene.c index 09c2990..8bcd5a4 100644 --- a/demos/05-scene.c +++ b/demos/05-scene.c @@ -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)) {} diff --git a/demos/09-shadertoy.c b/demos/09-shadertoy.c index 569cf4d..7ae5eb7 100644 --- a/demos/09-shadertoy.c +++ b/demos/09-shadertoy.c @@ -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))); } diff --git a/demos/99-nodes.c b/demos/99-nodes.c index 5c1ee56..0e3c094 100644 --- a/demos/99-nodes.c +++ b/demos/99-nodes.c @@ -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) diff --git a/demos/99-pbr.c b/demos/99-pbr.c index 334159c..307d9fd 100644 --- a/demos/99-pbr.c +++ b/demos/99-pbr.c @@ -661,4 +661,4 @@ int main() { ui_panel_end(); } } -} \ No newline at end of file +} diff --git a/depot b/depot index 616f75f..55dfe19 160000 --- a/depot +++ b/depot @@ -1 +1 @@ -Subproject commit 616f75f5bb015fefd6e3321621b0f178637535b5 +Subproject commit 55dfe191dcfca2c39969eaacbf283b75b11df31a diff --git a/engine/joint/v4k.h b/engine/joint/v4k.h index ee6341b..0ec0e4c 100644 --- a/engine/joint/v4k.h +++ b/engine/joint/v4k.h @@ -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)<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 } diff --git a/engine/split/3rd_nuklear_glfw_gl3.h b/engine/split/3rd_nuklear_glfw_gl3.h index 3573ea2..7432886 100644 --- a/engine/split/3rd_nuklear_glfw_gl3.h +++ b/engine/split/3rd_nuklear_glfw_gl3.h @@ -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); diff --git a/engine/split/v4k.c.inl b/engine/split/v4k.c.inl index c181bb6..4adfe3e 100644 --- a/engine/split/v4k.c.inl +++ b/engine/split/v4k.c.inl @@ -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 diff --git a/engine/split/v4k_memory.c b/engine/split/v4k_memory.c index cfaf927..2c1eb98 100644 --- a/engine/split/v4k_memory.c +++ b/engine/split/v4k_memory.c @@ -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 ----------------------------------------------------------------------- diff --git a/engine/split/v4k_obj.c b/engine/split/v4k_obj.c index 2c0d7ca..10054e1 100644 --- a/engine/split/v4k_obj.c +++ b/engine/split/v4k_obj.c @@ -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 } diff --git a/engine/split/v4k_obj.h b/engine/split/v4k_obj.h index 1e74673..9522fa8 100644 --- a/engine/split/v4k_obj.h +++ b/engine/split/v4k_obj.h @@ -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)<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; ) \ diff --git a/engine/split/v4k_reflect.c b/engine/split/v4k_reflect.c index 9293c6c..8a3017a 100644 --- a/engine/split/v4k_reflect.c +++ b/engine/split/v4k_reflect.c @@ -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 diff --git a/engine/split/v4k_reflect.h b/engine/split/v4k_reflect.h index 386b1e3..30b25b2 100644 --- a/engine/split/v4k_reflect.h +++ b/engine/split/v4k_reflect.h @@ -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 diff --git a/engine/split/v4k_ui.c b/engine/split/v4k_ui.c index d2dae75..71fa145 100644 --- a/engine/split/v4k_ui.c +++ b/engine/split/v4k_ui.c @@ -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; diff --git a/engine/split/v4k_window.c b/engine/split/v4k_window.c index d9d0aea..79a2908 100644 --- a/engine/split/v4k_window.c +++ b/engine/split/v4k_window.c @@ -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 diff --git a/engine/v4k b/engine/v4k index ff4aa9d..dcf7503 100644 --- a/engine/v4k +++ b/engine/v4k @@ -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); diff --git a/engine/v4k.c b/engine/v4k.c index 90f6138..c6253dc 100644 --- a/engine/v4k.c +++ b/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 } diff --git a/engine/v4k.h b/engine/v4k.h index e643ea4..6925c85 100644 --- a/engine/v4k.h +++ b/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)<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" diff --git a/tools/editor/editor.c b/tools/editor/editor.c index 57013c3..149909a 100644 --- a/tools/editor/editor.c +++ b/tools/editor/editor.c @@ -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 diff --git a/tools/editor/editor2.c b/tools/editor/editor2.c index cdf86cc..fae7ff6 100644 --- a/tools/editor/editor2.c +++ b/tools/editor/editor2.c @@ -13,7 +13,7 @@ - [ ] Editor: GUI pass: timeline and data tracks, node graphs. */ -#include "fwk.c" +#include "v4k.c" #include "editor2.h" // old editor interface #define ui_push_hspace(px) \ diff --git a/tools/editor/editor2.h b/tools/editor/editor2.h index 6eb7584..d207e5d 100644 --- a/tools/editor/editor2.h +++ b/tools/editor/editor2.h @@ -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; diff --git a/tools/editor/labs.meta/meta_info.c b/tools/editor/labs.meta/meta_info.c index 32d1b22..3adfb98 100644 --- a/tools/editor/labs.meta/meta_info.c +++ b/tools/editor/labs.meta/meta_info.c @@ -1,6 +1,6 @@ //#define META_DEMO -#include "fwk.h" +#include "v4k.h" #include #include diff --git a/tools/editor/labs.meta/meta_tool.c b/tools/editor/labs.meta/meta_tool.c index a381339..723dd2c 100644 --- a/tools/editor/labs.meta/meta_tool.c +++ b/tools/editor/labs.meta/meta_tool.c @@ -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 "); diff --git a/tools/editor/labs.osc/MAKE.bat b/tools/editor/labs.osc/MAKE.bat index c7ffcd0..f93798b 100644 --- a/tools/editor/labs.osc/MAKE.bat +++ b/tools/editor/labs.osc/MAKE.bat @@ -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 diff --git a/tools/editor/labs.osc/oscedit.c b/tools/editor/labs.osc/oscedit.c index 774d222..a5c65a4 100644 --- a/tools/editor/labs.osc/oscedit.c +++ b/tools/editor/labs.osc/oscedit.c @@ -1,4 +1,4 @@ -#include "fwk.h" +#include "v4k.h" #include "oscedit.h" // demo diff --git a/tools/editor/labs.osc/oscgame.c b/tools/editor/labs.osc/oscgame.c index a8698ac..e7d5064 100644 --- a/tools/editor/labs.osc/oscgame.c +++ b/tools/editor/labs.osc/oscgame.c @@ -1,4 +1,4 @@ -#include "fwk.h" +#include "v4k.h" #include "oscedit.h" // game diff --git a/tools/editor/labs.osc/osclab1.c b/tools/editor/labs.osc/osclab1.c index d4b76fb..c8f5627 100644 --- a/tools/editor/labs.osc/osclab1.c +++ b/tools/editor/labs.osc/osclab1.c @@ -1,4 +1,4 @@ -#include "fwk.h" +#include "v4k.h" #define OSCPACK_C #define OSCRECV_C diff --git a/tools/editor/labs.osc/osclab2.c b/tools/editor/labs.osc/osclab2.c index bc0d5e3..d449e0d 100644 --- a/tools/editor/labs.osc/osclab2.c +++ b/tools/editor/labs.osc/osclab2.c @@ -1,7 +1,7 @@ // networked gui demo // - rlyeh, public domain -#include "fwk.h" +#include "v4k.h" #define OSCPACK_C #define OSCRECV_C diff --git a/tools/editor/labs.osc/oscsend.c b/tools/editor/labs.osc/oscsend.c index ede9bf6..242cd83 100644 --- a/tools/editor/labs.osc/oscsend.c +++ b/tools/editor/labs.osc/oscsend.c @@ -1,4 +1,4 @@ -#include "fwk.h" +#include "v4k.h" #include "oscsend.h" #include "oscedit.h" int main(int argc, char **argv) { diff --git a/tools/editor/labs.vm/fwk_diff.md b/tools/editor/labs.vm/fwk_diff.md index df6f601..096fd5f 100644 --- a/tools/editor/labs.vm/fwk_diff.md +++ b/tools/editor/labs.vm/fwk_diff.md @@ -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 - diff --git a/tools/editor/windows.ini b/tools/editor/windows.ini index 6b6f150..a6043cf 100644 --- a/tools/editor/windows.ini +++ b/tools/editor/windows.ini @@ -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