-
-
Notifications
You must be signed in to change notification settings - Fork 184
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reimplemented blocking_event_loop for OSX #462
Conversation
7e05825
to
9abc2c1
Compare
- Reverted own NSApplication run implementation - Used same approach as for android and ios
9abc2c1
to
ea7d82b
Compare
When I run any of the examples using this PR on macos, I get a crash when the window loads. Seems to happen when macos.rs line 1240 gets called:
|
@markmurphydev, thanks diff --git a/src/native/macos.rs b/src/native/macos.rs
index 5ab3119..4820b66 100644
--- a/src/native/macos.rs
+++ b/src/native/macos.rs
@@ -1237,7 +1237,7 @@ where
if !conf.platform.blocking_event_loop || update_requested {
unsafe {
- msg_send_![view, performSelectorOnMainThread:sel!(setNeedsDisplay:) withObject:YES waitUntilDone:NO];
+ msg_send_![view, performSelectorOnMainThread:sel!(setNeedsDisplay:) withObject:nil waitUntilDone:NO];
}
}
thread::yield_now(); |
Thanks! With that change, the crash is fixed, but the Looking at the old implementation,
it seems to re-draw normally, and updates correctly while resizing. |
@markmurphydev, yeah, checked again, thanks
Because it expects YES as argument |
Great work, thanks for PR! Tho I am a bit scared merging it while I do not quite understand whats going on here, and not being a mac user myself doesn't really help too much :( I will review it eventually, but a brief description on what was wrong/how it works now would help! |
@not-fl3, yeah, of course, thanks |
@not-fl3, So, now view delegate functions call send_message in its functions: key_down, key_up and so on and parallel thread processes them (in context of view and on main thread, because opengl bindings not work sometimes otherwise) For or redrawing I used same approach as on ios I was not using timer and always having 60 fps, but I left it not limited, so probably timer aproach also needed but not sure where to put it for now, probably it should be separate thing for miniquad on all platforms I am not really sure about the need for MainThreadState, thing shared between two threads stored there, and I left some stuff there that is not probably needed in MacosDisplay itself but it is ok probably |
I finally revived my hackintosh! LGTM, but one little neat pick: diff --git a/src/native/macos.rs b/src/native/macos.rs
index ad1aab7..d416467 100644
--- a/src/native/macos.rs
+++ b/src/native/macos.rs
@@ -713,12 +713,6 @@ unsafe fn view_base_decl(decl: &mut ClassDecl) {
}
}
- extern "C" fn set_needs_display_hack(this: &Object, _: Sel) {
- unsafe {
- msg_send_![this, setNeedsDisplay: YES];
- }
- }
-
decl.add_method(
sel!(canBecomeKey),
yes as extern "C" fn(&Object, Sel) -> BOOL,
@@ -789,10 +783,6 @@ unsafe fn view_base_decl(decl: &mut ClassDecl) {
sel!(processMessage:),
process_message as extern "C" fn(&Object, Sel, ObjcId),
);
- decl.add_method(
- sel!(setNeedsDisplayHack),
- set_needs_display_hack as extern "C" fn(&Object, Sel),
- );
}
pub fn define_opengl_view_class() -> *const Class {
@@ -1282,7 +1272,7 @@ where
if !conf.platform.blocking_event_loop || update_requested {
unsafe {
- msg_send_![view, performSelectorOnMainThread:sel!(setNeedsDisplayHack) withObject:nil waitUntilDone:NO];
+ msg_send_![view, performSelectorOnMainThread:sel!(setNeedsDisplay:) withObject:YES waitUntilDone:NO];
}
}
thread::yield_now(); this seems to work fine for me for both opengl and metal, am I missing something? |
@not-fl3, it works for me too, but it works differently on arm chips |
@not-fl3, |
ufff I had no idea! I'll add a link to this very stackoverflow answer somewhere around Thanks for the PR, really impressive work! |
// Basically reimplementing msg_send![ns_app, run] here | ||
let () = msg_send![ns_app, finishLaunching]; | ||
let state = SendHack(state_original.clone()); | ||
thread::spawn(move || { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, somehow I ended up here again :)
I runned into this discussion: https://hero.handmade.network/forums/code-discussion/t/1409-main_game_loop_on_os_x#7886, and this made me question, do we really need this thread::spawn and [nsapp run] later? If we process the messages, maybe we can process them on right main thread?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this was my previous approach
#443
And I thought that I'm smart that I found it
Because it was my first experience of programming for osx and I found how to do window loop even though apple recommends using timer approach for games
But it seems that it isn't this simple and introduces multiple bugs, that should've been taken in account
#455
#464
And there would be more of them I think
So I decided to not fix bugs that I cannot predict and used a simple way
As I understand, sokol-app uses a timer approach and [NSApplication run]
https://github.com/floooh/sokol/blob/master/sokol_app.h#L3582
But, raylib via glfw uses nextEventMatchingMask loop and I can try to analyze their code and implement it as before, but possibly with less bugs
https://github.com/glfw/glfw/blob/master/src/cocoa_window.m#L1523
While solving this problem, decided to take a less hacky approach