Skip to content

Commit

Permalink
winit update and better support for android resume suspend
Browse files Browse the repository at this point in the history
  • Loading branch information
slyedoc committed Dec 15, 2022
1 parent bad3d57 commit febb8fe
Show file tree
Hide file tree
Showing 21 changed files with 278 additions and 84 deletions.
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ serialize = ["bevy_internal/serialize"]
# Display server protocol support (X11 is enabled by default)
wayland = ["bevy_internal/wayland"]
x11 = ["bevy_internal/x11"]
android = ["bevy_internal/android"]

# Enable rendering of font glyphs using subpixel accuracy
subpixel_glyph_atlas = ["bevy_internal/subpixel_glyph_atlas"]
Expand Down Expand Up @@ -130,6 +131,10 @@ bytemuck = "1.7"
futures-lite = "1.11.3"
crossbeam-channel = "0.5.0"

# TODO: Move these
[patch.crates-io]
winit = { git = "https://github.com/rust-windowing/winit", branch = "master" }

[[example]]
name = "hello_world"
path = "examples/hello_world.rs"
Expand Down
4 changes: 1 addition & 3 deletions crates/bevy_asset/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ bevy_log = { path = "../bevy_log", version = "0.9.0" }
bevy_reflect = { path = "../bevy_reflect", version = "0.9.0", features = ["bevy"] }
bevy_tasks = { path = "../bevy_tasks", version = "0.9.0" }
bevy_utils = { path = "../bevy_utils", version = "0.9.0" }
bevy_winit = { path = "../bevy_winit", version = "0.9.0" }

# other
serde = { version = "1", features = ["derive"] }
Expand All @@ -39,9 +40,6 @@ web-sys = { version = "0.3", features = ["Request", "Window", "Response"] }
wasm-bindgen-futures = "0.4"
js-sys = "0.3"

[target.'cfg(target_os = "android")'.dependencies]
ndk-glue = { version = "0.7" }

