From 313f2e0ad4f210c6c713c95057d3825056614da8 Mon Sep 17 00:00:00 2001 From: Martin Fouilleul Date: Mon, 11 Sep 2023 17:53:55 +0200 Subject: [PATCH] Fix quit by sending an event to wakeup the main loop when calling oc_request_quit() --- samples/breakout/.gitignore | 2 +- src/app/app.h | 1 - src/app/osx_app.m | 24 +++++++++++++++++------- src/app/win32_app.c | 3 +++ src/app/win32_app.h | 3 +++ src/graphics/mtl_renderer.m | 4 ++++ src/runtime.c | 13 +++++++++---- src/util/macros.h | 1 + src/wasmbind/core_api.json | 2 +- 9 files changed, 39 insertions(+), 14 deletions(-) diff --git a/samples/breakout/.gitignore b/samples/breakout/.gitignore index 0742738..667da26 100644 --- a/samples/breakout/.gitignore +++ b/samples/breakout/.gitignore @@ -1,3 +1,3 @@ -Pong +Breakout profile.dtrace profile.spall diff --git a/src/app/app.h b/src/app/app.h index cf2b1df..890927e 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -282,7 +282,6 @@ ORCA_API void oc_init(void); ORCA_API void oc_terminate(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_set_cursor(oc_mouse_cursor cursor); diff --git a/src/app/osx_app.m b/src/app/osx_app.m index b0c6b35..f0e24a3 100644 --- a/src/app/osx_app.m +++ b/src/app/osx_app.m @@ -376,11 +376,9 @@ void oc_install_keyboard_layout_listener() { //NOTE: We set shouldQuit to true and send a Quit event // 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 - // false, oc_event_loop() will exit, and the user can execute any cleanup needed and - // exit the program. + // want to execute cleanup code. Use can then call oc_request_quit() to exit + // the main runloop - oc_appData.shouldQuit = true; oc_event event = {}; event.type = OC_EVENT_QUIT; oc_queue_event(&event); @@ -1162,9 +1160,21 @@ void oc_cancel_quit() void oc_request_quit() { oc_appData.shouldQuit = true; - oc_event event = {}; - event.type = OC_EVENT_QUIT; - oc_queue_event(&event); + + @autoreleasepool + { + 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) diff --git a/src/app/win32_app.c b/src/app/win32_app.c index 45f1762..9e4248d 100644 --- a/src/app/win32_app.c +++ b/src/app/win32_app.c @@ -170,6 +170,8 @@ void oc_init() SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &wheelScrollLines, 0); oc_appData.win32.wheelScrollLines = wheelScrollLines; + oc_appData.win32.mainThreadID = GetCurrentThreadId(); + oc_vsync_init(); } } @@ -659,6 +661,7 @@ void oc_cancel_quit() void oc_request_quit() { oc_appData.shouldQuit = true; + PostThreadMessage(oc_appData.win32.mainThreadID, OC_WM_USER_WAKEUP, 0, 0); } void oc_pump_events(f64 timeout) diff --git a/src/app/win32_app.h b/src/app/win32_app.h index 481eeac..47f3779 100644 --- a/src/app/win32_app.h +++ b/src/app/win32_app.h @@ -43,6 +43,8 @@ typedef struct oc_win32_app_data u32 clickCount[OC_MOUSE_BUTTON_COUNT]; u32 wheelScrollLines; + DWORD mainThreadID; + } oc_win32_app_data; #define OC_PLATFORM_APP_DATA oc_win32_app_data win32; @@ -50,6 +52,7 @@ typedef struct oc_win32_app_data enum OC_WM_USER { OC_WM_USER_DISPATCH_PROC = 0x0400, // WM_USER messages are defined from 0x400 to 0x7FFF + OC_WM_USER_WAKEUP = 0x0401, }; #endif __WIN32_APP_H_ diff --git a/src/graphics/mtl_renderer.m b/src/graphics/mtl_renderer.m index d66c2a7..10088bf 100644 --- a/src/graphics/mtl_renderer.m +++ b/src/graphics/mtl_renderer.m @@ -1368,6 +1368,10 @@ void oc_mtl_canvas_destroy(oc_canvas_backend* interface) @autoreleasepool { + id endBuffer = [backend->surface->commandQueue commandBuffer]; + [endBuffer commit]; + [endBuffer waitUntilCompleted]; + [backend->pathPipeline release]; [backend->segmentPipeline release]; [backend->backpropPipeline release]; diff --git a/src/runtime.c b/src/runtime.c index 7f1bca9..538257c 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -195,6 +195,11 @@ void oc_bridge_log(oc_log_level level, msg); } +void oc_bridge_request_quit(void) +{ + __orcaApp.quit = true; +} + typedef struct orca_surface_create_data { oc_window window; @@ -543,7 +548,7 @@ i32 orca_runloop(void* user) oc_ui_set_context(&app->debugOverlay.ui); - while(!oc_should_quit()) + while(!app->quit) { oc_event* event = 0; while((event = oc_next_event(oc_scratch())) != 0) @@ -575,7 +580,7 @@ i32 orca_runloop(void* user) { case OC_EVENT_WINDOW_CLOSE: { - oc_request_quit(); + app->quit = true; } break; @@ -857,7 +862,7 @@ i32 orca_runloop(void* user) } } - app->quit = true; + oc_request_quit(); return (0); } @@ -902,7 +907,7 @@ int main(int argc, char** argv) oc_thread* runloopThread = oc_thread_create(orca_runloop, 0); - while(!app->quit) + while(!oc_should_quit()) { oc_pump_events(-1); //TODO: what to do with mem scratch here? diff --git a/src/util/macros.h b/src/util/macros.h index 6fd9370..0b2bf41 100644 --- a/src/util/macros.h +++ b/src/util/macros.h @@ -110,6 +110,7 @@ inline T oc_cube(T a) // the def parameter must be a macro that takes a type, and optional arguments #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, ...) \ 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__) \ diff --git a/src/wasmbind/core_api.json b/src/wasmbind/core_api.json index 566cfb8..17c64ed 100644 --- a/src/wasmbind/core_api.json +++ b/src/wasmbind/core_api.json @@ -76,7 +76,7 @@ }, { "name": "oc_request_quit", - "cname": "oc_request_quit", + "cname": "oc_bridge_request_quit", "ret": {"name": "void", "tag": "v"}, "args": [] }, -- 2.25.1