From 72fbbb08a3638ae569fa24de8117e2520d9f0c0a Mon Sep 17 00:00:00 2001 From: omigamedev Date: Wed, 8 Aug 2018 17:42:56 +0200 Subject: [PATCH] decouple renderer/events on mac --- PanoPainter-OSX/main.cpp | 209 ++++++++++++++++++++++++++++----------- engine/app_events.cpp | 6 +- engine/main.cpp | 2 - 3 files changed, 156 insertions(+), 61 deletions(-) diff --git a/PanoPainter-OSX/main.cpp b/PanoPainter-OSX/main.cpp index 9e29c22..d7d21b9 100644 --- a/PanoPainter-OSX/main.cpp +++ b/PanoPainter-OSX/main.cpp @@ -13,6 +13,12 @@ #include #import "objc_utils.h" +#include +#include + +std::deque> tasklist; +std::mutex task_mutex; + void global_exception_handler(NSException* e) { NSAlert *alert = [NSAlert alertWithMessageText:@"Recovery" @@ -160,6 +166,12 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime // this will not update unless 1/30th of a second has passed since the last update if (1 /*now < _prevTime + (1.0 / 30.0) &&*/ ) { + std::deque> working_list; + { + std::lock_guard lock(task_mutex); + working_list = std::move(tasklist); + } + // We draw on a secondary thread through the display link // When resizing the view, -reshape is called automatically on the main // thread. Add a mutex around to avoid the threads accessing the context @@ -167,6 +179,12 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime CGLLockContext([glctx CGLContextObj]); [glctx makeCurrentContext]; + while (!working_list.empty()) + { + working_list.front()(); + working_list.pop_front(); + } + if (App::I.redraw) { App::I.clear(); @@ -278,110 +296,187 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime } - (void)mouseDown:(NSEvent *)theEvent { - CGLLockContext([[self openGLContext] CGLContextObj]); +// CGLLockContext([[self openGLContext] CGLContextObj]); auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - App::I.mouse_down(0, mouseLoc.x, App::I.height - mouseLoc.y - 1, theEvent.pressure, kEventSource::Mouse); - CGLUnlockContext([[self openGLContext] CGLContextObj]); +// App::I.mouse_down(0, mouseLoc.x, App::I.height - mouseLoc.y - 1, theEvent.pressure, kEventSource::Mouse); +// CGLUnlockContext([[self openGLContext] CGLContextObj]); + { + std::lock_guard lock(task_mutex); + tasklist.emplace_back([mouseLoc,p=theEvent.pressure] { + App::I.mouse_down(0, mouseLoc.x, App::I.height - mouseLoc.y - 1, p, kEventSource::Mouse); + }); + } } - (void)rightMouseDown:(NSEvent *)theEvent { - CGLLockContext([[self openGLContext] CGLContextObj]); +// CGLLockContext([[self openGLContext] CGLContextObj]); auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - App::I.mouse_down(1, mouseLoc.x, App::I.height - mouseLoc.y - 1, theEvent.pressure, kEventSource::Mouse); - CGLUnlockContext([[self openGLContext] CGLContextObj]); +// App::I.mouse_down(1, mouseLoc.x, App::I.height - mouseLoc.y - 1, theEvent.pressure, kEventSource::Mouse); +// CGLUnlockContext([[self openGLContext] CGLContextObj]); + { + std::lock_guard lock(task_mutex); + tasklist.emplace_back([mouseLoc,p=theEvent.pressure] { + App::I.mouse_down(1, mouseLoc.x, App::I.height - mouseLoc.y - 1, p, kEventSource::Mouse); + }); + } } - (void)mouseUp:(NSEvent *)theEvent { - CGLLockContext([[self openGLContext] CGLContextObj]); +// CGLLockContext([[self openGLContext] CGLContextObj]); auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - App::I.mouse_up(0, mouseLoc.x, App::I.height - mouseLoc.y - 1, kEventSource::Mouse); - CGLUnlockContext([[self openGLContext] CGLContextObj]); +// App::I.mouse_up(0, mouseLoc.x, App::I.height - mouseLoc.y - 1, kEventSource::Mouse); +// CGLUnlockContext([[self openGLContext] CGLContextObj]); + { + std::lock_guard lock(task_mutex); + tasklist.emplace_back([mouseLoc] { + App::I.mouse_up(0, mouseLoc.x, App::I.height - mouseLoc.y - 1, kEventSource::Mouse); + }); + } } - (void)rightMouseUp:(NSEvent *)theEvent { - CGLLockContext([[self openGLContext] CGLContextObj]); +// CGLLockContext([[self openGLContext] CGLContextObj]); auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - App::I.mouse_up(1, mouseLoc.x, App::I.height - mouseLoc.y - 1, kEventSource::Mouse); - CGLUnlockContext([[self openGLContext] CGLContextObj]); +// App::I.mouse_up(1, mouseLoc.x, App::I.height - mouseLoc.y - 1, kEventSource::Mouse); +// CGLUnlockContext([[self openGLContext] CGLContextObj]); + { + std::lock_guard lock(task_mutex); + tasklist.emplace_back([mouseLoc] { + App::I.mouse_up(1, mouseLoc.x, App::I.height - mouseLoc.y - 1, kEventSource::Mouse); + }); + } } - (void)mouseMoved:(NSEvent *)theEvent { - CGLLockContext([[self openGLContext] CGLContextObj]); +// CGLLockContext([[self openGLContext] CGLContextObj]); auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - App::I.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1, theEvent.pressure, kEventSource::Mouse); - CGLUnlockContext([[self openGLContext] CGLContextObj]); +// App::I.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1, theEvent.pressure, kEventSource::Mouse); +// CGLUnlockContext([[self openGLContext] CGLContextObj]); + { + std::lock_guard lock(task_mutex); + tasklist.emplace_back([mouseLoc,p=theEvent.pressure] { + App::I.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1, p, kEventSource::Mouse); + }); + } } -(void)mouseDragged:(NSEvent *)theEvent { - CGLLockContext([[self openGLContext] CGLContextObj]); +// CGLLockContext([[self openGLContext] CGLContextObj]); auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - App::I.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1, theEvent.pressure, kEventSource::Mouse); - CGLUnlockContext([[self openGLContext] CGLContextObj]); +// App::I.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1, theEvent.pressure, kEventSource::Mouse); +// CGLUnlockContext([[self openGLContext] CGLContextObj]); + { + std::lock_guard lock(task_mutex); + tasklist.emplace_back([mouseLoc,p=theEvent.pressure] { + App::I.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1, p, kEventSource::Mouse); + }); + } } - (void)rightMouseDragged:(NSEvent *)theEvent { - CGLLockContext([[self openGLContext] CGLContextObj]); +// CGLLockContext([[self openGLContext] CGLContextObj]); auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - App::I.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1, theEvent.pressure, kEventSource::Mouse); - CGLUnlockContext([[self openGLContext] CGLContextObj]); +// App::I.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1, theEvent.pressure, kEventSource::Mouse); +// CGLUnlockContext([[self openGLContext] CGLContextObj]); + { + std::lock_guard lock(task_mutex); + tasklist.emplace_back([mouseLoc,p=theEvent.pressure] { + App::I.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1, p, kEventSource::Mouse); + }); + } } - (void)scrollWheel:(NSEvent *)theEvent { - CGLLockContext([[self openGLContext] CGLContextObj]); +// CGLLockContext([[self openGLContext] CGLContextObj]); auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - App::I.mouse_scroll(mouseLoc.x, App::I.height - mouseLoc.y - 1, [theEvent deltaY]); - CGLUnlockContext([[self openGLContext] CGLContextObj]); +// App::I.mouse_scroll(mouseLoc.x, App::I.height - mouseLoc.y - 1, [theEvent deltaY]); +// CGLUnlockContext([[self openGLContext] CGLContextObj]); + { + std::lock_guard lock(task_mutex); + tasklist.emplace_back([mouseLoc,d=[theEvent deltaY]] { + App::I.mouse_scroll(mouseLoc.x, App::I.height - mouseLoc.y - 1, d); + }); + } } - (void)keyDown:(NSEvent *)theEvent { - CGLLockContext([[self openGLContext] CGLContextObj]); +// CGLLockContext([[self openGLContext] CGLContextObj]); auto keyCode = [theEvent keyCode]; auto chars = [theEvent characters]; - if (App::I.keys[(int)kKey::KeyCtrl]) +// if (App::I.keys[(int)kKey::KeyCtrl]) +// { +// App::I.key_down(convert_key(keyCode)); +// App::I.key_up(convert_key(keyCode)); +// } +// else +// { +// App::I.key_down(convert_key(keyCode)); +// if (const char* cstr = [chars cStringUsingEncoding:NSASCIIStringEncoding]) +// App::I.key_char(cstr[0]); +// } +// CGLUnlockContext([[self openGLContext] CGLContextObj]); + std::string s = [chars cStringUsingEncoding:NSASCIIStringEncoding]; { - App::I.key_down(convert_key(keyCode)); - App::I.key_up(convert_key(keyCode)); + std::lock_guard lock(task_mutex); + tasklist.emplace_back([keyCode, s] { + if (App::I.keys[(int)kKey::KeyCtrl]) + { + App::I.key_down(convert_key(keyCode)); + App::I.key_up(convert_key(keyCode)); + } + else + { + App::I.key_down(convert_key(keyCode)); + if (!s.empty()) + App::I.key_char(s[0]); + } + }); } - else - { - App::I.key_down(convert_key(keyCode)); - if (const char* cstr = [chars cStringUsingEncoding:NSASCIIStringEncoding]) - App::I.key_char(cstr[0]); - } - CGLUnlockContext([[self openGLContext] CGLContextObj]); } - (void)keyUp:(NSEvent *)theEvent { - CGLLockContext([[self openGLContext] CGLContextObj]); +// CGLLockContext([[self openGLContext] CGLContextObj]); auto keyCode = [theEvent keyCode]; - //auto chars = [theEvent characters]; - App::I.key_up(convert_key(keyCode)); - CGLUnlockContext([[self openGLContext] CGLContextObj]); +// App::I.key_up(convert_key(keyCode)); +// CGLUnlockContext([[self openGLContext] CGLContextObj]); + { + std::lock_guard lock(task_mutex); + tasklist.emplace_back([keyCode] { + App::I.key_up(convert_key(keyCode)); + }); + } } - (void)flagsChanged:(NSEvent *)event { [super flagsChanged:event]; - CGLLockContext([[self openGLContext] CGLContextObj]); - static bool pressed_shift = false; - if (pressed_shift != ([event modifierFlags] & NSShiftKeyMask)) +// CGLLockContext([[self openGLContext] CGLContextObj]); + auto flags = [event modifierFlags]; { - pressed_shift = ([event modifierFlags] & NSShiftKeyMask); - pressed_shift ? App::I.key_down(kKey::KeyShift) : App::I.key_up(kKey::KeyShift); + std::lock_guard lock(task_mutex); + tasklist.emplace_back([flags] { + static bool pressed_shift = false; + if (pressed_shift != (flags & NSShiftKeyMask)) + { + pressed_shift = (flags & NSShiftKeyMask); + pressed_shift ? App::I.key_down(kKey::KeyShift) : App::I.key_up(kKey::KeyShift); + } + static bool pressed_alt = false; + if (pressed_alt != (flags & NSAlternateKeyMask)) + { + pressed_alt = (flags & NSAlternateKeyMask); + pressed_alt ? App::I.key_down(kKey::KeyAlt) : App::I.key_up(kKey::KeyAlt); + } + static bool pressed_cmd = false; + if (pressed_cmd != (flags & NSCommandKeyMask)) + { + pressed_cmd = (flags & NSCommandKeyMask); + pressed_cmd ? App::I.key_down(kKey::KeyCtrl) : App::I.key_up(kKey::KeyCtrl); + } + }); } - static bool pressed_alt = false; - if (pressed_alt != ([event modifierFlags] & NSAlternateKeyMask)) - { - pressed_alt = ([event modifierFlags] & NSAlternateKeyMask); - pressed_alt ? App::I.key_down(kKey::KeyAlt) : App::I.key_up(kKey::KeyAlt); - } - static bool pressed_cmd = false; - if (pressed_cmd != ([event modifierFlags] & NSCommandKeyMask)) - { - pressed_cmd = ([event modifierFlags] & NSCommandKeyMask); - pressed_cmd ? App::I.key_down(kKey::KeyCtrl) : App::I.key_up(kKey::KeyCtrl); - } - CGLUnlockContext([[self openGLContext] CGLContextObj]); + +// CGLUnlockContext([[self openGLContext] CGLContextObj]); } @end diff --git a/engine/app_events.cpp b/engine/app_events.cpp index effc834..3f56d14 100644 --- a/engine/app_events.cpp +++ b/engine/app_events.cpp @@ -49,8 +49,10 @@ void App::pick_image(std::function callback) #ifdef __IOS__ [ios_view pick_photo:callback]; #elif __OSX__ - std::string path = [osx_view pick_file]; - callback(path); + dispatch_async(dispatch_get_main_queue(), ^{ + std::string path = [osx_view pick_file]; + callback(path); + }); #elif __ANDROID__ //displayKeyboard(and_app, false); #elif _WIN32 diff --git a/engine/main.cpp b/engine/main.cpp index e7d6b1e..d4157d3 100644 --- a/engine/main.cpp +++ b/engine/main.cpp @@ -577,7 +577,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) tasklist.emplace_back([wp] { App::I.key_down(convert_key((int)wp)); }); - break; } break; case WM_SYSKEYUP: @@ -640,7 +639,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) tasklist.emplace_back([lp]{ App::I.mouse_up(1, (float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp), kEventSource::Mouse); }); - break; } break; case WM_MOUSEWHEEL: