Fix quit by sending an event to wakeup the main loop when calling oc_request_quit()

This commit is contained in:
Martin Fouilleul 2023-09-11 17:53:55 +02:00
parent ab4abd28d7
commit 313f2e0ad4
9 changed files with 39 additions and 14 deletions

View File

@ -1,3 +1,3 @@
Pong Breakout
profile.dtrace profile.dtrace
profile.spall profile.spall

View File

@ -282,7 +282,6 @@ ORCA_API void oc_init(void);
ORCA_API void oc_terminate(void); ORCA_API void oc_terminate(void);
ORCA_API bool oc_should_quit(void); ORCA_API bool oc_should_quit(void);
ORCA_API void oc_cancel_quit(void);
ORCA_API void oc_request_quit(void); ORCA_API void oc_request_quit(void);
ORCA_API void oc_set_cursor(oc_mouse_cursor cursor); ORCA_API void oc_set_cursor(oc_mouse_cursor cursor);

View File

@ -376,11 +376,9 @@ void oc_install_keyboard_layout_listener()
{ {
//NOTE: We set shouldQuit to true and send a Quit event //NOTE: We set shouldQuit to true and send a Quit event
// We then return a value to cancel the direct termination because we still // We then return a value to cancel the direct termination because we still
// want to execte the code after oc_event_loop(). If the user didn't set shouldQuit to // want to execute cleanup code. Use can then call oc_request_quit() to exit
// false, oc_event_loop() will exit, and the user can execute any cleanup needed and // the main runloop
// exit the program.
oc_appData.shouldQuit = true;
oc_event event = {}; oc_event event = {};
event.type = OC_EVENT_QUIT; event.type = OC_EVENT_QUIT;
oc_queue_event(&event); oc_queue_event(&event);
@ -1162,9 +1160,21 @@ void oc_cancel_quit()
void oc_request_quit() void oc_request_quit()
{ {
oc_appData.shouldQuit = true; oc_appData.shouldQuit = true;
oc_event event = {};
event.type = OC_EVENT_QUIT; @autoreleasepool
oc_queue_event(&event); {
NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined
location:NSMakePoint(0, 0)
modifierFlags:0
timestamp:0.0
windowNumber:0
context:nil
subtype:0
data1:0
data2:0];
[NSApp postEvent:event atStart:NO];
}
} }
void oc_set_cursor(oc_mouse_cursor cursor) void oc_set_cursor(oc_mouse_cursor cursor)

View File

@ -170,6 +170,8 @@ void oc_init()
SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &wheelScrollLines, 0); SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &wheelScrollLines, 0);
oc_appData.win32.wheelScrollLines = wheelScrollLines; oc_appData.win32.wheelScrollLines = wheelScrollLines;
oc_appData.win32.mainThreadID = GetCurrentThreadId();
oc_vsync_init(); oc_vsync_init();
} }
} }
@ -659,6 +661,7 @@ void oc_cancel_quit()
void oc_request_quit() void oc_request_quit()
{ {
oc_appData.shouldQuit = true; oc_appData.shouldQuit = true;
PostThreadMessage(oc_appData.win32.mainThreadID, OC_WM_USER_WAKEUP, 0, 0);
} }
void oc_pump_events(f64 timeout) void oc_pump_events(f64 timeout)

View File

@ -43,6 +43,8 @@ typedef struct oc_win32_app_data
u32 clickCount[OC_MOUSE_BUTTON_COUNT]; u32 clickCount[OC_MOUSE_BUTTON_COUNT];
u32 wheelScrollLines; u32 wheelScrollLines;
DWORD mainThreadID;
} oc_win32_app_data; } oc_win32_app_data;
#define OC_PLATFORM_APP_DATA oc_win32_app_data win32; #define OC_PLATFORM_APP_DATA oc_win32_app_data win32;
@ -50,6 +52,7 @@ typedef struct oc_win32_app_data
enum OC_WM_USER enum OC_WM_USER
{ {
OC_WM_USER_DISPATCH_PROC = 0x0400, // WM_USER messages are defined from 0x400 to 0x7FFF OC_WM_USER_DISPATCH_PROC = 0x0400, // WM_USER messages are defined from 0x400 to 0x7FFF
OC_WM_USER_WAKEUP = 0x0401,
}; };
#endif __WIN32_APP_H_ #endif __WIN32_APP_H_

