Android run return (#1604)

* Initial Draft

* Minor clean up

* cargo fmt

* Removed accidental change

* Update CHANGELOG.md

Co-authored-by: VZout <=>
This commit is contained in:
Viktor Zoutman 2020-06-17 15:55:52 +02:00 committed by GitHub
parent 4b1b314ce2
commit bf62103417
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 99 additions and 38 deletions

View file

@ -5,6 +5,7 @@
- On Wayland, fix deadlock when calling to `set_inner_size` from a callback. - On Wayland, fix deadlock when calling to `set_inner_size` from a callback.
- On macOS, add `hide__other_applications` to `EventLoopWindowTarget` via existing `EventLoopWindowTargetExtMacOS` trait. `hide_other_applications` will hide other applications by calling `-[NSApplication hideOtherApplications: nil]`. - On macOS, add `hide__other_applications` to `EventLoopWindowTarget` via existing `EventLoopWindowTargetExtMacOS` trait. `hide_other_applications` will hide other applications by calling `-[NSApplication hideOtherApplications: nil]`.
- On android added support for `run_return`.
- On MacOS, Fixed fullscreen and dialog support for `run_return`. - On MacOS, Fixed fullscreen and dialog support for `run_return`.
# 0.22.2 (2020-05-16) # 0.22.2 (2020-05-16)

View file

@ -1,6 +1,7 @@
#![cfg(any( #![cfg(any(
target_os = "windows", target_os = "windows",
target_os = "macos", target_os = "macos",
target_os = "android",
target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd" target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"
))] ))]

View file

