Allow driving resfresh from an NSTimer, which triggers even during live resize

This commit is contained in:
Martin Fouilleul 2022-08-16 09:57:30 +02:00
parent 5cfaf909fc
commit 6fe1a29a4b
2 changed files with 77 additions and 40 deletions

View File

@ -331,20 +331,22 @@ mp_view mp_view_bring_to_front(mp_view view);
mp_view mp_view_send_to_back(mp_view view); mp_view mp_view_send_to_back(mp_view view);
*/ */
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Main loop throttle // Main loop and events handling
//-------------------------------------------------------------------- //--------------------------------------------------------------------
void mp_set_target_fps(u32 fps); // or use wait vblank? typedef void(*mp_event_callback)(mp_event event, void* data);
void mp_set_event_callback(mp_event_callback callback, void* data);
void mp_set_target_fps(u32 fps);
void mp_run_loop();
//--------------------------------------------------------------------
// Events handling
//--------------------------------------------------------------------
void mp_pump_events(f64 timeout); void mp_pump_events(f64 timeout);
bool mp_next_event(mp_event* event); bool mp_next_event(mp_event* event);
typedef void(*mp_live_resize_callback)(mp_event event, void* data); typedef void(*mp_live_resize_callback)(mp_event event, void* data);
void mp_set_live_resize_callback(mp_live_resize_callback callback, void* data); void mp_set_live_resize_callback(mp_live_resize_callback callback, void* data);
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Input state polling // Input state polling
//-------------------------------------------------------------------- //--------------------------------------------------------------------

View File