View File

@ -1368,6 +1368,10 @@ void oc_mtl_canvas_destroy(oc_canvas_backend* interface)
@autoreleasepool @autoreleasepool
{ {
id<MTLCommandBuffer> endBuffer = [backend->surface->commandQueue commandBuffer];
[endBuffer commit];
[endBuffer waitUntilCompleted];
[backend->pathPipeline release]; [backend->pathPipeline release];
[backend->segmentPipeline release]; [backend->segmentPipeline release];
[backend->backpropPipeline release]; [backend->backpropPipeline release];

View File

@ -195,6 +195,11 @@ void oc_bridge_log(oc_log_level level,
msg); msg);
} }
void oc_bridge_request_quit(void)
{
__orcaApp.quit = true;
}
typedef struct orca_surface_create_data typedef struct orca_surface_create_data
{ {
oc_window window; oc_window window;
@ -543,7 +548,7 @@ i32 orca_runloop(void* user)
oc_ui_set_context(&app->debugOverlay.ui); oc_ui_set_context(&app->debugOverlay.ui);
while(!oc_should_quit()) while(!app->quit)
{ {
oc_event* event = 0; oc_event* event = 0;
while((event = oc_next_event(oc_scratch())) != 0) while((event = oc_next_event(oc_scratch())) != 0)
@ -575,7 +580,7 @@ i32 orca_runloop(void* user)
{ {
case OC_EVENT_WINDOW_CLOSE: case OC_EVENT_WINDOW_CLOSE:
{ {
oc_request_quit(); app->quit = true;
} }
break; break;
@ -857,7 +862,7 @@ i32 orca_runloop(void* user)
} }
} }
app->quit = true; oc_request_quit();
return (0); return (0);
} }
@ -902,7 +907,7 @@ int main(int argc, char** argv)
oc_thread* runloopThread = oc_thread_create(orca_runloop, 0); oc_thread* runloopThread = oc_thread_create(orca_runloop, 0);
while(!app->quit) while(!oc_should_quit())
{ {
oc_pump_events(-1); oc_pump_events(-1);
//TODO: what to do with mem scratch here? //TODO: what to do with mem scratch here?

View File

@ -110,6 +110,7 @@ inline T oc_cube(T a)
// the def parameter must be a macro that takes a type, and optional arguments // the def parameter must be a macro that takes a type, and optional arguments
#if OC_COMPILER_CL #if OC_COMPILER_CL
//NOTE: size_t conflicts with u64 on MSVC, whereas it is a distinct type on clang
#define oc_tga_variants(def, ...) \ #define oc_tga_variants(def, ...) \
def(u8, ##__VA_ARGS__) def(i8, ##__VA_ARGS__) def(u16, ##__VA_ARGS__) def(i16, ##__VA_ARGS__) \ def(u8, ##__VA_ARGS__) def(i8, ##__VA_ARGS__) def(u16, ##__VA_ARGS__) def(i16, ##__VA_ARGS__) \
def(u32, ##__VA_ARGS__) def(i32, ##__VA_ARGS__) def(u64, ##__VA_ARGS__) def(i64, ##__VA_ARGS__) \ def(u32, ##__VA_ARGS__) def(i32, ##__VA_ARGS__) def(u64, ##__VA_ARGS__) def(i64, ##__VA_ARGS__) \

View File

@ -76,7 +76,7 @@
}, },
{ {
"name": "oc_request_quit", "name": "oc_request_quit",
"cname": "oc_request_quit", "cname": "oc_bridge_request_quit",
"ret": {"name": "void", "tag": "v"}, "ret": {"name": "void", "tag": "v"},
"args": [] "args": []
}, },