@ -44,6 +44,20 @@ fn poll(poll: Poll) -> Option<EventSource> {
pub struct EventLoop<T: 'static> { pub struct EventLoop<T: 'static> {
window_target: event_loop::EventLoopWindowTarget<T>, window_target: event_loop::EventLoopWindowTarget<T>,
user_queue: Arc<Mutex<VecDeque<T>>>, user_queue: Arc<Mutex<VecDeque<T>>>,
first_event: Option<EventSource>,
start_cause: event::StartCause,
looper: ThreadLooper,
running: bool,
}
macro_rules! call_event_handler {
( $event_handler:expr, $window_target:expr, $cf:expr, $event:expr ) => {{
if $cf != ControlFlow::Exit {
$event_handler($event, $window_target, &mut $cf);
} else {
$event_handler($event, $window_target, &mut ControlFlow::Exit);
}
}};
} }
impl<T: 'static> EventLoop<T> { impl<T: 'static> EventLoop<T> {
@ -56,42 +70,61 @@ impl<T: 'static> EventLoop<T> {
_marker: std::marker::PhantomData, _marker: std::marker::PhantomData,
}, },
user_queue: Default::default(), user_queue: Default::default(),
first_event: None,
start_cause: event::StartCause::Init,
looper: ThreadLooper::for_thread().unwrap(),
running: false,
} }
} }
pub fn run<F>(self, mut event_handler: F) -> ! pub fn run<F>(mut self, event_handler: F) -> !
where where
F: 'static F: 'static
+ FnMut(event::Event<'_, T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow), + FnMut(event::Event<'_, T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
{ {
let mut cf = ControlFlow::default(); self.run_return(event_handler);
let mut first_event = None; ::std::process::exit(0);
let mut start_cause = event::StartCause::Init; }
let looper = ThreadLooper::for_thread().unwrap();
let mut running = false;
loop { pub fn run_return<F>(&mut self, mut event_handler: F)
event_handler( where
event::Event::NewEvents(start_cause), F: FnMut(event::Event<'_, T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
{
let mut control_flow = ControlFlow::default();
'event_loop: loop {
call_event_handler!(
event_handler,
self.window_target(), self.window_target(),
&mut cf, control_flow,
event::Event::NewEvents(self.start_cause)
); );
let mut redraw = false; let mut redraw = false;
let mut resized = false; let mut resized = false;
match first_event.take() { match self.first_event.take() {
Some(EventSource::Callback) => match ndk_glue::poll_events().unwrap() { Some(EventSource::Callback) => match ndk_glue::poll_events().unwrap() {
Event::WindowCreated => { Event::WindowCreated => {
event_handler(event::Event::Resumed, self.window_target(), &mut cf); call_event_handler!(
event_handler,
self.window_target(),
control_flow,
event::Event::Resumed
);
} }
Event::WindowResized => resized = true, Event::WindowResized => resized = true,
Event::WindowRedrawNeeded => redraw = true, Event::WindowRedrawNeeded => redraw = true,
Event::WindowDestroyed => { Event::WindowDestroyed => {
event_handler(event::Event::Suspended, self.window_target(), &mut cf); call_event_handler!(
event_handler,
self.window_target(),
control_flow,
event::Event::Suspended
);
} }
Event::Pause => running = false, Event::Pause => self.running = false,
Event::Resume => running = true, Event::Resume => self.running = true,
Event::ConfigChanged => { Event::ConfigChanged => {
let am = ndk_glue::native_activity().asset_manager(); let am = ndk_glue::native_activity().asset_manager();
let config = Configuration::from_asset_manager(&am); let config = Configuration::from_asset_manager(&am);
@ -107,7 +140,12 @@ impl<T: 'static> EventLoop<T> {
scale_factor, scale_factor,
}, },
}; };
event_handler(event, self.window_target(), &mut cf); call_event_handler!(
event_handler,
self.window_target(),
control_flow,
event
);
} }
} }
_ => {} _ => {}
@ -147,7 +185,12 @@ impl<T: 'static> EventLoop<T> {
force: None, force: None,
}), }),
}; };
event_handler(event, self.window_target(), &mut cf); call_event_handler!(
event_handler,
self.window_target(),
control_flow,
event
);
} }
} }
InputEvent::KeyEvent(_) => {} // TODO InputEvent::KeyEvent(_) => {} // TODO
@ -160,50 +203,66 @@ impl<T: 'static> EventLoop<T> {
Some(EventSource::User) => { Some(EventSource::User) => {
let mut user_queue = self.user_queue.lock().unwrap(); let mut user_queue = self.user_queue.lock().unwrap();
while let Some(event) = user_queue.pop_front() { while let Some(event) = user_queue.pop_front() {
event_handler( call_event_handler!(
event::Event::UserEvent(event), event_handler,
self.window_target(), self.window_target(),
&mut cf, control_flow,
event::Event::UserEvent(event)
); );
} }
} }
None => {} None => {
control_flow = ControlFlow::Exit;
}
} }
event_handler( call_event_handler!(
event::Event::MainEventsCleared, event_handler,
self.window_target(), self.window_target(),
&mut cf, control_flow,
event::Event::MainEventsCleared
); );
if resized && running { if resized && self.running {
let size = MonitorHandle.size(); let size = MonitorHandle.size();
let event = event::Event::WindowEvent { let event = event::Event::WindowEvent {
window_id: window::WindowId(WindowId), window_id: window::WindowId(WindowId),
event: event::WindowEvent::Resized(size), event: event::WindowEvent::Resized(size),
}; };
event_handler(event, self.window_target(), &mut cf); call_event_handler!(event_handler, self.window_target(), control_flow, event);
} }
if redraw && running { if redraw && self.running {
let event = event::Event::RedrawRequested(window::WindowId(WindowId)); let event = event::Event::RedrawRequested(window::WindowId(WindowId));
event_handler(event, self.window_target(), &mut cf); call_event_handler!(event_handler, self.window_target(), control_flow, event);
} }
event_handler( call_event_handler!(
event::Event::RedrawEventsCleared, event_handler,
self.window_target(), self.window_target(),
&mut cf, control_flow,
event::Event::RedrawEventsCleared
); );
match cf { match control_flow {
ControlFlow::Exit => panic!(), ControlFlow::Exit => {
self.first_event = poll(
self.looper
.poll_once_timeout(Duration::from_millis(0))
.unwrap(),
);
self.start_cause = event::StartCause::WaitCancelled {
start: Instant::now(),
requested_resume: None,
};
break 'event_loop;
}
ControlFlow::Poll => { ControlFlow::Poll => {
start_cause = event::StartCause::Poll; self.start_cause = event::StartCause::Poll;
} }
ControlFlow::Wait => { ControlFlow::Wait => {
first_event = poll(looper.poll_all().unwrap()); self.first_event = poll(self.looper.poll_all().unwrap());
start_cause = event::StartCause::WaitCancelled { self.start_cause = event::StartCause::WaitCancelled {
start: Instant::now(), start: Instant::now(),
requested_resume: None, requested_resume: None,
} }
@ -215,8 +274,8 @@ impl<T: 'static> EventLoop<T> {
} else { } else {
instant - start instant - start
}; };
first_event = poll(looper.poll_all_timeout(duration).unwrap()); self.first_event = poll(self.looper.poll_all_timeout(duration).unwrap());
start_cause = if first_event.is_some() { self.start_cause = if self.first_event.is_some() {
event::StartCause::WaitCancelled { event::StartCause::WaitCancelled {
start, start,
requested_resume: Some(instant), requested_resume: Some(instant),