main
Dominik Madarász 2023-10-20 19:55:43 +02:00
parent eb331e4251
commit ff08939b06
11 changed files with 240 additions and 66 deletions

@ -1 +1 @@
Subproject commit a239c188cadce8af6d28ae7402184cd7a3073fc2 Subproject commit e838bef9bea402b1fa3ecb66b74addcb4256b687

View File

@ -2457,11 +2457,11 @@ unsigned bytes;
reflect_t member_find(const char *T, const char *M); reflect_t member_find(const char *T, const char *M);
void * member_findptr(void *obj, const char *T, const char *M); void * member_findptr(void *obj, const char *T, const char *M);
reflect_t* members_find(const char *T); reflect_t* members_find(const char *T);
void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos); void type_inscribe(const char *TY,unsigned TYsz,const char *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);
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);
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);
void function_inscribe(const char *F,unsigned Fid,void *func,const char *infos); void function_inscribe(const char *F,void *func,const char *infos);
void reflect_print(const char *symbol); void reflect_print(const char *symbol);
void reflect_dump(const char *mask); void reflect_dump(const char *mask);
void reflect_init(); void reflect_init();

View File

@ -14200,6 +14200,7 @@ extern "C" {
#define conc4t(a,b) a##b ///- #define conc4t(a,b) a##b ///-
#define macro(name) concat(name, __LINE__) #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 defer(begin,end) for(int macro(i) = ((begin), 0); !macro(i); macro(i) = ((end), 1))
#define scope(end) defer((void)0, end) #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 )) #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(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) #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 #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 FILELINE __FILE__ ":" STRINGIZE(__LINE__)
#define STRINGIZE(x) STRINGIZ3(x) #define STRINGIZE(x) STRINGIZ3(x)
@ -14317,7 +14318,11 @@ extern "C" {
__declspec(allocate(".CRT$XIU")) \ __declspec(allocate(".CRT$XIU")) \
static int(* concat(fn,__2) )() = concat(fn,__1); \ static int(* concat(fn,__2) )() = concat(fn,__1); \
static void fn(void) 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) \ #define AUTORUN_(fn) \
__attribute__((constructor(__COUNTER__+101))) \ __attribute__((constructor(__COUNTER__+101))) \
static void fn(void) static void fn(void)
@ -16627,15 +16632,15 @@ typedef struct reflect_t {
// inscribe api // inscribe api
#define ENUM(V, .../*value_annotations*/) \ #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*/) \ #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*/) \ #define STRUCT(T, type, member, .../*member_annotations*/) \
struct_inscribe(#T,intern(#T),sizeof(T),OBJTYPE(T),NULL), \ struct_inscribe(#T,sizeof(T),OBJTYPE(T),NULL), \
type_inscribe(#type,intern(#type),sizeof(((T){0}).member),"" __VA_ARGS__/*member_annotations*/), \ type_inscribe(#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) ) member_inscribe(#T, #member,(uintptr_t)&((T*)0)->member, "" __VA_ARGS__/*member_annotations*/, #type, sizeof(((T){0}).member) )
// find api // find api
@ -16655,11 +16660,11 @@ API array(reflect_t) members_find(const char *T);
// private api, still exposed // private api, still exposed
API void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos); API void type_inscribe(const char *TY,unsigned TYsz,const char *infos);
API void enum_inscribe(const char *E,unsigned Eid,unsigned Eval,const char *infos); API void enum_inscribe(const char *E,unsigned Eval,const char *infos);
API void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos); API void struct_inscribe(const char *T,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 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,unsigned Fid,void *func,const char *infos); API void function_inscribe(const char *F,void *func,const char *infos);
API void reflect_print(const char *symbol); API void reflect_print(const char *symbol);
API void reflect_dump(const char *mask); API void reflect_dump(const char *mask);
@ -343869,33 +343874,53 @@ AUTORUN {
reflect_init(); 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(); reflect_init();
unsigned TYid = intern(TY = symbol(TY));
map_find_or_add(reflects, TYid, ((reflect_t){TYid, 0, TYsz, TY, infos})); 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(); reflect_init();
unsigned Eid = intern(E = symbol(E));
map_find_or_add(reflects, Eid, ((reflect_t){Eid,0, Eval, E,infos})); map_find_or_add(reflects, Eid, ((reflect_t){Eid,0, Eval, E,infos}));
} }
unsigned enum_find(const char *E) { unsigned enum_find(const char *E) {
reflect_init(); reflect_init();
E = symbol(E);
return map_find(reflects, intern(E))->sz; 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(); reflect_init();
unsigned Fid = intern(F = symbol(F));
map_find_or_add(reflects, Fid, ((reflect_t){Fid,0, 0, F,infos, func})); map_find_or_add(reflects, Fid, ((reflect_t){Fid,0, 0, F,infos, func}));
reflect_t *found = map_find(reflects,Fid); reflect_t *found = map_find(reflects,Fid);
} }
void *function_find(const char *F) { void *function_find(const char *F) {
reflect_init(); reflect_init();
F = symbol(F);
return map_find(reflects, intern(F))->addr; 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(); reflect_init();
unsigned Tid = intern(T = symbol(T));
map_find_or_add(reflects, Tid, ((reflect_t){Tid, OBJTYPEid, Tsz, T, infos})); 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(); 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 })); map_find_or_add(reflects, (Mid<<16)|Tid, ((reflect_t){Mid, 0, Msz, M, infos, NULL, Tid, type }));
// add member separately as well // add member separately as well
if(!members) map_init_int(members); 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_t member_find(const char *T, const char *M) {
reflect_init(); reflect_init();
T = symbol(T);
M = symbol(M);
return *map_find(reflects, (intern(M)<<16)|intern(T)); return *map_find(reflects, (intern(M)<<16)|intern(T));
} }
void *member_findptr(void *obj, const char *T, const char *M) { void *member_findptr(void *obj, const char *T, const char *M) {
reflect_init(); reflect_init();
T = symbol(T);
M = symbol(M);
return (char*)obj + member_find(T,M).sz; return (char*)obj + member_find(T,M).sz;
} }
array(reflect_t) members_find(const char *T) { array(reflect_t) members_find(const char *T) {
reflect_init(); reflect_init();
T = symbol(T);
return *map_find(members, intern(T)); return *map_find(members, intern(T));
} }
@ -351411,11 +351441,37 @@ void app_hang() {
for(;;); for(;;);
} }
void app_crash() { void app_crash() {
int *p = 0; volatile int *p = 0;
*p = 42; *p = 42;
} }
void app_beep() { 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); 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) { 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) { int ui_notify(const char *title, const char *body) {
app_beep();
struct ui_notify n = {0}; struct ui_notify n = {0};
n.title = title && title[0] ? stringf("*%s", title) : 0; n.title = title && title[0] ? stringf("*%s", title) : 0;
n.body = body && body[0] ? STRDUP(body) : 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_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_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_outliner" )) ui_show("Outliner", ui_visible("Outliner") ^ true);
else if( !strcmp(cmd, "key_record" )) if(record_active()) record_stop(); else else if( !strcmp(cmd, "key_record" )) if(record_active()) record_stop(), ui_notify(va("Video recorded"), date_string()); else
name = file_counter(va("%s.mp4",app_name())), window_record(name), ui_notify(va("Video capturing: %s", name), date_string()); 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_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_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 else if( !strcmp(cmd, "key_fullscreen" )) record_stop(), window_fullscreen( window_has_fullscreen() ^ 1 ); // framebuffer resizing corrupts video stream, so stop any recording beforehand

View File

@ -169,6 +169,7 @@
#define conc4t(a,b) a##b ///- #define conc4t(a,b) a##b ///-
#define macro(name) concat(name, __LINE__) #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 defer(begin,end) for(int macro(i) = ((begin), 0); !macro(i); macro(i) = ((end), 1))
#define scope(end) defer((void)0, end) #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 )) #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(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) #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 #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 FILELINE __FILE__ ":" STRINGIZE(__LINE__)
#define STRINGIZE(x) STRINGIZ3(x) #define STRINGIZE(x) STRINGIZ3(x)
@ -286,7 +287,11 @@
__declspec(allocate(".CRT$XIU")) \ __declspec(allocate(".CRT$XIU")) \
static int(* concat(fn,__2) )() = concat(fn,__1); \ static int(* concat(fn,__2) )() = concat(fn,__1); \
static void fn(void) 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) \ #define AUTORUN_(fn) \
__attribute__((constructor(__COUNTER__+101))) \ __attribute__((constructor(__COUNTER__+101))) \
static void fn(void) static void fn(void)

View File

@ -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_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_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_outliner" )) ui_show("Outliner", ui_visible("Outliner") ^ true);
else if( !strcmp(cmd, "key_record" )) if(record_active()) record_stop(); else else if( !strcmp(cmd, "key_record" )) if(record_active()) record_stop(), ui_notify(va("Video recorded"), date_string()); else
name = file_counter(va("%s.mp4",app_name())), window_record(name), ui_notify(va("Video capturing: %s", name), date_string()); 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_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_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 else if( !strcmp(cmd, "key_fullscreen" )) record_stop(), window_fullscreen( window_has_fullscreen() ^ 1 ); // framebuffer resizing corrupts video stream, so stop any recording beforehand

View File

@ -14,33 +14,53 @@ AUTORUN {
reflect_init(); 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(); reflect_init();
unsigned TYid = intern(TY = symbol(TY));
map_find_or_add(reflects, TYid, ((reflect_t){TYid, 0, TYsz, TY, infos})); 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(); reflect_init();
unsigned Eid = intern(E = symbol(E));
map_find_or_add(reflects, Eid, ((reflect_t){Eid,0, Eval, E,infos})); map_find_or_add(reflects, Eid, ((reflect_t){Eid,0, Eval, E,infos}));
} }
unsigned enum_find(const char *E) { unsigned enum_find(const char *E) {
reflect_init(); reflect_init();
E = symbol(E);
return map_find(reflects, intern(E))->sz; 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(); reflect_init();
unsigned Fid = intern(F = symbol(F));
map_find_or_add(reflects, Fid, ((reflect_t){Fid,0, 0, F,infos, func})); map_find_or_add(reflects, Fid, ((reflect_t){Fid,0, 0, F,infos, func}));
reflect_t *found = map_find(reflects,Fid); reflect_t *found = map_find(reflects,Fid);
} }
void *function_find(const char *F) { void *function_find(const char *F) {
reflect_init(); reflect_init();
F = symbol(F);
return map_find(reflects, intern(F))->addr; 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(); reflect_init();
unsigned Tid = intern(T = symbol(T));
map_find_or_add(reflects, Tid, ((reflect_t){Tid, OBJTYPEid, Tsz, T, infos})); 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(); 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 })); map_find_or_add(reflects, (Mid<<16)|Tid, ((reflect_t){Mid, 0, Msz, M, infos, NULL, Tid, type }));
// add member separately as well // add member separately as well
if(!members) map_init_int(members); 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_t member_find(const char *T, const char *M) {
reflect_init(); reflect_init();
T = symbol(T);
M = symbol(M);
return *map_find(reflects, (intern(M)<<16)|intern(T)); return *map_find(reflects, (intern(M)<<16)|intern(T));
} }
void *member_findptr(void *obj, const char *T, const char *M) { void *member_findptr(void *obj, const char *T, const char *M) {
reflect_init(); reflect_init();
T = symbol(T);
M = symbol(M);
return (char*)obj + member_find(T,M).sz; return (char*)obj + member_find(T,M).sz;
} }
array(reflect_t) members_find(const char *T) { array(reflect_t) members_find(const char *T) {
reflect_init(); reflect_init();
T = symbol(T);
return *map_find(members, intern(T)); return *map_find(members, intern(T));
} }