[dev-dependencies]
futures-lite = "1.4.0"
tempfile = "3.2.0"
Expand Down
12 changes: 9 additions & 3 deletions crates/bevy_asset/src/io/android_asset_io.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{AssetIo, AssetIoError, Metadata};
use anyhow::Result;
use bevy_utils::BoxedFuture;
use bevy_winit::android::AssetManager;
use std::{
convert::TryFrom,
ffi::CString,
Expand All @@ -19,21 +20,26 @@ use std::{
/// [AssetManager]: https://developer.android.com/reference/android/content/res/AssetManager
pub struct AndroidAssetIo {
root_path: PathBuf,
asset_manager: AssetManager,
}

impl AndroidAssetIo {
pub fn new<P: AsRef<Path>>(path: P) -> Self {
/// Creates a new `AndroidAssetIo` from apk
///
/// See `get_base_path` below.
pub fn new<P: AsRef<Path>>(path: P, asset_manager: AssetManager) -> Self {
AndroidAssetIo {
root_path: path.as_ref().to_owned(),
asset_manager,
}
}
}

impl AssetIo for AndroidAssetIo {
fn load_path<'a>(&'a self, path: &'a Path) -> BoxedFuture<'a, Result<Vec<u8>, AssetIoError>> {
Box::pin(async move {
let asset_manager = ndk_glue::native_activity().asset_manager();
let mut opened_asset = asset_manager
let mut opened_asset = self
.asset_manager
.open(&CString::new(path.to_str().unwrap()).unwrap())
.ok_or(AssetIoError::NotFound(path.to_path_buf()))?;
let bytes = opened_asset.get_buffer()?;
Expand Down
14 changes: 11 additions & 3 deletions crates/bevy_asset/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,20 @@ impl AssetPlugin {
///
/// This is useful when providing a custom `AssetIo` instance that needs to
/// delegate to the default `AssetIo` for the platform.
pub fn create_platform_default_asset_io(&self) -> Box<dyn AssetIo> {
#[allow(unused_variables)]
pub fn create_platform_default_asset_io(&self, app: &App) -> Box<dyn AssetIo> {
#[cfg(all(not(target_arch = "wasm32"), not(target_os = "android")))]
let source = FileAssetIo::new(&self.asset_folder, self.watch_for_changes);
#[cfg(target_arch = "wasm32")]
let source = WasmAssetIo::new(&self.asset_folder);
#[cfg(target_os = "android")]
let source = AndroidAssetIo::new(&self.asset_folder);
let source = AndroidAssetIo::new(
&self.asset_folder,
app.world
.resource::<bevy_winit::android::AndroidActivityApp>()
.android_app
.asset_manager(),
);

Box::new(source)
}
Expand All @@ -100,7 +107,8 @@ impl AssetPlugin {
impl Plugin for AssetPlugin {
fn build(&self, app: &mut App) {
if !app.world.contains_resource::<AssetServer>() {
let source = self.create_platform_default_asset_io();
let source = self.create_platform_default_asset_io(app);

let asset_server = AssetServer::with_boxed_io(source);
app.insert_resource(asset_server);
}
Expand Down
6 changes: 0 additions & 6 deletions crates/bevy_derive/src/bevy_main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,6 @@ pub fn bevy_main(_attr: TokenStream, item: TokenStream) -> TokenStream {
);

TokenStream::from(quote! {
// use ndk-glue macro to create an activity: https://github.com/rust-windowing/android-ndk-rs/tree/master/ndk-macro
#[cfg(target_os = "android")]
#[cfg_attr(target_os = "android", bevy::ndk_glue::main(backtrace = "on", ndk_glue = "bevy::ndk_glue"))]
fn android_main() {
main()
}

#[no_mangle]
#[cfg(target_os = "ios")]
Expand Down
6 changes: 1 addition & 5 deletions crates/bevy_internal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ serialize = ["bevy_core/serialize", "bevy_input/serialize", "bevy_time/serialize
# Display server protocol support (X11 is enabled by default)
wayland = ["bevy_winit/wayland"]
x11 = ["bevy_winit/x11"]
android = ["bevy_winit/android"]

# enable rendering of font glyphs using subpixel accuracy
subpixel_glyph_atlas = ["bevy_text/subpixel_glyph_atlas"]
Expand Down Expand Up @@ -97,8 +98,3 @@ bevy_text = { path = "../bevy_text", optional = true, version = "0.9.0" }
bevy_ui = { path = "../bevy_ui", optional = true, version = "0.9.0" }
bevy_winit = { path = "../bevy_winit", optional = true, version = "0.9.0" }
bevy_gilrs = { path = "../bevy_gilrs", optional = true, version = "0.9.0" }

[target.'cfg(target_os = "android")'.dependencies]
# This version *must* be the same as the version used by winit,
# or Android will break: https://github.com/rust-windowing/winit#android
ndk-glue = {version = "0.7", features = ["logger"]}
3 changes: 0 additions & 3 deletions crates/bevy_internal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,3 @@ pub mod dynamic_plugin {
//! Dynamic linking of plugins
pub use bevy_dynamic_plugin::*;
}

#[cfg(target_os = "android")]
pub use ndk_glue;
4 changes: 2 additions & 2 deletions crates/bevy_window/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ pub mod prelude {
#[doc(hidden)]
pub use crate::{
CursorEntered, CursorIcon, CursorLeft, CursorMoved, FileDragAndDrop, MonitorSelection,
ReceivedCharacter, Window, WindowDescriptor, WindowMode, WindowMoved, WindowPlugin,
WindowPosition, Windows,
ReceivedCharacter, Window, WindowDescriptor, WindowLevel, WindowMode, WindowMoved,
WindowPlugin, WindowPosition, Windows,
};
}

Expand Down
54 changes: 41 additions & 13 deletions crates/bevy_window/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,34 @@ pub enum PresentMode {
Fifo = 4, // NOTE: The explicit ordinal values mirror wgpu.
}

/// A window level groups windows with respect to their z-position.
///
/// The relative ordering between windows in different window levels is fixed.
/// The z-order of a window within the same window level may change dynamically on user interaction.
///
/// ## Platform-specific
///
/// - **iOS / Android / Web / Wayland:** Unsupported.
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Reflect, FromReflect)]
#[cfg_attr(
feature = "serialize",
derive(serde::Serialize, serde::Deserialize),
reflect(Serialize, Deserialize)
)]
#[reflect(Debug, PartialEq, Hash)]
pub enum WindowLevel {
/// The default.
Normal = 0,
/// The window will always be below normal windows.
///
/// This is useful for a widget-based app.
AlwaysOnBottom = 1,

/// The window will always be on top of normal windows.
AlwaysOnTop = 2,
}

/// Specifies how the alpha channel of the textures should be handled during compositing.
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Reflect, FromReflect)]
Expand Down Expand Up @@ -317,7 +345,7 @@ pub struct Window {
fit_canvas_to_parent: bool,
command_queue: Vec<WindowCommand>,
alpha_mode: CompositeAlphaMode,
always_on_top: bool,
window_level: WindowLevel,
}
/// A command to be sent to a window.
///
Expand Down Expand Up @@ -397,9 +425,9 @@ pub enum WindowCommand {
SetResizeConstraints {
resize_constraints: WindowResizeConstraints,
},
/// Set whether the window is always on top.
SetAlwaysOnTop {
always_on_top: bool,
/// Set whether the window level
SetWindowLevel {
window_level: WindowLevel,
},
Close,
}
Expand Down Expand Up @@ -481,7 +509,7 @@ impl Window {
fit_canvas_to_parent: window_descriptor.fit_canvas_to_parent,
command_queue: Vec::new(),
alpha_mode: window_descriptor.alpha_mode,
always_on_top: window_descriptor.always_on_top,
window_level: window_descriptor.window_level,
}
}
/// Get the window's [`WindowId`].
Expand Down Expand Up @@ -861,15 +889,15 @@ impl Window {
}
/// Get whether or not the window is always on top.
#[inline]
pub fn always_on_top(&self) -> bool {
self.always_on_top
pub fn window_level(&self) -> WindowLevel {
self.window_level
}

/// Set whether of not the window is always on top.
pub fn set_always_on_top(&mut self, always_on_top: bool) {
self.always_on_top = always_on_top;
pub fn set_window_level(&mut self, window_level: WindowLevel) {
self.window_level = window_level;
self.command_queue
.push(WindowCommand::SetAlwaysOnTop { always_on_top });
.push(WindowCommand::SetWindowLevel { window_level });
}
/// Close the operating system window corresponding to this [`Window`].
///
Expand Down Expand Up @@ -1064,12 +1092,12 @@ pub struct WindowDescriptor {
pub fit_canvas_to_parent: bool,
/// Specifies how the alpha channel of the textures should be handled during compositing.
pub alpha_mode: CompositeAlphaMode,
/// Sets the window to always be on top of other windows.
/// Sets the window level
///
/// ## Platform-specific
/// - iOS / Android / Web: Unsupported.
/// - Linux (Wayland): Unsupported.
pub always_on_top: bool,
pub window_level: WindowLevel,
}

impl Default for WindowDescriptor {
Expand All @@ -1093,7 +1121,7 @@ impl Default for WindowDescriptor {
canvas: None,
fit_canvas_to_parent: false,
alpha_mode: CompositeAlphaMode::Auto,
always_on_top: false,
window_level: WindowLevel::Normal,
}
}
}
4 changes: 4 additions & 0 deletions crates/bevy_winit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ keywords = ["bevy"]
trace = []
wayland = ["winit/wayland"]
x11 = ["winit/x11"]
android = ["winit/android-native-activity"]

[dependencies]
# bevy
Expand All @@ -27,6 +28,9 @@ winit = { version = "0.27", default-features = false }
approx = { version = "0.5", default-features = false }
raw-window-handle = "0.5"

[target.'cfg(target_os = "android")'.dependencies]
ndk = "0.7" # Need till https://github.com/rib/android-activity/issues/45

[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = { version = "0.2" }
web-sys = "0.3"
Expand Down
11 changes: 11 additions & 0 deletions crates/bevy_winit/src/android.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use bevy_ecs::system::Resource;

pub use ndk::asset::AssetManager;
pub use winit::platform::android::activity::*;

/// Resource containing AndroidApp
pub struct AndroidActivityApp {
pub android_app: AndroidApp,
}

impl Resource for AndroidActivityApp {}
11 changes: 10 additions & 1 deletion crates/bevy_winit/src/converters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use bevy_input::{
ButtonState,
};
use bevy_math::Vec2;
use bevy_window::{CursorGrabMode, CursorIcon};
use bevy_window::{CursorGrabMode, CursorIcon, WindowLevel};

pub fn convert_keyboard_input(keyboard_input: &winit::event::KeyboardInput) -> KeyboardInput {
KeyboardInput {
Expand Down Expand Up @@ -275,3 +275,12 @@ pub fn convert_cursor_grab_mode(mode: CursorGrabMode) -> winit::window::CursorGr
CursorGrabMode::Locked => winit::window::CursorGrabMode::Locked,
}
}

/// Map [`bevy_window::WindowLevel`] to [`winit::window::WindowLevel`].
pub fn convert_window_level(level: WindowLevel) -> winit::window::WindowLevel {
match level {
WindowLevel::Normal => winit::window::WindowLevel::Normal,
WindowLevel::AlwaysOnTop => winit::window::WindowLevel::AlwaysOnTop,
WindowLevel::AlwaysOnBottom => winit::window::WindowLevel::AlwaysOnBottom,
}
}
Loading

0 comments on commit febb8fe

Please sign in to comment.