@ -174,9 +174,14 @@ struct mp_app_data
mp_live_resize_callback liveResizeCallback; mp_live_resize_callback liveResizeCallback;
void* liveResizeData; void* liveResizeData;
//TODO: we should probably use a CVDisplayLink, but it complexifies things since
// it's called from another thread
NSTimer* frameTimer;
mp_event_callback eventCallback;
void* eventData;
mp_frame_stats frameStats; mp_frame_stats frameStats;
NSTimer* frameTimer;
NSCursor* cursor; NSCursor* cursor;
mp_window_data windowPool[MP_APP_MAX_WINDOWS]; mp_window_data windowPool[MP_APP_MAX_WINDOWS];
list_info windowFreeList; list_info windowFreeList;
@ -665,6 +670,14 @@ static void mp_queue_event(mp_event* event)
} }
} }
static void mp_dispatch_event(mp_event* event)
{
if(__mpAppData.eventCallback)
{
__mpAppData.eventCallback(*event, __mpAppData.eventData);
}
}
//--------------------------------------------------------------- //---------------------------------------------------------------
// Application and app delegate // Application and app delegate
//--------------------------------------------------------------- //---------------------------------------------------------------
@ -693,7 +706,7 @@ static void mp_queue_event(mp_event* event)
__mpAppData.shouldQuit = true; __mpAppData.shouldQuit = true;
mp_event event = {}; mp_event event = {};
event.type = MP_EVENT_QUIT; event.type = MP_EVENT_QUIT;
mp_queue_event(&event); mp_dispatch_event(&event);
return(NSTerminateCancel); return(NSTerminateCancel);
} }
@ -721,7 +734,7 @@ static void mp_queue_event(mp_event* event)
{ {
mp_event event = {}; mp_event event = {};
event.type = MP_EVENT_FRAME; event.type = MP_EVENT_FRAME;
mp_queue_event(&event); mp_dispatch_event(&event);
} }
- (void)applicationDidFinishLaunching:(NSNotification *)notification - (void)applicationDidFinishLaunching:(NSNotification *)notification
@ -795,7 +808,7 @@ static void mp_queue_event(mp_event* event)
mpWindow->hidden = false; mpWindow->hidden = false;
mp_queue_event(&event); mp_dispatch_event(&event);
} }
- (void)windowDidResignKey:(NSNotification*)notification - (void)windowDidResignKey:(NSNotification*)notification
@ -804,7 +817,7 @@ static void mp_queue_event(mp_event* event)
event.window = mp_window_handle_from_ptr(mpWindow); event.window = mp_window_handle_from_ptr(mpWindow);
event.type = MP_EVENT_WINDOW_UNFOCUS; event.type = MP_EVENT_WINDOW_UNFOCUS;
mp_queue_event(&event); mp_dispatch_event(&event);
} }
- (void)windowDidMove:(NSNotification *)notification - (void)windowDidMove:(NSNotification *)notification
@ -821,7 +834,7 @@ static void mp_queue_event(mp_event* event)
event.frame.rect.w = contentRect.size.width; event.frame.rect.w = contentRect.size.width;
event.frame.rect.h = contentRect.size.height; event.frame.rect.h = contentRect.size.height;
mp_queue_event(&event); mp_dispatch_event(&event);
} }
- (void)windowDidResize:(NSNotification *)notification - (void)windowDidResize:(NSNotification *)notification
@ -848,7 +861,7 @@ static void mp_queue_event(mp_event* event)
} }
//TODO: also ensure we don't overflow the queue during live resize... //TODO: also ensure we don't overflow the queue during live resize...
mp_queue_event(&event); mp_dispatch_event(&event);
} }
-(void)windowWillStartLiveResize:(NSNotification *)notification -(void)windowWillStartLiveResize:(NSNotification *)notification
@ -880,7 +893,7 @@ static void mp_queue_event(mp_event* event)
event.window = mp_window_handle_from_ptr(mpWindow); event.window = mp_window_handle_from_ptr(mpWindow);
event.type = MP_EVENT_WINDOW_CLOSE; event.type = MP_EVENT_WINDOW_CLOSE;
mp_queue_event(&event); mp_dispatch_event(&event);
return(mpWindow->shouldClose); return(mpWindow->shouldClose);
} }
@ -987,7 +1000,7 @@ static void mp_queue_event(mp_event* event)
__mpAppData.inputState.mouse.buttons[event.key.code].doubleClicked = true; __mpAppData.inputState.mouse.buttons[event.key.code].doubleClicked = true;
} }
mp_queue_event(&event); mp_dispatch_event(&event);
[window->nsWindow makeFirstResponder:self]; [window->nsWindow makeFirstResponder:self];
} }
@ -1004,7 +1017,7 @@ static void mp_queue_event(mp_event* event)
mp_update_key_state(&__mpAppData.inputState.mouse.buttons[event.key.code], false); mp_update_key_state(&__mpAppData.inputState.mouse.buttons[event.key.code], false);
mp_queue_event(&event); mp_dispatch_event(&event);
} }
- (void)rightMouseDown:(NSEvent*)nsEvent - (void)rightMouseDown:(NSEvent*)nsEvent
@ -1018,7 +1031,7 @@ static void mp_queue_event(mp_event* event)
mp_update_key_state(&__mpAppData.inputState.mouse.buttons[event.key.code], true); mp_update_key_state(&__mpAppData.inputState.mouse.buttons[event.key.code], true);
mp_queue_event(&event); mp_dispatch_event(&event);
} }
- (void)rightMouseUp:(NSEvent*)nsEvent - (void)rightMouseUp:(NSEvent*)nsEvent
@ -1032,7 +1045,7 @@ static void mp_queue_event(mp_event* event)
mp_update_key_state(&__mpAppData.inputState.mouse.buttons[event.key.code], false); mp_update_key_state(&__mpAppData.inputState.mouse.buttons[event.key.code], false);
mp_queue_event(&event); mp_dispatch_event(&event);
} }
- (void)otherMouseDown:(NSEvent*)nsEvent - (void)otherMouseDown:(NSEvent*)nsEvent
@ -1046,7 +1059,7 @@ static void mp_queue_event(mp_event* event)
mp_update_key_state(&__mpAppData.inputState.mouse.buttons[event.key.code], true); mp_update_key_state(&__mpAppData.inputState.mouse.buttons[event.key.code], true);
mp_queue_event(&event); mp_dispatch_event(&event);
} }
- (void)otherMouseUp:(NSEvent*)nsEvent - (void)otherMouseUp:(NSEvent*)nsEvent
@ -1060,7 +1073,7 @@ static void mp_queue_event(mp_event* event)
mp_update_key_state(&__mpAppData.inputState.mouse.buttons[event.key.code], false); mp_update_key_state(&__mpAppData.inputState.mouse.buttons[event.key.code], false);
mp_queue_event(&event); mp_dispatch_event(&event);
} }
- (void)mouseDragged:(NSEvent*)nsEvent - (void)mouseDragged:(NSEvent*)nsEvent
@ -1084,7 +1097,7 @@ static void mp_queue_event(mp_event* event)
mp_update_mouse_move(p.x, p.y, event.move.deltaX, event.move.deltaY); mp_update_mouse_move(p.x, p.y, event.move.deltaX, event.move.deltaY);
mp_queue_event(&event); mp_dispatch_event(&event);
} }
- (void)scrollWheel:(NSEvent*)nsEvent - (void)scrollWheel:(NSEvent*)nsEvent
@ -1102,7 +1115,7 @@ static void mp_queue_event(mp_event* event)
mp_update_mouse_wheel(event.move.deltaX, event.move.deltaY); mp_update_mouse_wheel(event.move.deltaX, event.move.deltaY);
mp_queue_event(&event); mp_dispatch_event(&event);
} }
- (void)mouseExited:(NSEvent *)nsEvent - (void)mouseExited:(NSEvent *)nsEvent
@ -1110,7 +1123,7 @@ static void mp_queue_event(mp_event* event)
mp_event event = {}; mp_event event = {};
event.window = mp_window_handle_from_ptr(window); event.window = mp_window_handle_from_ptr(window);
event.type = MP_EVENT_MOUSE_LEAVE; event.type = MP_EVENT_MOUSE_LEAVE;
mp_queue_event(&event); mp_dispatch_event(&event);
} }
- (void)mouseEntered:(NSEvent *)nsEvent - (void)mouseEntered:(NSEvent *)nsEvent
@ -1118,7 +1131,7 @@ static void mp_queue_event(mp_event* event)
mp_event event = {}; mp_event event = {};
event.window = mp_window_handle_from_ptr(window); event.window = mp_window_handle_from_ptr(window);
event.type = MP_EVENT_MOUSE_ENTER; event.type = MP_EVENT_MOUSE_ENTER;
mp_queue_event(&event); mp_dispatch_event(&event);
} }
@ -1138,7 +1151,7 @@ static void mp_queue_event(mp_event* event)
mp_update_key_state(&__mpAppData.inputState.keyboard.keys[event.key.code], true); mp_update_key_state(&__mpAppData.inputState.keyboard.keys[event.key.code], true);
mp_queue_event(&event); mp_dispatch_event(&event);
[self interpretKeyEvents:@[nsEvent]]; [self interpretKeyEvents:@[nsEvent]];
} }
@ -1154,7 +1167,7 @@ static void mp_queue_event(mp_event* event)
mp_update_key_state(&__mpAppData.inputState.keyboard.keys[event.key.code], false); mp_update_key_state(&__mpAppData.inputState.keyboard.keys[event.key.code], false);
mp_queue_event(&event); mp_dispatch_event(&event);
} }
- (void) flagsChanged:(NSEvent*)nsEvent - (void) flagsChanged:(NSEvent*)nsEvent
@ -1166,7 +1179,7 @@ static void mp_queue_event(mp_event* event)
mp_update_key_mods(event.key.mods); mp_update_key_mods(event.key.mods);
mp_queue_event(&event); mp_dispatch_event(&event);
} }
- (BOOL)performKeyEquivalent:(NSEvent*)nsEvent - (BOOL)performKeyEquivalent:(NSEvent*)nsEvent
@ -1185,7 +1198,7 @@ static void mp_queue_event(mp_event* event)
mp_event event = {}; mp_event event = {};
event.type = MP_EVENT_QUIT; event.type = MP_EVENT_QUIT;
mp_queue_event(&event); mp_dispatch_event(&event);
//[NSApp terminate:self]; //[NSApp terminate:self];
return(YES); return(YES);
@ -1306,7 +1319,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
mp_update_text(codepoint); mp_update_text(codepoint);
mp_queue_event(&event); mp_dispatch_event(&event);
} }
} }
[self unmarkText]; [self unmarkText];
@ -1353,12 +1366,9 @@ CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink,
CVOptionFlags *flagsOut, CVOptionFlags *flagsOut,
void *displayLinkContext) void *displayLinkContext)
{ {
if(__mpAppData.liveResizeCallback) if(__mpAppData.displayRefreshCallback)
{ {
mp_event event = {}; __mpAppData.displayRefreshCallback(__mpAppData.displayRefreshData);
event.type = MP_EVENT_FRAME;
__mpAppData.liveResizeCallback(event, __mpAppData.liveResizeData);
} }
return(0); return(0);
@ -1406,11 +1416,12 @@ void mp_init()
LOG_MESSAGE("run application\n"); LOG_MESSAGE("run application\n");
[NSApp run]; [NSApp run];
/*TODO: maybe some day send frame events during live resize, without breaking everyting... /*
CGDirectDisplayID displayID = CGMainDisplayID(); CGDirectDisplayID displayID = CGMainDisplayID();
CVDisplayLinkCreateWithCGDisplay(displayID, &__mpAppData.displayLink); CVDisplayLinkCreateWithCGDisplay(displayID, &__mpAppData.displayLink);
CVDisplayLinkSetOutputCallback(__mpAppData.displayLink, DisplayLinkCallback, 0); CVDisplayLinkSetOutputCallback(__mpAppData.displayLink, DisplayLinkCallback, 0);
*/ */
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
[NSApp activateIgnoringOtherApps:YES]; [NSApp activateIgnoringOtherApps:YES];
@ -1446,7 +1457,7 @@ void mp_request_quit()
__mpAppData.shouldQuit = true; __mpAppData.shouldQuit = true;
mp_event event = {}; mp_event event = {};
event.type = MP_EVENT_QUIT; event.type = MP_EVENT_QUIT;
mp_queue_event(&event); mp_dispatch_event(&event);
} }
void mp_set_cursor(mp_mouse_cursor cursor) void mp_set_cursor(mp_mouse_cursor cursor)
@ -1980,10 +1991,6 @@ void mp_view_set_frame(mp_view viewHandle, mp_rect frame)
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Main loop throttle // Main loop throttle
//-------------------------------------------------------------------- //--------------------------------------------------------------------
/*
////////////////////////////////////////////////////////////
//TODO
////////////////////////////////////////////////////////////
void mp_set_target_fps(u32 fps) void mp_set_target_fps(u32 fps)
{ {
@ -2004,7 +2011,7 @@ void mp_set_target_fps(u32 fps)
[[NSRunLoop currentRunLoop] addTimer:__mpAppData.frameTimer forMode:NSRunLoopCommonModes]; [[NSRunLoop currentRunLoop] addTimer:__mpAppData.frameTimer forMode:NSRunLoopCommonModes];
} }
/*
void mp_begin_frame() void mp_begin_frame()
{ {
__mpAppData.frameStats.start = mp_get_elapsed_seconds(); __mpAppData.frameStats.start = mp_get_elapsed_seconds();
@ -2043,6 +2050,13 @@ void mp_set_live_resize_callback(mp_live_resize_callback callback, void* data)
__mpAppData.liveResizeData = data; __mpAppData.liveResizeData = data;
} }
void mp_set_event_callback(mp_event_callback callback, void* data)
{
__mpAppData.eventCallback = callback;
__mpAppData.eventData = data;
}
void mp_pump_events(f64 timeout) void mp_pump_events(f64 timeout)
{ {
__mpAppData.inputState.frameCounter++; __mpAppData.inputState.frameCounter++;
@ -2104,6 +2118,27 @@ bool mp_next_event(mp_event* event)
} }
} }
void mp_run_loop()
{@autoreleasepool {
//CVDisplayLinkStart(__mpAppData.displayLink);
while(!__mpAppData.shouldQuit)
{
NSEvent* event = [NSApp nextEventMatchingMask: NSEventMaskAny
untilDate:[NSDate distantFuture]
inMode: NSDefaultRunLoopMode
dequeue: YES];
if(event != nil)
{
[NSApp sendEvent:event];
}
}
//CVDisplayLinkStop(__mpAppData.displayLink);
}}
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Input state polling // Input state polling
//-------------------------------------------------------------------- //--------------------------------------------------------------------