View File

@ -26,15 +26,15 @@ typedef struct reflect_t {
// inscribe api // inscribe api
#define ENUM(V, .../*value_annotations*/) \ #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*/) \ #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*/) \ #define STRUCT(T, type, member, .../*member_annotations*/) \
struct_inscribe(#T,intern(#T),sizeof(T),OBJTYPE(T),NULL), \ struct_inscribe(#T,sizeof(T),OBJTYPE(T),NULL), \
type_inscribe(#type,intern(#type),sizeof(((T){0}).member),"" __VA_ARGS__/*member_annotations*/), \ type_inscribe(#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) ) member_inscribe(#T, #member,(uintptr_t)&((T*)0)->member, "" __VA_ARGS__/*member_annotations*/, #type, sizeof(((T){0}).member) )
// find api // find api
@ -54,11 +54,11 @@ API array(reflect_t) members_find(const char *T);
// private api, still exposed // private api, still exposed
API void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos); API void type_inscribe(const char *TY,unsigned TYsz,const char *infos);
API void enum_inscribe(const char *E,unsigned Eid,unsigned Eval,const char *infos); API void enum_inscribe(const char *E,unsigned Eval,const char *infos);
API void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos); API void struct_inscribe(const char *T,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 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,unsigned Fid,void *func,const char *infos); API void function_inscribe(const char *F,void *func,const char *infos);
API void reflect_print(const char *symbol); API void reflect_print(const char *symbol);
API void reflect_dump(const char *mask); API void reflect_dump(const char *mask);

View File

@ -793,11 +793,37 @@ void app_hang() {
for(;;); for(;;);
} }
void app_crash() { void app_crash() {
int *p = 0; volatile int *p = 0;
*p = 42; *p = 42;
} }
void app_beep() { 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); 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) { void app_singleton(const char *guid) {

View File

@ -1596,6 +1596,8 @@ int ui_label2_toolbar(const char *label, const char *icons) {
} }
int ui_notify(const char *title, const char *body) { int ui_notify(const char *title, const char *body) {
app_beep();
struct ui_notify n = {0}; struct ui_notify n = {0};
n.title = title && title[0] ? stringf("*%s", title) : 0; n.title = title && title[0] ? stringf("*%s", title) : 0;
n.body = body && body[0] ? STRDUP(body) : 0; n.body = body && body[0] ? STRDUP(body) : 0;

View File

@ -12794,33 +12794,53 @@ AUTORUN {
reflect_init(); 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(); reflect_init();
unsigned TYid = intern(TY = symbol(TY));
map_find_or_add(reflects, TYid, ((reflect_t){TYid, 0, TYsz, TY, infos})); 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(); reflect_init();
unsigned Eid = intern(E = symbol(E));
map_find_or_add(reflects, Eid, ((reflect_t){Eid,0, Eval, E,infos})); map_find_or_add(reflects, Eid, ((reflect_t){Eid,0, Eval, E,infos}));
} }
unsigned enum_find(const char *E) { unsigned enum_find(const char *E) {
reflect_init(); reflect_init();
E = symbol(E);
return map_find(reflects, intern(E))->sz; 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(); reflect_init();
unsigned Fid = intern(F = symbol(F));
map_find_or_add(reflects, Fid, ((reflect_t){Fid,0, 0, F,infos, func})); map_find_or_add(reflects, Fid, ((reflect_t){Fid,0, 0, F,infos, func}));
reflect_t *found = map_find(reflects,Fid); reflect_t *found = map_find(reflects,Fid);
} }
void *function_find(const char *F) { void *function_find(const char *F) {
reflect_init(); reflect_init();
F = symbol(F);
return map_find(reflects, intern(F))->addr; 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(); reflect_init();
unsigned Tid = intern(T = symbol(T));
map_find_or_add(reflects, Tid, ((reflect_t){Tid, OBJTYPEid, Tsz, T, infos})); 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(); 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 })); map_find_or_add(reflects, (Mid<<16)|Tid, ((reflect_t){Mid, 0, Msz, M, infos, NULL, Tid, type }));
// add member separately as well // add member separately as well
if(!members) map_init_int(members); 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_t member_find(const char *T, const char *M) {
reflect_init(); reflect_init();
T = symbol(T);
M = symbol(M);
return *map_find(reflects, (intern(M)<<16)|intern(T)); return *map_find(reflects, (intern(M)<<16)|intern(T));
} }
void *member_findptr(void *obj, const char *T, const char *M) { void *member_findptr(void *obj, const char *T, const char *M) {
reflect_init(); reflect_init();
T = symbol(T);
M = symbol(M);
return (char*)obj + member_find(T,M).sz; return (char*)obj + member_find(T,M).sz;
} }
array(reflect_t) members_find(const char *T) { array(reflect_t) members_find(const char *T) {
reflect_init(); reflect_init();
T = symbol(T);
return *map_find(members, intern(T)); return *map_find(members, intern(T));
} }
@ -20336,11 +20361,37 @@ void app_hang() {
for(;;); for(;;);
} }
void app_crash() { void app_crash() {
int *p = 0; volatile int *p = 0;
*p = 42; *p = 42;
} }
void app_beep() { 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); 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) { 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) { int ui_notify(const char *title, const char *body) {
app_beep();
struct ui_notify n = {0}; struct ui_notify n = {0};
n.title = title && title[0] ? stringf("*%s", title) : 0; n.title = title && title[0] ? stringf("*%s", title) : 0;
n.body = body && body[0] ? STRDUP(body) : 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_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_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_outliner" )) ui_show("Outliner", ui_visible("Outliner") ^ true);
else if( !strcmp(cmd, "key_record" )) if(record_active()) record_stop(); else else if( !strcmp(cmd, "key_record" )) if(record_active()) record_stop(), ui_notify(va("Video recorded"), date_string()); else
name = file_counter(va("%s.mp4",app_name())), window_record(name), ui_notify(va("Video capturing: %s", name), date_string()); 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_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_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 else if( !strcmp(cmd, "key_fullscreen" )) record_stop(), window_fullscreen( window_has_fullscreen() ^ 1 ); // framebuffer resizing corrupts video stream, so stop any recording beforehand

View File

@ -267,6 +267,7 @@ extern "C" {
#define conc4t(a,b) a##b ///- #define conc4t(a,b) a##b ///-
#define macro(name) concat(name, __LINE__) #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 defer(begin,end) for(int macro(i) = ((begin), 0); !macro(i); macro(i) = ((end), 1))
#define scope(end) defer((void)0, end) #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 )) #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(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) #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 #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 FILELINE __FILE__ ":" STRINGIZE(__LINE__)
#define STRINGIZE(x) STRINGIZ3(x) #define STRINGIZE(x) STRINGIZ3(x)
@ -384,7 +385,11 @@ extern "C" {
__declspec(allocate(".CRT$XIU")) \ __declspec(allocate(".CRT$XIU")) \
static int(* concat(fn,__2) )() = concat(fn,__1); \ static int(* concat(fn,__2) )() = concat(fn,__1); \
static void fn(void) 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) \ #define AUTORUN_(fn) \
__attribute__((constructor(__COUNTER__+101))) \ __attribute__((constructor(__COUNTER__+101))) \
static void fn(void) static void fn(void)
@ -2694,15 +2699,15 @@ typedef struct reflect_t {
// inscribe api // inscribe api
#define ENUM(V, .../*value_annotations*/) \ #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*/) \ #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*/) \ #define STRUCT(T, type, member, .../*member_annotations*/) \
struct_inscribe(#T,intern(#T),sizeof(T),OBJTYPE(T),NULL), \ struct_inscribe(#T,sizeof(T),OBJTYPE(T),NULL), \
type_inscribe(#type,intern(#type),sizeof(((T){0}).member),"" __VA_ARGS__/*member_annotations*/), \ type_inscribe(#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) ) member_inscribe(#T, #member,(uintptr_t)&((T*)0)->member, "" __VA_ARGS__/*member_annotations*/, #type, sizeof(((T){0}).member) )
// find api // find api
@ -2722,11 +2727,11 @@ API array(reflect_t) members_find(const char *T);
// private api, still exposed // private api, still exposed
API void type_inscribe(const char *TY,unsigned TYid,unsigned TYsz,const char *infos); API void type_inscribe(const char *TY,unsigned TYsz,const char *infos);
API void enum_inscribe(const char *E,unsigned Eid,unsigned Eval,const char *infos); API void enum_inscribe(const char *E,unsigned Eval,const char *infos);
API void struct_inscribe(const char *T,unsigned Tid,unsigned Tsz,unsigned OBJTYPEid, const char *infos); API void struct_inscribe(const char *T,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 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,unsigned Fid,void *func,const char *infos); API void function_inscribe(const char *F,void *func,const char *infos);
API void reflect_print(const char *symbol); API void reflect_print(const char *symbol);
API void reflect_dump(const char *mask); API void reflect_dump(const char *mask);