main
Dominik Madarász 2023-10-23 15:25:03 +02:00
parent e8bfb4bfb5
commit 49c41fb90e
35 changed files with 507 additions and 376 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

2
depot

@ -1 +1 @@
Subproject commit 616f75f5bb015fefd6e3321621b0f178637535b5
Subproject commit 55dfe191dcfca2c39969eaacbf283b75b11df31a

View File

@ -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);
@ -331994,6 +331990,14 @@ int main() {
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
}

View File

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

View File

@ -102,6 +102,14 @@
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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -102,6 +102,14 @@
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
}

View File

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

View File

@ -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,7 +1022,7 @@ void editor_render_menubar() {
}
}
int do_context_cmd = 0;
uint64_t do_context_cmd = 0;
void *do_context_obj = 0;
void editor_obj_render_properties_recursively(void *obj, const char *mask) {
@ -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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
//#define META_DEMO
#include "fwk.h"
#include "v4k.h"
#include <string.h>
#include <stdint.h>

View File

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

View File

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

View File

@ -1,4 +1,4 @@
#include "fwk.h"
#include "v4k.h"
#include "oscedit.h"
// demo

View File

@ -1,4 +1,4 @@
#include "fwk.h"
#include "v4k.h"
#include "oscedit.h"
// game

View File

@ -1,4 +1,4 @@
#include "fwk.h"
#include "v4k.h"
#define OSCPACK_C
#define OSCRECV_C

View File

@ -1,7 +1,7 @@
// networked gui demo
// - rlyeh, public domain
#include "fwk.h"
#include "v4k.h"
#define OSCPACK_C
#define OSCRECV_C

View File

@ -1,4 +1,4 @@
#include "fwk.h"
#include "v4k.h"
#include "oscsend.h"
#include "oscedit.h"
int main(int argc, char **argv) {

View File

@ -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.
A: 0000000000hello world and thanks for the fish.\0
B: hello cruel l_o world and thanks for the fish!\0
C: XXXXXXXXXXXXXX0000000000000000000000000000000X 0 (-)
^
- 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.
XXXXXXXXXXXXXXX: +14 "hello cruel o_"
0000000000000000000000000000000: -29
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

View File

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