diff --git a/_mirror b/_mirror index a239c18..e838bef 160000 --- a/_mirror +++ b/_mirror @@ -1 +1 @@ -Subproject commit a239c188cadce8af6d28ae7402184cd7a3073fc2 +Subproject commit e838bef9bea402b1fa3ecb66b74addcb4256b687 diff --git a/bind/v4k.lua b/bind/v4k.lua index 005563f..92fc1b9 100644 --- a/bind/v4k.lua +++ b/bind/v4k.lua @@ -2457,11 +2457,11 @@ unsigned bytes; reflect_t member_find(const char *T, const char *M); void * member_findptr(void *obj, const char *T, const char *M); reflect_t* members_find(const char *T); - void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos); - void enum_inscribe(const char *E,unsigned Eid,unsigned Eval,const char *infos); - void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos); - void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type, unsigned bytes); - void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos); + void type_inscribe(const char *TY,unsigned TYsz,const char *infos); + void enum_inscribe(const char *E,unsigned Eval,const char *infos); + 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(); diff --git a/engine/joint/v4k.h b/engine/joint/v4k.h index cb4a01c..8c57ad5 100644 --- a/engine/joint/v4k.h +++ b/engine/joint/v4k.h @@ -14200,6 +14200,7 @@ extern "C" { #define conc4t(a,b) a##b ///- #define macro(name) concat(name, __LINE__) +#define unique(name) concat(concat(name, L##__LINE__), __COUNTER__) #define defer(begin,end) for(int macro(i) = ((begin), 0); !macro(i); macro(i) = ((end), 1)) #define scope(end) defer((void)0, end) #define benchmark for(double macro(i) = 1, macro(t) = (time_ss(),-time_ss()); macro(i); macro(t)+=time_ss(), macro(i)=0, printf("%.4fs %2.f%% (" FILELINE ")\n", macro(t), macro(t)*100/0.0166667 )) @@ -14227,7 +14228,7 @@ extern "C" { #define ASSERT(expr, ...) do { int fool_msvc[] = {0,}; if(!(expr)) { fool_msvc[0]++; breakpoint(va("!Expression failed: " #expr " " FILELINE "\n" __VA_ARGS__)); } } while(0) #define ASSERT_ONCE(expr, ...) do { int fool_msvc[] = {0,}; if(!(expr)) { fool_msvc[0]++; static int seen = 0; if(!seen) seen = 1, breakpoint(va("!Expression failed: " #expr " " FILELINE "\n" __VA_ARGS__)); } } while(0) #endif -#define STATIC_ASSERT(EXPR) typedef struct { unsigned macro(static_assert_on_line_) : !!(EXPR); } macro(static_assert_on_line_) +#define STATIC_ASSERT(EXPR) typedef struct { unsigned macro(static_assert_on_L) : !!(EXPR); } unique(static_assert_on_L) #define FILELINE __FILE__ ":" STRINGIZE(__LINE__) #define STRINGIZE(x) STRINGIZ3(x) @@ -14317,7 +14318,11 @@ extern "C" { __declspec(allocate(".CRT$XIU")) \ static int(* concat(fn,__2) )() = concat(fn,__1); \ static void fn(void) -#else // gcc,tcc,clang,clang-cl... +#elif defined __TINYC__ // tcc... +#define AUTORUN_(fn) \ + __attribute__((constructor)) \ + static void fn(void) +#else // gcc,clang,clang-cl... #define AUTORUN_(fn) \ __attribute__((constructor(__COUNTER__+101))) \ static void fn(void) @@ -16627,15 +16632,15 @@ typedef struct reflect_t { // inscribe api #define ENUM(V, .../*value_annotations*/) \ - enum_inscribe(#V,intern(#V),V, "" __VA_ARGS__/*value_annotations*/) + enum_inscribe(#V,V, "" __VA_ARGS__/*value_annotations*/) #define FUNCTION(F, .../*function_annotations*/) \ - function_inscribe(#F,intern(#F),(void*)F, "" __VA_ARGS__/*function_annotations*/) + function_inscribe(#F,(void*)F, "" __VA_ARGS__/*function_annotations*/) #define STRUCT(T, type, member, .../*member_annotations*/) \ - struct_inscribe(#T,intern(#T),sizeof(T),OBJTYPE(T),NULL), \ - type_inscribe(#type,intern(#type),sizeof(((T){0}).member),"" __VA_ARGS__/*member_annotations*/), \ - member_inscribe(intern(#T), #member,intern(#member),(uintptr_t)&((T*)0)->member, "" __VA_ARGS__/*member_annotations*/, #type, sizeof(((T){0}).member) ) + 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) ) // find api @@ -16655,11 +16660,11 @@ API array(reflect_t) members_find(const char *T); // private api, still exposed -API void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos); -API void enum_inscribe(const char *E,unsigned Eid,unsigned Eval,const char *infos); -API void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos); -API void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type, unsigned bytes); -API void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos); +API void type_inscribe(const char *TY,unsigned TYsz,const char *infos); +API void enum_inscribe(const char *E,unsigned Eval,const char *infos); +API void struct_inscribe(const char *T,unsigned Tsz,unsigned OBJTYPEid, const char *infos); +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); @@ -343869,33 +343874,53 @@ AUTORUN { reflect_init(); } -void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos) { +static +const char* symbol(const char *s) { + if( strbeg(s, "const ") ) s += 6; + if( strbeg(s, "union ") ) s += 6; + if( strbeg(s, "struct ") ) s += 7; + if(!strstr(s, " *") ) return s; + char *copy = va("%s", s); + do strswap(copy," *","*"); while( strstr(copy, " *") ); // char * -> char* + return (const char *)copy; +} + +void type_inscribe(const char *TY,unsigned TYsz,const char *infos) { reflect_init(); + unsigned TYid = intern(TY = symbol(TY)); map_find_or_add(reflects, TYid, ((reflect_t){TYid, 0, TYsz, TY, infos})); } -void enum_inscribe(const char *E,unsigned Eid,unsigned Eval,const char *infos) { +void enum_inscribe(const char *E,unsigned Eval,const char *infos) { reflect_init(); + unsigned Eid = intern(E = symbol(E)); map_find_or_add(reflects, Eid, ((reflect_t){Eid,0, Eval, E,infos})); } unsigned enum_find(const char *E) { reflect_init(); + E = symbol(E); return map_find(reflects, intern(E))->sz; } -void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos) { +void function_inscribe(const char *F,void *func,const char *infos) { reflect_init(); + unsigned Fid = intern(F = symbol(F)); map_find_or_add(reflects, Fid, ((reflect_t){Fid,0, 0, F,infos, func})); reflect_t *found = map_find(reflects,Fid); } void *function_find(const char *F) { reflect_init(); + F = symbol(F); return map_find(reflects, intern(F))->addr; } -void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos) { +void struct_inscribe(const char *T,unsigned Tsz,unsigned OBJTYPEid, const char *infos) { reflect_init(); + unsigned Tid = intern(T = symbol(T)); map_find_or_add(reflects, Tid, ((reflect_t){Tid, OBJTYPEid, Tsz, T, infos})); } -void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type, unsigned bytes) { +void member_inscribe(const char *T, const char *M,unsigned Msz, const char *infos, const char *type, unsigned bytes) { reflect_init(); + unsigned Tid = intern(T = symbol(T)); + unsigned Mid = intern(M = symbol(M)); + type = symbol(type); map_find_or_add(reflects, (Mid<<16)|Tid, ((reflect_t){Mid, 0, Msz, M, infos, NULL, Tid, type })); // add member separately as well if(!members) map_init_int(members); @@ -343904,14 +343929,19 @@ void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, cons } reflect_t member_find(const char *T, const char *M) { reflect_init(); + T = symbol(T); + M = symbol(M); return *map_find(reflects, (intern(M)<<16)|intern(T)); } void *member_findptr(void *obj, const char *T, const char *M) { reflect_init(); + T = symbol(T); + M = symbol(M); return (char*)obj + member_find(T,M).sz; } array(reflect_t) members_find(const char *T) { reflect_init(); + T = symbol(T); return *map_find(members, intern(T)); } @@ -351411,11 +351441,37 @@ void app_hang() { for(;;); } void app_crash() { - int *p = 0; + volatile int *p = 0; *p = 42; } void app_beep() { + ifdef(win32, system("rundll32 user32.dll,MessageBeep"); return; ); + ifdef(linux, system("paplay /usr/share/sounds/freedesktop/stereo/message.oga"); return; ); + ifdef(osx, system("tput bel"); return; ); + + //fallback: fputc('\x7', stdout); + + // win32: + // rundll32 user32.dll,MessageBeep ; ok + // rundll32 cmdext.dll,MessageBeepStub ; ok + + // osx: + // tput bel + // say "beep" + // osascript -e 'beep' + // osascript -e "beep 1" + // afplay /System/Library/Sounds/Ping.aiff + // /usr/bin/printf "\a" + + // linux: + // paplay /usr/share/sounds/freedesktop/stereo/message.oga ; ok + // paplay /usr/share/sounds/freedesktop/stereo/complete.oga ; ok + // paplay /usr/share/sounds/freedesktop/stereo/bell.oga ; ok + // beep ; apt-get + // echo -e '\007' ; mute + // echo -e "\007" >/dev/tty10 ; sudo + // tput bel ; mute } void app_singleton(const char *guid) { @@ -353274,6 +353330,8 @@ int ui_label2_toolbar(const char *label, const char *icons) { } int ui_notify(const char *title, const char *body) { + app_beep(); + struct ui_notify n = {0}; n.title = title && title[0] ? stringf("*%s", title) : 0; n.body = body && body[0] ? STRDUP(body) : 0; @@ -356763,8 +356821,8 @@ int editor_send(const char *cmd, const char *optional_value) { else if( !strcmp(cmd, "key_battery" )) *powersave = optional_value ? !!atoi(optional_value) : *powersave ^ 1; else if( !strcmp(cmd, "key_browser" )) ui_show("File Browser", ui_visible("File Browser") ^ true); else if( !strcmp(cmd, "key_outliner" )) ui_show("Outliner", ui_visible("Outliner") ^ true); - else if( !strcmp(cmd, "key_record" )) if(record_active()) record_stop(); else - name = file_counter(va("%s.mp4",app_name())), window_record(name), ui_notify(va("Video capturing: %s", name), date_string()); + else if( !strcmp(cmd, "key_record" )) if(record_active()) record_stop(), ui_notify(va("Video recorded"), date_string()); else + app_beep(), name = file_counter(va("%s.mp4",app_name())), window_record(name); else if( !strcmp(cmd, "key_screenshot" )) name = file_counter(va("%s.png",app_name())), window_screenshot(name), ui_notify(va("Screenshot: %s", name), date_string()); else if( !strcmp(cmd, "key_profiler" )) ui_show("Profiler", profiler_enable(ui_visible("Profiler") ^ true)); else if( !strcmp(cmd, "key_fullscreen" )) record_stop(), window_fullscreen( window_has_fullscreen() ^ 1 ); // framebuffer resizing corrupts video stream, so stop any recording beforehand diff --git a/engine/split/v4k_config.h b/engine/split/v4k_config.h index e0a1ee6..0eef31f 100644 --- a/engine/split/v4k_config.h +++ b/engine/split/v4k_config.h @@ -169,6 +169,7 @@ #define conc4t(a,b) a##b ///- #define macro(name) concat(name, __LINE__) +#define unique(name) concat(concat(name, L##__LINE__), __COUNTER__) #define defer(begin,end) for(int macro(i) = ((begin), 0); !macro(i); macro(i) = ((end), 1)) #define scope(end) defer((void)0, end) #define benchmark for(double macro(i) = 1, macro(t) = (time_ss(),-time_ss()); macro(i); macro(t)+=time_ss(), macro(i)=0, printf("%.4fs %2.f%% (" FILELINE ")\n", macro(t), macro(t)*100/0.0166667 )) @@ -196,7 +197,7 @@ #define ASSERT(expr, ...) do { int fool_msvc[] = {0,}; if(!(expr)) { fool_msvc[0]++; breakpoint(va("!Expression failed: " #expr " " FILELINE "\n" __VA_ARGS__)); } } while(0) #define ASSERT_ONCE(expr, ...) do { int fool_msvc[] = {0,}; if(!(expr)) { fool_msvc[0]++; static int seen = 0; if(!seen) seen = 1, breakpoint(va("!Expression failed: " #expr " " FILELINE "\n" __VA_ARGS__)); } } while(0) #endif -#define STATIC_ASSERT(EXPR) typedef struct { unsigned macro(static_assert_on_line_) : !!(EXPR); } macro(static_assert_on_line_) +#define STATIC_ASSERT(EXPR) typedef struct { unsigned macro(static_assert_on_L) : !!(EXPR); } unique(static_assert_on_L) #define FILELINE __FILE__ ":" STRINGIZE(__LINE__) #define STRINGIZE(x) STRINGIZ3(x) @@ -286,7 +287,11 @@ __declspec(allocate(".CRT$XIU")) \ static int(* concat(fn,__2) )() = concat(fn,__1); \ static void fn(void) -#else // gcc,tcc,clang,clang-cl... +#elif defined __TINYC__ // tcc... +#define AUTORUN_(fn) \ + __attribute__((constructor)) \ + static void fn(void) +#else // gcc,clang,clang-cl... #define AUTORUN_(fn) \ __attribute__((constructor(__COUNTER__+101))) \ static void fn(void) diff --git a/engine/split/v4k_editor.c b/engine/split/v4k_editor.c index 890fc9e..aaf3772 100644 --- a/engine/split/v4k_editor.c +++ b/engine/split/v4k_editor.c @@ -160,8 +160,8 @@ int editor_send(const char *cmd, const char *optional_value) { else if( !strcmp(cmd, "key_battery" )) *powersave = optional_value ? !!atoi(optional_value) : *powersave ^ 1; else if( !strcmp(cmd, "key_browser" )) ui_show("File Browser", ui_visible("File Browser") ^ true); else if( !strcmp(cmd, "key_outliner" )) ui_show("Outliner", ui_visible("Outliner") ^ true); - else if( !strcmp(cmd, "key_record" )) if(record_active()) record_stop(); else - name = file_counter(va("%s.mp4",app_name())), window_record(name), ui_notify(va("Video capturing: %s", name), date_string()); + else if( !strcmp(cmd, "key_record" )) if(record_active()) record_stop(), ui_notify(va("Video recorded"), date_string()); else + app_beep(), name = file_counter(va("%s.mp4",app_name())), window_record(name); else if( !strcmp(cmd, "key_screenshot" )) name = file_counter(va("%s.png",app_name())), window_screenshot(name), ui_notify(va("Screenshot: %s", name), date_string()); else if( !strcmp(cmd, "key_profiler" )) ui_show("Profiler", profiler_enable(ui_visible("Profiler") ^ true)); else if( !strcmp(cmd, "key_fullscreen" )) record_stop(), window_fullscreen( window_has_fullscreen() ^ 1 ); // framebuffer resizing corrupts video stream, so stop any recording beforehand diff --git a/engine/split/v4k_reflect.c b/engine/split/v4k_reflect.c index 4fe42b4..5d698ff 100644 --- a/engine/split/v4k_reflect.c +++ b/engine/split/v4k_reflect.c @@ -14,33 +14,53 @@ AUTORUN { reflect_init(); } -void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos) { +static +const char* symbol(const char *s) { + if( strbeg(s, "const ") ) s += 6; + if( strbeg(s, "union ") ) s += 6; + if( strbeg(s, "struct ") ) s += 7; + if(!strstr(s, " *") ) return s; + char *copy = va("%s", s); + do strswap(copy," *","*"); while( strstr(copy, " *") ); // char * -> char* + return (const char *)copy; +} + +void type_inscribe(const char *TY,unsigned TYsz,const char *infos) { reflect_init(); + unsigned TYid = intern(TY = symbol(TY)); map_find_or_add(reflects, TYid, ((reflect_t){TYid, 0, TYsz, TY, infos})); } -void enum_inscribe(const char *E,unsigned Eid,unsigned Eval,const char *infos) { +void enum_inscribe(const char *E,unsigned Eval,const char *infos) { reflect_init(); + unsigned Eid = intern(E = symbol(E)); map_find_or_add(reflects, Eid, ((reflect_t){Eid,0, Eval, E,infos})); } unsigned enum_find(const char *E) { reflect_init(); + E = symbol(E); return map_find(reflects, intern(E))->sz; } -void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos) { +void function_inscribe(const char *F,void *func,const char *infos) { reflect_init(); + unsigned Fid = intern(F = symbol(F)); map_find_or_add(reflects, Fid, ((reflect_t){Fid,0, 0, F,infos, func})); reflect_t *found = map_find(reflects,Fid); } void *function_find(const char *F) { reflect_init(); + F = symbol(F); return map_find(reflects, intern(F))->addr; } -void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos) { +void struct_inscribe(const char *T,unsigned Tsz,unsigned OBJTYPEid, const char *infos) { reflect_init(); + unsigned Tid = intern(T = symbol(T)); map_find_or_add(reflects, Tid, ((reflect_t){Tid, OBJTYPEid, Tsz, T, infos})); } -void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type, unsigned bytes) { +void member_inscribe(const char *T, const char *M,unsigned Msz, const char *infos, const char *type, unsigned bytes) { reflect_init(); + unsigned Tid = intern(T = symbol(T)); + unsigned Mid = intern(M = symbol(M)); + type = symbol(type); map_find_or_add(reflects, (Mid<<16)|Tid, ((reflect_t){Mid, 0, Msz, M, infos, NULL, Tid, type })); // add member separately as well if(!members) map_init_int(members); @@ -49,14 +69,19 @@ void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, cons } reflect_t member_find(const char *T, const char *M) { reflect_init(); + T = symbol(T); + M = symbol(M); return *map_find(reflects, (intern(M)<<16)|intern(T)); } void *member_findptr(void *obj, const char *T, const char *M) { reflect_init(); + T = symbol(T); + M = symbol(M); return (char*)obj + member_find(T,M).sz; } array(reflect_t) members_find(const char *T) { reflect_init(); + T = symbol(T); return *map_find(members, intern(T)); } diff --git a/engine/split/v4k_reflect.h b/engine/split/v4k_reflect.h index bf3a169..8add9b8 100644 --- a/engine/split/v4k_reflect.h +++ b/engine/split/v4k_reflect.h @@ -26,15 +26,15 @@ typedef struct reflect_t { // inscribe api #define ENUM(V, .../*value_annotations*/) \ - enum_inscribe(#V,intern(#V),V, "" __VA_ARGS__/*value_annotations*/) + enum_inscribe(#V,V, "" __VA_ARGS__/*value_annotations*/) #define FUNCTION(F, .../*function_annotations*/) \ - function_inscribe(#F,intern(#F),(void*)F, "" __VA_ARGS__/*function_annotations*/) + function_inscribe(#F,(void*)F, "" __VA_ARGS__/*function_annotations*/) #define STRUCT(T, type, member, .../*member_annotations*/) \ - struct_inscribe(#T,intern(#T),sizeof(T),OBJTYPE(T),NULL), \ - type_inscribe(#type,intern(#type),sizeof(((T){0}).member),"" __VA_ARGS__/*member_annotations*/), \ - member_inscribe(intern(#T), #member,intern(#member),(uintptr_t)&((T*)0)->member, "" __VA_ARGS__/*member_annotations*/, #type, sizeof(((T){0}).member) ) + 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) ) // find api @@ -54,11 +54,11 @@ API array(reflect_t) members_find(const char *T); // private api, still exposed -API void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos); -API void enum_inscribe(const char *E,unsigned Eid,unsigned Eval,const char *infos); -API void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos); -API void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type, unsigned bytes); -API void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos); +API void type_inscribe(const char *TY,unsigned TYsz,const char *infos); +API void enum_inscribe(const char *E,unsigned Eval,const char *infos); +API void struct_inscribe(const char *T,unsigned Tsz,unsigned OBJTYPEid, const char *infos); +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); diff --git a/engine/split/v4k_system.c b/engine/split/v4k_system.c index e89c7ce..c4f2723 100644 --- a/engine/split/v4k_system.c +++ b/engine/split/v4k_system.c @@ -793,11 +793,37 @@ void app_hang() { for(;;); } void app_crash() { - int *p = 0; + volatile int *p = 0; *p = 42; } void app_beep() { + ifdef(win32, system("rundll32 user32.dll,MessageBeep"); return; ); + ifdef(linux, system("paplay /usr/share/sounds/freedesktop/stereo/message.oga"); return; ); + ifdef(osx, system("tput bel"); return; ); + + //fallback: fputc('\x7', stdout); + + // win32: + // rundll32 user32.dll,MessageBeep ; ok + // rundll32 cmdext.dll,MessageBeepStub ; ok + + // osx: + // tput bel + // say "beep" + // osascript -e 'beep' + // osascript -e "beep 1" + // afplay /System/Library/Sounds/Ping.aiff + // /usr/bin/printf "\a" + + // linux: + // paplay /usr/share/sounds/freedesktop/stereo/message.oga ; ok + // paplay /usr/share/sounds/freedesktop/stereo/complete.oga ; ok + // paplay /usr/share/sounds/freedesktop/stereo/bell.oga ; ok + // beep ; apt-get + // echo -e '\007' ; mute + // echo -e "\007" >/dev/tty10 ; sudo + // tput bel ; mute } void app_singleton(const char *guid) { diff --git a/engine/split/v4k_ui.c b/engine/split/v4k_ui.c index 4068c88..2180ca4 100644 --- a/engine/split/v4k_ui.c +++ b/engine/split/v4k_ui.c @@ -1596,6 +1596,8 @@ int ui_label2_toolbar(const char *label, const char *icons) { } int ui_notify(const char *title, const char *body) { + app_beep(); + struct ui_notify n = {0}; n.title = title && title[0] ? stringf("*%s", title) : 0; n.body = body && body[0] ? STRDUP(body) : 0; diff --git a/engine/v4k.c b/engine/v4k.c index 492e16b..3aaceea 100644 --- a/engine/v4k.c +++ b/engine/v4k.c @@ -12794,33 +12794,53 @@ AUTORUN { reflect_init(); } -void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos) { +static +const char* symbol(const char *s) { + if( strbeg(s, "const ") ) s += 6; + if( strbeg(s, "union ") ) s += 6; + if( strbeg(s, "struct ") ) s += 7; + if(!strstr(s, " *") ) return s; + char *copy = va("%s", s); + do strswap(copy," *","*"); while( strstr(copy, " *") ); // char * -> char* + return (const char *)copy; +} + +void type_inscribe(const char *TY,unsigned TYsz,const char *infos) { reflect_init(); + unsigned TYid = intern(TY = symbol(TY)); map_find_or_add(reflects, TYid, ((reflect_t){TYid, 0, TYsz, TY, infos})); } -void enum_inscribe(const char *E,unsigned Eid,unsigned Eval,const char *infos) { +void enum_inscribe(const char *E,unsigned Eval,const char *infos) { reflect_init(); + unsigned Eid = intern(E = symbol(E)); map_find_or_add(reflects, Eid, ((reflect_t){Eid,0, Eval, E,infos})); } unsigned enum_find(const char *E) { reflect_init(); + E = symbol(E); return map_find(reflects, intern(E))->sz; } -void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos) { +void function_inscribe(const char *F,void *func,const char *infos) { reflect_init(); + unsigned Fid = intern(F = symbol(F)); map_find_or_add(reflects, Fid, ((reflect_t){Fid,0, 0, F,infos, func})); reflect_t *found = map_find(reflects,Fid); } void *function_find(const char *F) { reflect_init(); + F = symbol(F); return map_find(reflects, intern(F))->addr; } -void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos) { +void struct_inscribe(const char *T,unsigned Tsz,unsigned OBJTYPEid, const char *infos) { reflect_init(); + unsigned Tid = intern(T = symbol(T)); map_find_or_add(reflects, Tid, ((reflect_t){Tid, OBJTYPEid, Tsz, T, infos})); } -void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type, unsigned bytes) { +void member_inscribe(const char *T, const char *M,unsigned Msz, const char *infos, const char *type, unsigned bytes) { reflect_init(); + unsigned Tid = intern(T = symbol(T)); + unsigned Mid = intern(M = symbol(M)); + type = symbol(type); map_find_or_add(reflects, (Mid<<16)|Tid, ((reflect_t){Mid, 0, Msz, M, infos, NULL, Tid, type })); // add member separately as well if(!members) map_init_int(members); @@ -12829,14 +12849,19 @@ void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, cons } reflect_t member_find(const char *T, const char *M) { reflect_init(); + T = symbol(T); + M = symbol(M); return *map_find(reflects, (intern(M)<<16)|intern(T)); } void *member_findptr(void *obj, const char *T, const char *M) { reflect_init(); + T = symbol(T); + M = symbol(M); return (char*)obj + member_find(T,M).sz; } array(reflect_t) members_find(const char *T) { reflect_init(); + T = symbol(T); return *map_find(members, intern(T)); } @@ -20336,11 +20361,37 @@ void app_hang() { for(;;); } void app_crash() { - int *p = 0; + volatile int *p = 0; *p = 42; } void app_beep() { + ifdef(win32, system("rundll32 user32.dll,MessageBeep"); return; ); + ifdef(linux, system("paplay /usr/share/sounds/freedesktop/stereo/message.oga"); return; ); + ifdef(osx, system("tput bel"); return; ); + + //fallback: fputc('\x7', stdout); + + // win32: + // rundll32 user32.dll,MessageBeep ; ok + // rundll32 cmdext.dll,MessageBeepStub ; ok + + // osx: + // tput bel + // say "beep" + // osascript -e 'beep' + // osascript -e "beep 1" + // afplay /System/Library/Sounds/Ping.aiff + // /usr/bin/printf "\a" + + // linux: + // paplay /usr/share/sounds/freedesktop/stereo/message.oga ; ok + // paplay /usr/share/sounds/freedesktop/stereo/complete.oga ; ok + // paplay /usr/share/sounds/freedesktop/stereo/bell.oga ; ok + // beep ; apt-get + // echo -e '\007' ; mute + // echo -e "\007" >/dev/tty10 ; sudo + // tput bel ; mute } void app_singleton(const char *guid) { @@ -22199,6 +22250,8 @@ int ui_label2_toolbar(const char *label, const char *icons) { } int ui_notify(const char *title, const char *body) { + app_beep(); + struct ui_notify n = {0}; n.title = title && title[0] ? stringf("*%s", title) : 0; n.body = body && body[0] ? STRDUP(body) : 0; @@ -25688,8 +25741,8 @@ int editor_send(const char *cmd, const char *optional_value) { else if( !strcmp(cmd, "key_battery" )) *powersave = optional_value ? !!atoi(optional_value) : *powersave ^ 1; else if( !strcmp(cmd, "key_browser" )) ui_show("File Browser", ui_visible("File Browser") ^ true); else if( !strcmp(cmd, "key_outliner" )) ui_show("Outliner", ui_visible("Outliner") ^ true); - else if( !strcmp(cmd, "key_record" )) if(record_active()) record_stop(); else - name = file_counter(va("%s.mp4",app_name())), window_record(name), ui_notify(va("Video capturing: %s", name), date_string()); + else if( !strcmp(cmd, "key_record" )) if(record_active()) record_stop(), ui_notify(va("Video recorded"), date_string()); else + app_beep(), name = file_counter(va("%s.mp4",app_name())), window_record(name); else if( !strcmp(cmd, "key_screenshot" )) name = file_counter(va("%s.png",app_name())), window_screenshot(name), ui_notify(va("Screenshot: %s", name), date_string()); else if( !strcmp(cmd, "key_profiler" )) ui_show("Profiler", profiler_enable(ui_visible("Profiler") ^ true)); else if( !strcmp(cmd, "key_fullscreen" )) record_stop(), window_fullscreen( window_has_fullscreen() ^ 1 ); // framebuffer resizing corrupts video stream, so stop any recording beforehand diff --git a/engine/v4k.h b/engine/v4k.h index 070b8e5..64d0920 100644 --- a/engine/v4k.h +++ b/engine/v4k.h @@ -267,6 +267,7 @@ extern "C" { #define conc4t(a,b) a##b ///- #define macro(name) concat(name, __LINE__) +#define unique(name) concat(concat(name, L##__LINE__), __COUNTER__) #define defer(begin,end) for(int macro(i) = ((begin), 0); !macro(i); macro(i) = ((end), 1)) #define scope(end) defer((void)0, end) #define benchmark for(double macro(i) = 1, macro(t) = (time_ss(),-time_ss()); macro(i); macro(t)+=time_ss(), macro(i)=0, printf("%.4fs %2.f%% (" FILELINE ")\n", macro(t), macro(t)*100/0.0166667 )) @@ -294,7 +295,7 @@ extern "C" { #define ASSERT(expr, ...) do { int fool_msvc[] = {0,}; if(!(expr)) { fool_msvc[0]++; breakpoint(va("!Expression failed: " #expr " " FILELINE "\n" __VA_ARGS__)); } } while(0) #define ASSERT_ONCE(expr, ...) do { int fool_msvc[] = {0,}; if(!(expr)) { fool_msvc[0]++; static int seen = 0; if(!seen) seen = 1, breakpoint(va("!Expression failed: " #expr " " FILELINE "\n" __VA_ARGS__)); } } while(0) #endif -#define STATIC_ASSERT(EXPR) typedef struct { unsigned macro(static_assert_on_line_) : !!(EXPR); } macro(static_assert_on_line_) +#define STATIC_ASSERT(EXPR) typedef struct { unsigned macro(static_assert_on_L) : !!(EXPR); } unique(static_assert_on_L) #define FILELINE __FILE__ ":" STRINGIZE(__LINE__) #define STRINGIZE(x) STRINGIZ3(x) @@ -384,7 +385,11 @@ extern "C" { __declspec(allocate(".CRT$XIU")) \ static int(* concat(fn,__2) )() = concat(fn,__1); \ static void fn(void) -#else // gcc,tcc,clang,clang-cl... +#elif defined __TINYC__ // tcc... +#define AUTORUN_(fn) \ + __attribute__((constructor)) \ + static void fn(void) +#else // gcc,clang,clang-cl... #define AUTORUN_(fn) \ __attribute__((constructor(__COUNTER__+101))) \ static void fn(void) @@ -2694,15 +2699,15 @@ typedef struct reflect_t { // inscribe api #define ENUM(V, .../*value_annotations*/) \ - enum_inscribe(#V,intern(#V),V, "" __VA_ARGS__/*value_annotations*/) + enum_inscribe(#V,V, "" __VA_ARGS__/*value_annotations*/) #define FUNCTION(F, .../*function_annotations*/) \ - function_inscribe(#F,intern(#F),(void*)F, "" __VA_ARGS__/*function_annotations*/) + function_inscribe(#F,(void*)F, "" __VA_ARGS__/*function_annotations*/) #define STRUCT(T, type, member, .../*member_annotations*/) \ - struct_inscribe(#T,intern(#T),sizeof(T),OBJTYPE(T),NULL), \ - type_inscribe(#type,intern(#type),sizeof(((T){0}).member),"" __VA_ARGS__/*member_annotations*/), \ - member_inscribe(intern(#T), #member,intern(#member),(uintptr_t)&((T*)0)->member, "" __VA_ARGS__/*member_annotations*/, #type, sizeof(((T){0}).member) ) + 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) ) // find api @@ -2722,11 +2727,11 @@ API array(reflect_t) members_find(const char *T); // private api, still exposed -API void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos); -API void enum_inscribe(const char *E,unsigned Eid,unsigned Eval,const char *infos); -API void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos); -API void member_inscribe(unsigned Tid, const char *M,unsigned Mid,unsigned Msz, const char *infos, const char *type, unsigned bytes); -API void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos); +API void type_inscribe(const char *TY,unsigned TYsz,const char *infos); +API void enum_inscribe(const char *E,unsigned Eval,const char *infos); +API void struct_inscribe(const char *T,unsigned Tsz,unsigned OBJTYPEid, const char *infos); +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);