diff --git a/.gitignore b/.gitignore index eb5a316..a9d37c5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ target +Cargo.lock diff --git a/android-activity/src/game_activity/mod.rs b/android-activity/src/game_activity/mod.rs index 7cf3894..333de52 100644 --- a/android-activity/src/game_activity/mod.rs +++ b/android-activity/src/game_activity/mod.rs @@ -8,6 +8,7 @@ use std::ptr; use std::ptr::NonNull; use std::sync::Weak; use std::sync::{Arc, Mutex, RwLock}; +use std::task::{RawWaker, RawWakerVTable, Waker}; use std::time::Duration; use libc::c_void; @@ -118,6 +119,27 @@ impl AndroidAppWaker { ALooper_wake(self.looper.as_ptr()); } } + + /// Creates a [`Waker`] that wakes up the [`AndroidApp`]. + /// + /// This is useful for using this crate in `async` environments. + /// + /// [`Waker`]: std::task::Waker + pub fn waker(self) -> Waker { + const VTABLE: RawWakerVTable = RawWakerVTable::new(clone, wake, wake, drop); + + unsafe fn clone(data: *const ()) -> RawWaker { + RawWaker::new(data, &VTABLE) + } + + unsafe fn wake(data: *const ()) { + ndk_sys::ALooper_wake(data as *const _ as *mut _) + } + + unsafe fn drop(_: *const ()) {} + + unsafe { Waker::from_raw(RawWaker::new(self.looper.as_ptr() as *const (), &VTABLE)) } + } } impl AndroidApp { diff --git a/android-activity/src/native_activity/mod.rs b/android-activity/src/native_activity/mod.rs index 2adcd52..d6e0b2b 100644 --- a/android-activity/src/native_activity/mod.rs +++ b/android-activity/src/native_activity/mod.rs @@ -6,6 +6,7 @@ use std::panic::AssertUnwindSafe; use std::ptr; use std::ptr::NonNull; use std::sync::{Arc, Mutex, RwLock, Weak}; +use std::task::{RawWaker, RawWakerVTable, Waker}; use std::time::Duration; use libc::c_void; @@ -83,6 +84,27 @@ impl AndroidAppWaker { ndk_sys::ALooper_wake(self.looper.as_ptr()); } } + + /// Creates a [`Waker`] that wakes up the [`AndroidApp`]. + /// + /// This is useful for using this crate in `async` environments. + /// + /// [`Waker`]: std::task::Waker + pub fn waker(self) -> Waker { + const VTABLE: RawWakerVTable = RawWakerVTable::new(clone, wake, wake, drop); + + unsafe fn clone(data: *const ()) -> RawWaker { + RawWaker::new(data, &VTABLE) + } + + unsafe fn wake(data: *const ()) { + ndk_sys::ALooper_wake(data as *const _ as *mut _) + } + + unsafe fn drop(_: *const ()) {} + + unsafe { Waker::from_raw(RawWaker::new(self.looper.as_ptr() as *const (), &VTABLE)) } + } } impl AndroidApp {