From dc0aaf818d18647172bbc467f8ca222b20dd31d9 Mon Sep 17 00:00:00 2001 From: Robert Mikhayelyan Date: Thu, 23 Jul 2020 03:31:40 -0700 Subject: [PATCH 01/20] basic cfg for uwp --- src/main.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main.rs b/src/main.rs index 42c6081..6bfd5d2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,10 +17,23 @@ use winit::{ use bindings::windows::{foundation::numerics::Vector2, ui::composition::Compositor}; +// TODO: Validate that this works +#[cfg(target_vendor = "uwp")] +fn test() { + println!("UWP!"); +} + +#[cfg(target_vendor = "pc")] +fn test() { + println!("Win32!") +} + fn run() -> winrt::Result<()> { ro_initialize(RoInitType::MultiThreaded)?; let _controller = create_dispatcher_queue_controller_for_current_thread()?; + test(); + let event_loop = EventLoop::new(); let window = WindowBuilder::new().build(&event_loop).unwrap(); window.set_title("Minesweeper"); From 08e51ffb1e604812b4cd6a7ec3b0a76dd71a42eb Mon Sep 17 00:00:00 2001 From: Robert Mikhayelyan Date: Thu, 23 Jul 2020 03:55:01 -0700 Subject: [PATCH 02/20] split desktop and uwp --- Cargo.lock | 83 ++++++++++++++-------------- Cargo.toml | 8 ++- bindings/Cargo.toml | 4 +- src/{ => desktop}/interop.rs | 16 ------ src/desktop/mod.rs | 5 ++ src/desktop/run.rs | 74 +++++++++++++++++++++++++ src/{ => desktop}/window_target.rs | 2 +- src/main.rs | 88 +++--------------------------- src/uwp/interop.rs | 15 +++++ src/uwp/mod.rs | 4 ++ src/uwp/run.rs | 3 + 11 files changed, 160 insertions(+), 142 deletions(-) rename src/{ => desktop}/interop.rs (90%) create mode 100644 src/desktop/mod.rs create mode 100644 src/desktop/run.rs rename src/{ => desktop}/window_target.rs (95%) create mode 100644 src/uwp/interop.rs create mode 100644 src/uwp/mod.rs create mode 100644 src/uwp/run.rs diff --git a/Cargo.lock b/Cargo.lock index 7b4f1bf..3a71490 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,9 +73,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.54" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bbb73db36c1246e9034e307d0fba23f9a2e251faa47ade70c1bd252220c8311" +checksum = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518" [[package]] name = "cfg-if" @@ -94,9 +94,9 @@ dependencies = [ [[package]] name = "cocoa" -version = "0.20.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f7b6f3f7f4f0b3ec5c5039aaa9e8c3cef97a7a480a400fd62944841314f293d" +checksum = "0c49e86fc36d5704151f5996b7b3795385f50ce09e3be0f47a0cfde869681cf8" dependencies = [ "bitflags", "block", @@ -125,9 +125,9 @@ checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" [[package]] name = "core-graphics" -version = "0.19.0" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59e78b2e0aaf43f08e7ae0d6bc96895ef72ff0921c7d4ff4762201b2dba376dd" +checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923" dependencies = [ "bitflags", "core-foundation", @@ -176,9 +176,9 @@ dependencies = [ [[package]] name = "downcast-rs" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ba6eb47c2131e784a38b726eb54c1e1484904f013e576a25354d0124161af6" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] name = "foreign-types" @@ -224,9 +224,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7777a24a1ce5de49fcdde84ec46efa487c3af49d5b6e6e0a50367cc5c1096182" +checksum = "5b141fdc7836c525d4d594027d318c84161ca17aaf8113ab1f81ab93ae897485" [[package]] name = "iovec" @@ -283,7 +283,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2cadb8e769f070c45df05c78c7520eb4cd17061d4ab262e43cfc68b4d00ac71c" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -306,9 +306,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.8" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" dependencies = [ "cfg-if", ] @@ -335,7 +335,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" dependencies = [ "libc", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -431,7 +431,7 @@ checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" dependencies = [ "cfg-if", "libc", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -449,9 +449,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" +checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" dependencies = [ "autocfg", ] @@ -489,9 +489,9 @@ dependencies = [ [[package]] name = "ordered-float" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518" +checksum = "3741934be594d77de1c8461ebcbbe866f585ea616a9753aa78f2bdc69f0e4579" dependencies = [ "num-traits", ] @@ -517,7 +517,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -528,9 +528,9 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pkg-config" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" +checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33" [[package]] name = "ppv-lite86" @@ -540,9 +540,9 @@ checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" [[package]] name = "proc-macro-crate" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" dependencies = [ "toml", ] @@ -635,9 +635,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.1.56" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "rusttype" @@ -711,9 +711,9 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" [[package]] name = "smallvec" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4" +checksum = "3757cb9d89161a2f24e1cf78efa0c1fcff485d18e3f55e0aa3480824ddaa0f3f" [[package]] name = "smithay-client-toolkit" @@ -785,7 +785,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" dependencies = [ "same-file", - "winapi 0.3.8", + "winapi 0.3.9", "winapi-util", ] @@ -863,9 +863,9 @@ checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" [[package]] name = "winapi" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", @@ -889,7 +889,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -925,15 +925,15 @@ dependencies = [ "raw-window-handle", "smithay-client-toolkit", "wayland-client", - "winapi 0.3.8", + "winapi 0.3.9", "x11-dl", ] [[package]] name = "winrt" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e7a6707aad48277a3f68e7de09191c03e06184a01b50ebffd000002ee0fbb27" +checksum = "3ad0eddcf97212ae610f63026855cbaa60589aecba13139db0d89ef65356fea1" dependencies = [ "sha1", "winrt_macros", @@ -941,22 +941,23 @@ dependencies = [ [[package]] name = "winrt_gen" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a3dda4a993af82fb6f639b18568340c1a95160a6dd9dc0f9ff2263a2577a89" +checksum = "cb3aa95db4dbd92feb5c8669220caefcbd4d184c4818abde8e523b8105473922" dependencies = [ "proc-macro2 1.0.18", "quote 1.0.7", "serde_json", "sha1", + "syn", "winrt_gen_macros", ] [[package]] name = "winrt_gen_macros" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bee2d8e97c35a0a26fde56151a0e10fe0601f747c7364248dc5fd67b0d917f" +checksum = "5e7b81e2615075dc2241404dad02020ea23dc412cf83562eb4123b7e3f40df4b" dependencies = [ "proc-macro2 1.0.18", "quote 1.0.7", @@ -965,9 +966,9 @@ dependencies = [ [[package]] name = "winrt_macros" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc78a0c7bce1d0bb669ceb8faf102c200cd7db14ff7b684a50f588ea6be257a8" +checksum = "e54ec67bf72b938b42b980369ebc207210bb24599c541cd149853656ca7e9594" dependencies = [ "proc-macro2 1.0.18", "quote 1.0.7", diff --git a/Cargo.toml b/Cargo.toml index 968e0bd..d50d6fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,11 +5,13 @@ authors = ["Robert Mikhayelyan "] edition = "2018" [dependencies] -winit = "0.22.0" -raw-window-handle = "0.3.3" -winrt = "0.7.0" +winrt = "0.7.1" rand = "0.7.3" bindings = { path = "bindings" } +[target.'cfg(target_vendor = "pc")'.dependencies] +winit = "0.22.2" +raw-window-handle = "0.3.3" + [features] show-mines = [] diff --git a/bindings/Cargo.toml b/bindings/Cargo.toml index 0d7256c..4245f9c 100644 --- a/bindings/Cargo.toml +++ b/bindings/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2018" [dependencies] -winrt = "0.7.0" +winrt = "0.7.1" [build-dependencies] -winrt = "0.7.0" +winrt = "0.7.1" diff --git a/src/interop.rs b/src/desktop/interop.rs similarity index 90% rename from src/interop.rs rename to src/desktop/interop.rs index c824b86..45cce15 100644 --- a/src/interop.rs +++ b/src/desktop/interop.rs @@ -57,22 +57,6 @@ impl CompositorDesktopInterop { } } -#[link(name = "windowsapp")] -extern "stdcall" { - fn RoInitialize(init_type: RoInitType) -> winrt::ErrorCode; -} - -#[allow(dead_code)] -#[repr(i32)] -pub enum RoInitType { - MultiThreaded = 0, - SingleThreaded = 1, -} - -pub fn ro_initialize(init_type: RoInitType) -> winrt::Result<()> { - unsafe { RoInitialize(init_type).ok() } -} - #[link(name = "coremessaging")] extern "stdcall" { fn CreateDispatcherQueueController( diff --git a/src/desktop/mod.rs b/src/desktop/mod.rs new file mode 100644 index 0000000..ebafa84 --- /dev/null +++ b/src/desktop/mod.rs @@ -0,0 +1,5 @@ +pub mod interop; +mod run; +pub mod window_target; + +pub use run::run; \ No newline at end of file diff --git a/src/desktop/run.rs b/src/desktop/run.rs new file mode 100644 index 0000000..d7668af --- /dev/null +++ b/src/desktop/run.rs @@ -0,0 +1,74 @@ +use crate::desktop::interop::create_dispatcher_queue_controller_for_current_thread; +use crate::uwp::interop::{ro_initialize, RoInitType}; +use crate::minesweeper::Minesweeper; +use crate::desktop::window_target::CompositionDesktopWindowTargetSource; +use winit::{ + event::{ElementState, Event, MouseButton, WindowEvent}, + event_loop::{ControlFlow, EventLoop}, + window::WindowBuilder, +}; + +use bindings::windows::{foundation::numerics::Vector2, ui::composition::Compositor}; + +pub fn run() -> winrt::Result<()> { + ro_initialize(RoInitType::MultiThreaded)?; + let _controller = create_dispatcher_queue_controller_for_current_thread()?; + + let event_loop = EventLoop::new(); + let window = WindowBuilder::new().build(&event_loop).unwrap(); + window.set_title("Minesweeper"); + + let compositor = Compositor::new()?; + let target = window.create_window_target(&compositor, false)?; + + let root = compositor.create_container_visual()?; + root.set_relative_size_adjustment(Vector2 { x: 1.0, y: 1.0 })?; + target.set_root(&root)?; + + let window_size = window.inner_size(); + let window_size = Vector2 { + x: window_size.width as f32, + y: window_size.height as f32, + }; + let mut game = Minesweeper::new(&root, &window_size)?; + + event_loop.run(move |event, _, control_flow| { + *control_flow = ControlFlow::Wait; + match event { + Event::WindowEvent { + event: WindowEvent::CloseRequested, + window_id, + } if window_id == window.id() => *control_flow = ControlFlow::Exit, + Event::WindowEvent { + event: WindowEvent::Resized(size), + .. + } => { + let size = Vector2 { + x: size.width as f32, + y: size.height as f32, + }; + game.on_parent_size_changed(&size).unwrap(); + } + Event::WindowEvent { + event: WindowEvent::CursorMoved { position, .. }, + .. + } => { + let point = Vector2 { + x: position.x as f32, + y: position.y as f32, + }; + game.on_pointer_moved(&point).unwrap(); + } + Event::WindowEvent { + event: WindowEvent::MouseInput { state, button, .. }, + .. + } => { + if state == ElementState::Pressed { + game.on_pointer_pressed(button == MouseButton::Right, false) + .unwrap(); + } + } + _ => (), + } + }); +} \ No newline at end of file diff --git a/src/window_target.rs b/src/desktop/window_target.rs similarity index 95% rename from src/window_target.rs rename to src/desktop/window_target.rs index accbfbe..1bfff03 100644 --- a/src/window_target.rs +++ b/src/desktop/window_target.rs @@ -1,4 +1,4 @@ -use crate::interop::CompositorDesktopInterop; +use crate::desktop::interop::CompositorDesktopInterop; use bindings::windows::ui::composition::{desktop::DesktopWindowTarget, Compositor}; use raw_window_handle::HasRawWindowHandle; use winrt::TryInto; diff --git a/src/main.rs b/src/main.rs index 6bfd5d2..e1cd06e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,96 +1,26 @@ mod comp_assets; mod comp_ui; -mod interop; mod minesweeper; mod numerics; mod visual_grid; -mod window_target; - -use interop::{create_dispatcher_queue_controller_for_current_thread, ro_initialize, RoInitType}; -use minesweeper::Minesweeper; -use window_target::CompositionDesktopWindowTargetSource; -use winit::{ - event::{ElementState, Event, MouseButton, WindowEvent}, - event_loop::{ControlFlow, EventLoop}, - window::WindowBuilder, -}; +mod uwp; +#[cfg(target_vendor = "pc")] +mod desktop; -use bindings::windows::{foundation::numerics::Vector2, ui::composition::Compositor}; +#[cfg(target_vendor = "pc")] +use desktop::run; +#[cfg(target_vendor = "uwp")] +use uwp::run; // TODO: Validate that this works #[cfg(target_vendor = "uwp")] fn test() { - println!("UWP!"); + println!("UWP"); } #[cfg(target_vendor = "pc")] fn test() { - println!("Win32!") -} - -fn run() -> winrt::Result<()> { - ro_initialize(RoInitType::MultiThreaded)?; - let _controller = create_dispatcher_queue_controller_for_current_thread()?; - - test(); - - let event_loop = EventLoop::new(); - let window = WindowBuilder::new().build(&event_loop).unwrap(); - window.set_title("Minesweeper"); - - let compositor = Compositor::new()?; - let target = window.create_window_target(&compositor, false)?; - - let root = compositor.create_container_visual()?; - root.set_relative_size_adjustment(Vector2 { x: 1.0, y: 1.0 })?; - target.set_root(&root)?; - - let window_size = window.inner_size(); - let window_size = Vector2 { - x: window_size.width as f32, - y: window_size.height as f32, - }; - let mut game = Minesweeper::new(&root, &window_size)?; - - event_loop.run(move |event, _, control_flow| { - *control_flow = ControlFlow::Wait; - match event { - Event::WindowEvent { - event: WindowEvent::CloseRequested, - window_id, - } if window_id == window.id() => *control_flow = ControlFlow::Exit, - Event::WindowEvent { - event: WindowEvent::Resized(size), - .. - } => { - let size = Vector2 { - x: size.width as f32, - y: size.height as f32, - }; - game.on_parent_size_changed(&size).unwrap(); - } - Event::WindowEvent { - event: WindowEvent::CursorMoved { position, .. }, - .. - } => { - let point = Vector2 { - x: position.x as f32, - y: position.y as f32, - }; - game.on_pointer_moved(&point).unwrap(); - } - Event::WindowEvent { - event: WindowEvent::MouseInput { state, button, .. }, - .. - } => { - if state == ElementState::Pressed { - game.on_pointer_pressed(button == MouseButton::Right, false) - .unwrap(); - } - } - _ => (), - } - }); + println!("Win32") } fn main() { diff --git a/src/uwp/interop.rs b/src/uwp/interop.rs new file mode 100644 index 0000000..1f07149 --- /dev/null +++ b/src/uwp/interop.rs @@ -0,0 +1,15 @@ +#[link(name = "windowsapp")] +extern "stdcall" { + fn RoInitialize(init_type: RoInitType) -> winrt::ErrorCode; +} + +#[allow(dead_code)] +#[repr(i32)] +pub enum RoInitType { + MultiThreaded = 0, + SingleThreaded = 1, +} + +pub fn ro_initialize(init_type: RoInitType) -> winrt::Result<()> { + unsafe { RoInitialize(init_type).ok() } +} \ No newline at end of file diff --git a/src/uwp/mod.rs b/src/uwp/mod.rs new file mode 100644 index 0000000..1de5345 --- /dev/null +++ b/src/uwp/mod.rs @@ -0,0 +1,4 @@ +pub mod interop; +mod run; + +pub use run::run; \ No newline at end of file diff --git a/src/uwp/run.rs b/src/uwp/run.rs new file mode 100644 index 0000000..c829485 --- /dev/null +++ b/src/uwp/run.rs @@ -0,0 +1,3 @@ +pub fn run() -> winrt::Result<()> { + Ok(()) +} \ No newline at end of file From 03264554e817736cdd97d236ca38a98ea28c19d3 Mon Sep 17 00:00:00 2001 From: Robert Mikhayelyan Date: Sun, 26 Jul 2020 05:18:59 -0700 Subject: [PATCH 03/20] attempt --- Cargo.lock | 5 + Cargo.toml | 1 + bindings/build.rs | 8 + src/desktop/interop.rs | 4 +- src/main.rs | 15 ++ src/uwp/app.rs | 588 +++++++++++++++++++++++++++++++++++++++++ src/uwp/mod.rs | 1 + src/uwp/run.rs | 17 ++ winrt_guid/Cargo.toml | 8 + winrt_guid/src/guid.rs | 85 ++++++ winrt_guid/src/lib.rs | 35 +++ 11 files changed, 766 insertions(+), 1 deletion(-) create mode 100644 src/uwp/app.rs create mode 100644 winrt_guid/Cargo.toml create mode 100644 winrt_guid/src/guid.rs create mode 100644 winrt_guid/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 3a71490..94b8168 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -347,6 +347,7 @@ dependencies = [ "raw-window-handle", "winit", "winrt", + "winrt_guid", ] [[package]] @@ -964,6 +965,10 @@ dependencies = [ "syn", ] +[[package]] +name = "winrt_guid" +version = "0.1.0" + [[package]] name = "winrt_macros" version = "0.7.1" diff --git a/Cargo.toml b/Cargo.toml index d50d6fc..f37c803 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ edition = "2018" winrt = "0.7.1" rand = "0.7.3" bindings = { path = "bindings" } +winrt_guid = { path = "winrt_guid" } [target.'cfg(target_vendor = "pc")'.dependencies] winit = "0.22.2" diff --git a/bindings/build.rs b/bindings/build.rs index 7ce510a..221198c 100644 --- a/bindings/build.rs +++ b/bindings/build.rs @@ -2,6 +2,9 @@ winrt::build!( dependencies os types + windows::application_model::core::{ + CoreApplication, CoreApplicationView, IFrameworkViewSource, IFrameworkView, + } windows::foundation::numerics::{Vector2, Vector3} windows::foundation::TimeSpan windows::graphics::SizeInt32 @@ -14,12 +17,17 @@ winrt::build!( CompositionGeometry, CompositionShape, CompositionSpriteShape, + CompositionTarget, Compositor, ContainerVisual, SpriteVisual, } windows::ui::composition::desktop::DesktopWindowTarget windows::ui::Colors + windows::ui::core::{ + CoreDispatcher, CoreWindow, CoreProcessEventsOption, WindowSizeChangedEventArgs, + PointerEventArgs + } ); fn main() { diff --git a/src/desktop/interop.rs b/src/desktop/interop.rs index 45cce15..b8c5b0b 100644 --- a/src/desktop/interop.rs +++ b/src/desktop/interop.rs @@ -2,6 +2,7 @@ use bindings::windows::{ system::DispatcherQueueController, ui::composition::desktop::DesktopWindowTarget, }; use winrt::AbiTransferable; +use winrt_guid::winrt_guid; #[repr(C)] pub struct abi_ICompositorDesktopInterop { @@ -18,7 +19,8 @@ unsafe impl winrt::ComInterface for CompositorDesktopInterop { type VTable = abi_ICompositorDesktopInterop; fn iid() -> winrt::Guid { - winrt::Guid::from_values(702976506, 17767, 19914, [179, 25, 208, 242, 7, 235, 104, 7]) + winrt_guid!(29E691FA-4567-4DCA-B319-D0F207EB6807) + //winrt::Guid::from_values(702976506, 17767, 19914, [179, 25, 208, 242, 7, 235, 104, 7]) } } diff --git a/src/main.rs b/src/main.rs index e1cd06e..866916d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,3 +31,18 @@ fn main() { error.code().unwrap(); } } + +/* +#[no_mangle] +extern "system" fn wWinMain( + _h_instance: *const i32, + _h_prev_instance: *const i32, + _cmd_line: *const u16, + _n_cmd_show: i32, +) -> i32 { + match run() { + Ok(()) => 0, + Err(e) => e.code().0 as i32, + } +} +*/ \ No newline at end of file diff --git a/src/uwp/app.rs b/src/uwp/app.rs new file mode 100644 index 0000000..d691f22 --- /dev/null +++ b/src/uwp/app.rs @@ -0,0 +1,588 @@ +use bindings::{ + windows::{ + application_model::core::{ + CoreApplication, CoreApplicationView, IFrameworkViewSource, IFrameworkView, + abi_IFrameworkViewSource, abi_IFrameworkView, + }, + foundation::numerics::Vector2, + ui::Colors, + ui::core::{ + CoreDispatcher, CoreWindow, CoreProcessEventsOption, WindowSizeChangedEventArgs, + PointerEventArgs + }, + ui::composition::{ + Compositor, CompositionTarget + } + } +}; +use std::rc::Rc; +use winrt::AbiTransferable; +use winrt_guid::winrt_guid; + +#[repr(C)] +pub struct abi_IUnknown { + pub unknown_query_interface: + unsafe extern "system" fn(winrt::NonNullRawComPtr, &winrt::Guid, *mut winrt::RawPtr) -> winrt::ErrorCode, + pub unknown_add_ref: extern "system" fn(winrt::NonNullRawComPtr) -> u32, + pub unknown_release: extern "system" fn(winrt::NonNullRawComPtr) -> u32, +} + +#[repr(C)] +pub struct abi_IInspectable { + iunknown: abi_IUnknown, + + pub inspectable_iids: + unsafe extern "system" fn(winrt::NonNullRawComPtr, *mut u32, *mut *mut winrt::Guid) -> winrt::ErrorCode, + pub inspectable_type_name: unsafe extern "system" fn( + winrt::NonNullRawComPtr, + *mut ::Abi, + ) -> winrt::ErrorCode, + pub inspectable_trust_level: + unsafe extern "system" fn(winrt::NonNullRawComPtr, *mut i32) -> winrt::ErrorCode, +} + +#[derive(Default, Clone, PartialEq)] +#[repr(transparent)] +pub struct App { + ptr: winrt::ComPtr, +} + +impl App { + pub fn new() -> winrt::Result { + unsafe { + let raw = AppRc::new(); + + let mut result: App = std::mem::zeroed(); + let mut ptr: std::ptr::NonNull = std::ptr::NonNull::new_unchecked(raw.as_ref().unwrap().get_app_abi() as _); + *::set_abi(&mut result) = + Some(winrt::NonNullRawComPtr::new(ptr.cast())); + + Ok(result) + } + } +} + +unsafe impl winrt::ComInterface for App { + type VTable = abi_IApp; + fn iid() -> winrt::Guid { + winrt_guid!(DF36D812-3CF5-4B3D-BFA6-AC1A74F3C5C0) + } +} + +unsafe impl winrt::AbiTransferable for App { + type Abi = winrt::RawComPtr; + fn get_abi(&self) -> Self::Abi { + as winrt::AbiTransferable>::get_abi(&self.ptr) + } + fn set_abi(&mut self) -> *mut Self::Abi { + as winrt::AbiTransferable>::set_abi(&mut self.ptr) + } +} + +#[repr(C)] +pub struct abi_IApp { + iinspectable: abi_IInspectable, +} + +#[repr(C)] +pub struct abi_IFrameworkView_Full { + iinspectable: abi_IInspectable, + pub initialize: unsafe extern "system" fn( + ::winrt::NonNullRawComPtr, + application_view: ::Abi, + ) -> ::winrt::ErrorCode, + pub set_window: unsafe extern "system" fn( + ::winrt::NonNullRawComPtr, + window: ::Abi, + ) -> ::winrt::ErrorCode, + pub load: unsafe extern "system" fn( + ::winrt::NonNullRawComPtr, + entry_point: ::Abi, + ) -> ::winrt::ErrorCode, + pub run: unsafe extern "system" fn( + ::winrt::NonNullRawComPtr, + ) -> ::winrt::ErrorCode, + pub uninitialize: unsafe extern "system" fn( + ::winrt::NonNullRawComPtr, + ) -> ::winrt::ErrorCode, +} + +#[repr(C)] +pub struct abi_IFrameworkViewSource_Full { + iinspectable: abi_IInspectable, + pub create_view: unsafe extern "system" fn( + ::winrt::NonNullRawComPtr, + result__: *mut ::Abi, + ) -> ::winrt::ErrorCode, +} + +struct AppState { + compositor: Compositor, + target: CompositionTarget, +} + +struct AppInner { + state: Option +} + +impl AppInner { + pub fn new() -> Self { + Self { + state: None, + } + } + + pub fn initialize(&self, window: &CoreApplicationView) -> winrt::Result<()> { + Ok(()) + } + + pub fn set_window(&self, window: &CoreWindow) -> winrt::Result<()> { + Ok(()) + } + + pub fn load(&self, entry_point: &winrt::HString) -> winrt::Result<()> { + Ok(()) + } + + pub fn run(&self) -> winrt::Result<()> { + let compositor = Compositor::new()?; + let root = compositor.create_container_visual()?; + root.set_relative_size_adjustment(Vector2 { x:1.0, y:1.0 })?; + let target = compositor.create_target_for_current_view()?; + target.set_root(&root)?; + + // TODO: Remove + let test = compositor.create_sprite_visual()?; + test.set_size(Vector2 { x: 200.0, y: 200.0 })?; + test.set_brush(compositor.create_color_brush_with_color(Colors::red()?)?)?; + root.children()?.insert_at_top(&test)?; + + // TODO: Init minesweeper + + // TODO: Hook events + + let window = CoreWindow::get_for_current_thread()?; + let dispatcher = window.dispatcher()?; + dispatcher.process_events(CoreProcessEventsOption::ProcessUntilQuit)?; + + Ok(()) + } + + pub fn uninitialize(&self) -> winrt::Result<()> { + Ok(()) + } +} + +struct AppRc { + count: winrt::RefCount, + this: *mut AppRc, + app_abi: *mut impl_App, + view_abi: *mut impl_App_IFrameworkView, + view_source_abi: *mut impl_App_IFrameworkViewSource, + inner: AppInner, +} + +impl AppRc { + pub fn new() -> *mut Self { + let count = winrt::RefCount::new(); + let inner = AppInner::new(); + unsafe { + let base = Self { + count, + this: std::ptr::null_mut::(), + app_abi: std::ptr::null_mut::(), + view_abi: std::ptr::null_mut::(), + view_source_abi: std::ptr::null_mut::(), + inner + }; + let base = Box::into_raw(Box::new(base)); + + let app_abi = impl_App::from_base(base); + let view_abi = impl_App_IFrameworkView::from_base(base); + let view_source_abi = impl_App_IFrameworkViewSource::from_base(base); + + (*base).this = base; + (*base).app_abi = app_abi; + (*base).view_abi = view_abi; + (*base).view_source_abi = view_source_abi; + + base + } + } + + pub fn add_ref(&self) -> u32 { + self.count.add_ref() + } + + pub unsafe fn release(&self) -> u32 { + let remaining = self.count.release(); + if remaining == 0 { + Box::from_raw(self.this); + } + remaining + } + + pub unsafe fn get_inner(&self) -> &AppInner { + &self.inner + } + + pub fn get_app_abi(&self) -> *mut impl_App { + self.app_abi + } + + pub fn get_view_abi(&self) -> *mut impl_App_IFrameworkView { + self.view_abi + } + + pub fn get_view_source_abi(&self) -> *mut impl_App_IFrameworkViewSource { + self.view_source_abi + } +} + +impl Drop for AppRc { + fn drop(&mut self) { + unsafe { + Box::from_raw(self.app_abi); + Box::from_raw(self.view_abi); + Box::from_raw(self.view_source_abi); + } + } +} + +#[repr(C)] +struct impl_App_IFrameworkView { + vtable: *const abi_IFrameworkView_Full, + base: *mut AppRc, +} + +#[repr(C)] +struct impl_App_IFrameworkViewSource { + vtable: *const abi_IFrameworkViewSource_Full, + base: *mut AppRc, +} + +#[repr(C)] +struct impl_App { + vtable: *const abi_IApp, + base: *mut AppRc, +} + +impl impl_App { + const VTABLE: abi_IApp = abi_IApp { + iinspectable: abi_IInspectable { + iunknown: abi_IUnknown { + unknown_query_interface: impl_App::unknown_query_interface, + unknown_add_ref: impl_App::unknown_add_ref, + unknown_release: impl_App::unknown_release, + }, + inspectable_iids: impl_App::inspectable_iids, + inspectable_type_name: impl_App::inspectable_type_name, + inspectable_trust_level: impl_App::inspectable_trust_level, + }, + }; + + unsafe fn from_base(base: *mut AppRc) -> *mut Self { + Box::into_raw(Box::new(Self { + vtable: &Self::VTABLE, + base + })) + } + + extern "system" fn unknown_query_interface( + this: winrt::NonNullRawComPtr, + iid: &winrt::Guid, + interface: *mut winrt::RawPtr, + ) -> winrt::ErrorCode { + unsafe { + let this: *mut Self = this.as_raw() as _; + if iid == &::iid() + || iid == &::iid() + || iid == &::iid() + || iid == &::iid() + { + *interface = this as winrt::RawPtr; + (*this).base.as_ref().unwrap().add_ref(); + return winrt::ErrorCode(0); + } else if iid == &::iid() { + (*this).base.as_ref().unwrap().add_ref(); + let base = (*this).base; + *interface = (*base).get_view_abi() as winrt::RawPtr; + return winrt::ErrorCode(0); + } else if iid == &::iid() { + (*this).base.as_ref().unwrap().add_ref(); + let base = (*this).base; + *interface = (*base).get_view_source_abi() as winrt::RawPtr; + return winrt::ErrorCode(0); + } + *interface = std::ptr::null_mut(); + winrt::ErrorCode(0x80004002) + } + } + extern "system" fn unknown_add_ref(this: winrt::NonNullRawComPtr) -> u32 { + unsafe { + let this: *mut Self = this.as_raw() as _; + (*this).base.as_ref().unwrap().add_ref() + } + } + extern "system" fn unknown_release(this: winrt::NonNullRawComPtr) -> u32 { + unsafe { + let this: *mut Self = this.as_raw() as _; + (*this).base.as_ref().unwrap().release() + } + } + extern "system" fn inspectable_iids( + _this: winrt::NonNullRawComPtr, + _iidcount: *mut u32, + _iids: *mut *mut winrt::Guid, + ) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) + } + extern "system" fn inspectable_type_name( + _this: winrt::NonNullRawComPtr, + _class_name: *mut ::Abi, + ) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) + } + extern "system" fn inspectable_trust_level( + _this: winrt::NonNullRawComPtr, + _trust_level: *mut i32, + ) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) + } +} + +impl impl_App_IFrameworkView { + const VTABLE: abi_IFrameworkView_Full = abi_IFrameworkView_Full { + iinspectable: abi_IInspectable { + iunknown: abi_IUnknown { + unknown_query_interface: impl_App_IFrameworkView::unknown_query_interface, + unknown_add_ref: impl_App_IFrameworkView::unknown_add_ref, + unknown_release: impl_App_IFrameworkView::unknown_release, + }, + inspectable_iids: impl_App_IFrameworkView::inspectable_iids, + inspectable_type_name: impl_App_IFrameworkView::inspectable_type_name, + inspectable_trust_level: impl_App_IFrameworkView::inspectable_trust_level, + }, + initialize: impl_App_IFrameworkView::initialize, + set_window: impl_App_IFrameworkView::set_window, + load: impl_App_IFrameworkView::load, + run: impl_App_IFrameworkView::run, + uninitialize: impl_App_IFrameworkView::uninitialize, + }; + + unsafe fn from_base(base: *mut AppRc) -> *mut Self { + Box::into_raw(Box::new(Self { + vtable: &Self::VTABLE, + base + })) + } + + extern "system" fn unknown_query_interface( + this: winrt::NonNullRawComPtr, + iid: &winrt::Guid, + interface: *mut winrt::RawPtr, + ) -> winrt::ErrorCode { + unsafe { + let this: *mut Self = this.as_raw() as _; + if iid == &::iid() + || iid == &::iid() + || iid == &::iid() + || iid == &::iid() + { + *interface = this as winrt::RawPtr; + (*this).base.as_ref().unwrap().add_ref(); + return winrt::ErrorCode(0); + } else if iid == &::iid() { + (*this).base.as_ref().unwrap().add_ref(); + let base = (*this).base; + *interface = (*base).get_app_abi() as winrt::RawPtr; + return winrt::ErrorCode(0); + } else if iid == &::iid() { + (*this).base.as_ref().unwrap().add_ref(); + let base = (*this).base; + *interface = (*base).get_view_source_abi() as winrt::RawPtr; + return winrt::ErrorCode(0); + } + *interface = std::ptr::null_mut(); + winrt::ErrorCode(0x80004002) + } + } + extern "system" fn unknown_add_ref(this: winrt::NonNullRawComPtr) -> u32 { + unsafe { + let this: *mut Self = this.as_raw() as _; + (*this).base.as_ref().unwrap().add_ref() + } + } + extern "system" fn unknown_release(this: winrt::NonNullRawComPtr) -> u32 { + unsafe { + let this: *mut Self = this.as_raw() as _; + (*this).base.as_ref().unwrap().release() + } + } + extern "system" fn inspectable_iids( + _this: winrt::NonNullRawComPtr, + _iidcount: *mut u32, + _iids: *mut *mut winrt::Guid, + ) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) + } + extern "system" fn inspectable_type_name( + _this: winrt::NonNullRawComPtr, + _class_name: *mut ::Abi, + ) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) + } + extern "system" fn inspectable_trust_level( + _this: winrt::NonNullRawComPtr, + _trust_level: *mut i32, + ) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) + } + unsafe extern "system" fn initialize( + this: winrt::NonNullRawComPtr, + application_view: ::Abi, + ) -> ::winrt::ErrorCode { + let this: *mut Self = this.as_raw() as _; + let application_view = CoreApplicationView::from_abi(&application_view); + let result = (*this).base.as_ref().unwrap().get_inner() + .initialize(&application_view) + .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)); + std::mem::forget(application_view); + result + } + unsafe extern "system" fn set_window( + this: ::winrt::NonNullRawComPtr, + window: ::Abi, + ) -> ::winrt::ErrorCode { + let this: *mut Self = this.as_raw() as _; + let window = CoreWindow::from_abi(&window); + let result = (*this).base.as_ref().unwrap().get_inner() + .set_window(&window) + .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)); + std::mem::forget(window); + result + } + unsafe extern "system" fn load( + this: ::winrt::NonNullRawComPtr, + entry_point: ::Abi, + ) -> ::winrt::ErrorCode { + let this: *mut Self = this.as_raw() as _; + let entry_point = winrt::HString::from_abi(&entry_point); + let result = (*this).base.as_ref().unwrap().get_inner() + .load(&entry_point) + .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)); + std::mem::forget(entry_point); + result + } + unsafe extern "system" fn run( + this: ::winrt::NonNullRawComPtr, + ) -> ::winrt::ErrorCode { + let this: *mut Self = this.as_raw() as _; + (*this).base.as_ref().unwrap().get_inner() + .run() + .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)) + } + unsafe extern "system" fn uninitialize( + this: ::winrt::NonNullRawComPtr, + ) -> ::winrt::ErrorCode { + let this: *mut Self = this.as_raw() as _; + (*this).base.as_ref().unwrap().get_inner() + .uninitialize() + .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)) + } +} + +impl impl_App_IFrameworkViewSource { + const VTABLE: abi_IFrameworkViewSource_Full = abi_IFrameworkViewSource_Full { + iinspectable: abi_IInspectable { + iunknown: abi_IUnknown { + unknown_query_interface: impl_App_IFrameworkViewSource::unknown_query_interface, + unknown_add_ref: impl_App_IFrameworkViewSource::unknown_add_ref, + unknown_release: impl_App_IFrameworkViewSource::unknown_release, + }, + inspectable_iids: impl_App_IFrameworkViewSource::inspectable_iids, + inspectable_type_name: impl_App_IFrameworkViewSource::inspectable_type_name, + inspectable_trust_level: impl_App_IFrameworkViewSource::inspectable_trust_level, + }, + create_view: impl_App_IFrameworkViewSource::create_view, + }; + + unsafe fn from_base(base: *mut AppRc) -> *mut Self { + Box::into_raw(Box::new(Self { + vtable: &Self::VTABLE, + base + })) + } + + extern "system" fn unknown_query_interface( + this: winrt::NonNullRawComPtr, + iid: &winrt::Guid, + interface: *mut winrt::RawPtr, + ) -> winrt::ErrorCode { + unsafe { + let this: *mut Self = this.as_raw() as _; + if iid == &::iid() + || iid == &::iid() + || iid == &::iid() + || iid == &::iid() + { + *interface = this as winrt::RawPtr; + (*this).base.as_ref().unwrap().add_ref(); + return winrt::ErrorCode(0); + } else if iid == &::iid() { + (*this).base.as_ref().unwrap().add_ref(); + let base = (*this).base; + *interface = (*base).get_view_abi() as winrt::RawPtr; + return winrt::ErrorCode(0); + } else if iid == &::iid() { + (*this).base.as_ref().unwrap().add_ref(); + let base = (*this).base; + *interface = (*base).get_app_abi() as winrt::RawPtr; + return winrt::ErrorCode(0); + } + *interface = std::ptr::null_mut(); + winrt::ErrorCode(0x80004002) + } + } + extern "system" fn unknown_add_ref(this: winrt::NonNullRawComPtr) -> u32 { + unsafe { + let this: *mut Self = this.as_raw() as _; + (*this).base.as_ref().unwrap().add_ref() + } + } + extern "system" fn unknown_release(this: winrt::NonNullRawComPtr) -> u32 { + unsafe { + let this: *mut Self = this.as_raw() as _; + (*this).base.as_ref().unwrap().release() + } + } + extern "system" fn inspectable_iids( + _this: winrt::NonNullRawComPtr, + _iidcount: *mut u32, + _iids: *mut *mut winrt::Guid, + ) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) + } + extern "system" fn inspectable_type_name( + _this: winrt::NonNullRawComPtr, + _class_name: *mut ::Abi, + ) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) + } + extern "system" fn inspectable_trust_level( + _this: winrt::NonNullRawComPtr, + _trust_level: *mut i32, + ) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) + } + unsafe extern "system" fn create_view( + this: ::winrt::NonNullRawComPtr, + result__: *mut ::Abi, + ) -> ::winrt::ErrorCode { + let this: *mut Self = this.as_raw() as _; + (*this).base.as_ref().unwrap().add_ref(); + let base = (*this).base; + *result__ = std::mem::transmute((*base).get_view_abi()); + winrt::ErrorCode(0) + } +} \ No newline at end of file diff --git a/src/uwp/mod.rs b/src/uwp/mod.rs index 1de5345..6e10c56 100644 --- a/src/uwp/mod.rs +++ b/src/uwp/mod.rs @@ -1,4 +1,5 @@ pub mod interop; mod run; +mod app; pub use run::run; \ No newline at end of file diff --git a/src/uwp/run.rs b/src/uwp/run.rs index c829485..709967e 100644 --- a/src/uwp/run.rs +++ b/src/uwp/run.rs @@ -1,3 +1,20 @@ +use bindings::{ + windows::{ + application_model::core::{ + CoreApplication, CoreApplicationView, IFrameworkViewSource, IFrameworkView, + }, + ui::core::{ + CoreDispatcher, CoreWindow, CoreProcessEventsOption, WindowSizeChangedEventArgs, + PointerEventArgs + } + } +}; +use winrt::TryInto; +use crate::uwp::app::App; + pub fn run() -> winrt::Result<()> { + let app = App::new()?; + let view_source: IFrameworkViewSource = app.try_into()?; + CoreApplication::run(&view_source)?; Ok(()) } \ No newline at end of file diff --git a/winrt_guid/Cargo.toml b/winrt_guid/Cargo.toml new file mode 100644 index 0000000..1559b7a --- /dev/null +++ b/winrt_guid/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "winrt_guid" +version = "0.1.0" +authors = ["Robert Mikhayelyan "] +edition = "2018" + +[lib] +proc-macro = true diff --git a/winrt_guid/src/guid.rs b/winrt_guid/src/guid.rs new file mode 100644 index 0000000..1fc7ff6 --- /dev/null +++ b/winrt_guid/src/guid.rs @@ -0,0 +1,85 @@ +// Taken from winrt-rs +// TODO: upstream? + +/// A globally unique identifier [(GUID)](https://docs.microsoft.com/en-us/dotnet/api/system.guid?view=netcore-3.1) +/// used to uniquely identify COM and WinRT interfaces. +#[repr(C)] +#[derive(Clone, Default, PartialEq)] +pub(crate) struct Guid { + pub data1: u32, + pub data2: u16, + pub data3: u16, + pub data4: [u8; 8], +} + +impl Guid { + /// Creates a `Guid` with the given constant values. + pub const fn from_values(data1: u32, data2: u16, data3: u16, data4: [u8; 8]) -> Guid { + Guid { + data1, + data2, + data3, + data4, + } + } +} + +impl From<&str> for Guid { + fn from(value: &str) -> Guid { + assert!(value.len() == 36, "Invalid GUID string"); + let mut bytes = value.bytes(); + + let a = ((bytes.next_u32() * 16 + bytes.next_u32()) << 24) + + ((bytes.next_u32() * 16 + bytes.next_u32()) << 16) + + ((bytes.next_u32() * 16 + bytes.next_u32()) << 8) + + bytes.next_u32() * 16 + + bytes.next_u32(); + assert!(bytes.next().unwrap() == b'-', "Invalid GUID string"); + let b = ((bytes.next_u16() * 16 + (bytes.next_u16())) << 8) + + bytes.next_u16() * 16 + + bytes.next_u16(); + assert!(bytes.next().unwrap() == b'-', "Invalid GUID string"); + let c = ((bytes.next_u16() * 16 + bytes.next_u16()) << 8) + + bytes.next_u16() * 16 + + bytes.next_u16(); + assert!(bytes.next().unwrap() == b'-', "Invalid GUID string"); + let d = bytes.next_u8() * 16 + bytes.next_u8(); + let e = bytes.next_u8() * 16 + bytes.next_u8(); + assert!(bytes.next().unwrap() == b'-', "Invalid GUID string"); + + let f = bytes.next_u8() * 16 + bytes.next_u8(); + let g = bytes.next_u8() * 16 + bytes.next_u8(); + let h = bytes.next_u8() * 16 + bytes.next_u8(); + let i = bytes.next_u8() * 16 + bytes.next_u8(); + let j = bytes.next_u8() * 16 + bytes.next_u8(); + let k = bytes.next_u8() * 16 + bytes.next_u8(); + + Guid::from_values(a, b, c, [d, e, f, g, h, i, j, k]) + } +} + +trait HexReader { + fn next_u8(&mut self) -> u8; + fn next_u16(&mut self) -> u16; + fn next_u32(&mut self) -> u32; +} + +impl HexReader for std::str::Bytes<'_> { + fn next_u8(&mut self) -> u8 { + let value = self.next().unwrap(); + match value { + b'0'..=b'9' => value - b'0', + b'A'..=b'F' => 10 + value - b'A', + b'a'..=b'f' => 10 + value - b'a', + _ => panic!("Invalid GUID string"), + } + } + + fn next_u16(&mut self) -> u16 { + self.next_u8().into() + } + + fn next_u32(&mut self) -> u32 { + self.next_u8().into() + } +} \ No newline at end of file diff --git a/winrt_guid/src/lib.rs b/winrt_guid/src/lib.rs new file mode 100644 index 0000000..311702e --- /dev/null +++ b/winrt_guid/src/lib.rs @@ -0,0 +1,35 @@ +mod guid; + +use guid::Guid; +use proc_macro::{TokenStream, TokenTree}; + +#[proc_macro] +pub fn winrt_guid(input: TokenStream) -> TokenStream { + let input = { + let mut input_string = String::new(); + println!("{:#?}", input); + for part in input { + match part { + TokenTree::Literal(part) => input_string.push_str(&part.to_string()), + TokenTree::Ident(part) => input_string.push_str(&part.to_string()), + TokenTree::Punct(part) => input_string.push(part.as_char()), + _ => assert!(false, "Invalid GUID string"), + } + } + input_string + }; + let guid = Guid::from(input.as_str()); + let data4 = { + let mut data4 = String::new(); + data4.push_str("["); + for data in &guid.data4 { + data4.push_str(&format!("{}, ", data)); + } + data4.pop(); + data4.pop(); + data4.push_str("]"); + data4 + }; + let output = format!("winrt::Guid::from_values({}, {}, {}, {})", guid.data1, guid.data2, guid.data3, data4); + output.parse().unwrap() +} \ No newline at end of file From 5e8f7cef2dddcd827cbd489e6c1727f8c1574f85 Mon Sep 17 00:00:00 2001 From: Robert Mikhayelyan Date: Sun, 26 Jul 2020 18:42:14 -0700 Subject: [PATCH 04/20] working --- AppxManifest.xml | 28 ++++++++++++++++++++++++++++ Assets/LockScreenLogo.png | Bin 0 -> 1173 bytes Assets/SplashScreen.png | Bin 0 -> 17743 bytes Assets/Square150x150Logo.png | Bin 0 -> 4456 bytes Assets/Square44x44Logo.png | Bin 0 -> 2105 bytes Assets/StoreLogo.png | Bin 0 -> 1228 bytes Assets/Wide310x150Logo.png | Bin 0 -> 4886 bytes src/main.rs | 7 ++++--- src/uwp/app.rs | 2 ++ 9 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 AppxManifest.xml create mode 100644 Assets/LockScreenLogo.png create mode 100644 Assets/SplashScreen.png create mode 100644 Assets/Square150x150Logo.png create mode 100644 Assets/Square44x44Logo.png create mode 100644 Assets/StoreLogo.png create mode 100644 Assets/Wide310x150Logo.png diff --git a/AppxManifest.xml b/AppxManifest.xml new file mode 100644 index 0000000..8d505f5 --- /dev/null +++ b/AppxManifest.xml @@ -0,0 +1,28 @@ + + + + + + Minesweeper-rs + robmi + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Assets/LockScreenLogo.png b/Assets/LockScreenLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..99e393347cb088f5796d4966025cdb72794dad23 GIT binary patch literal 1173 zcmV;G1Zw+Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1S&~HK~!i%?U-F? z9Yqw!XLfHBB{yoD2OmW1Lrd|^2SLHMAjH}#*isZkd=asJC9NW96x*yf!H33NEV24h zp@kxTQt+c9Sf~nuqM$E66!oD{&>$AXq=xkF9RFwLZ0^0`c6avnX4B&R!QMINBs=Gv znKQeyqq=nIa%H2X?I`1u(Nm;oj?>t zrLb?{Er<_03!_hCcn_1J=b+r|Y@QI!BAF`gU4sF6Qmi0f5?%>J(V=o!Hb>#;elaDK zY-tdr+;iz5WPl!G%ntV=_$T4D2Ewwsw<&lIT4@)&)$MP7xEItNq!O-%Sf~VlRlA-t z2&GNs)EA%qeAkw3*Fn4;7hH1iZHL{A^n$TS62MI88RW3#<$b$m#CB0~1yPxteh+a! z$ief3%lKb94JC+v|5Oxi8XJB3w6mm>>oJOdzBU>8qz1PsGB&de|XiDlJP0+u;Qf6Y9_W0>Qhj#*NdI8r!?ON5n<^ zW?%(^7c%|&B(PG!dy$#I$_>7yBQtPWlbJx%Cb4)jowrN?`>OQ~*E%s54+Xm#V-af; zUImV?upbM4ky&c7xv}!Xp0lF1#A^*8_>V*^41DMOlodSVmw-{9idY!FVmhX9bW#SF z9~cu4!t=LcT7;undMy^a<1CSR3|oYEAiFv-uooD;R z)WMCKg6&9Z2Wh>oWyhq>VeuR%V@|~9`#(?at@oKPc&4qT$j9roIdzO@ModlMlk_(< zHznT^QXR-ESigT{=!`Wk0r%`j*}R`8c&4ocvOqAupjqp*I%x^Ci}!ora%Gtk(BI+b n>!nw)s@K+hmo8np2ul42hQn_`ZA`LJ00000NkvXXu0mjf+uJu> literal 0 HcmV?d00001 diff --git a/Assets/SplashScreen.png b/Assets/SplashScreen.png new file mode 100644 index 0000000000000000000000000000000000000000..1605ae2ef2913153a07b4ef4a286e295c3cbc469 GIT binary patch literal 17743 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 literal 0 HcmV?d00001 diff --git a/Assets/Square150x150Logo.png b/Assets/Square150x150Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..66b5fd945a02b5576429e44787c618d90bee5537 GIT binary patch literal 4456 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 literal 0 HcmV?d00001 diff --git a/Assets/Square44x44Logo.png b/Assets/Square44x44Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..4aa5c0e4ee7b5c3ef09dd8c32a34b3c1af87798c GIT binary patch literal 2105 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 0, Err(e) => e.code().0 as i32, } -} -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/src/uwp/app.rs b/src/uwp/app.rs index d691f22..396a035 100644 --- a/src/uwp/app.rs +++ b/src/uwp/app.rs @@ -162,6 +162,8 @@ impl AppInner { // TODO: Hook events let window = CoreWindow::get_for_current_thread()?; + window.activate()?; + let dispatcher = window.dispatcher()?; dispatcher.process_events(CoreProcessEventsOption::ProcessUntilQuit)?; From 0c4b54114ac0581b6a9ea3342b51f24944839c14 Mon Sep 17 00:00:00 2001 From: Robert Mikhayelyan Date: Sun, 26 Jul 2020 19:09:18 -0700 Subject: [PATCH 05/20] hooked up minesweeper tree --- src/uwp/app.rs | 560 +++-------------------------------------- src/uwp/app_adapter.rs | 539 +++++++++++++++++++++++++++++++++++++++ src/uwp/mod.rs | 1 + src/uwp/run.rs | 5 +- 4 files changed, 579 insertions(+), 526 deletions(-) create mode 100644 src/uwp/app_adapter.rs diff --git a/src/uwp/app.rs b/src/uwp/app.rs index 396a035..e47e74a 100644 --- a/src/uwp/app.rs +++ b/src/uwp/app.rs @@ -18,150 +18,68 @@ use bindings::{ use std::rc::Rc; use winrt::AbiTransferable; use winrt_guid::winrt_guid; - -#[repr(C)] -pub struct abi_IUnknown { - pub unknown_query_interface: - unsafe extern "system" fn(winrt::NonNullRawComPtr, &winrt::Guid, *mut winrt::RawPtr) -> winrt::ErrorCode, - pub unknown_add_ref: extern "system" fn(winrt::NonNullRawComPtr) -> u32, - pub unknown_release: extern "system" fn(winrt::NonNullRawComPtr) -> u32, -} - -#[repr(C)] -pub struct abi_IInspectable { - iunknown: abi_IUnknown, - - pub inspectable_iids: - unsafe extern "system" fn(winrt::NonNullRawComPtr, *mut u32, *mut *mut winrt::Guid) -> winrt::ErrorCode, - pub inspectable_type_name: unsafe extern "system" fn( - winrt::NonNullRawComPtr, - *mut ::Abi, - ) -> winrt::ErrorCode, - pub inspectable_trust_level: - unsafe extern "system" fn(winrt::NonNullRawComPtr, *mut i32) -> winrt::ErrorCode, -} - -#[derive(Default, Clone, PartialEq)] -#[repr(transparent)] -pub struct App { - ptr: winrt::ComPtr, -} - -impl App { - pub fn new() -> winrt::Result { - unsafe { - let raw = AppRc::new(); - - let mut result: App = std::mem::zeroed(); - let mut ptr: std::ptr::NonNull = std::ptr::NonNull::new_unchecked(raw.as_ref().unwrap().get_app_abi() as _); - *::set_abi(&mut result) = - Some(winrt::NonNullRawComPtr::new(ptr.cast())); - - Ok(result) - } - } -} - -unsafe impl winrt::ComInterface for App { - type VTable = abi_IApp; - fn iid() -> winrt::Guid { - winrt_guid!(DF36D812-3CF5-4B3D-BFA6-AC1A74F3C5C0) - } -} - -unsafe impl winrt::AbiTransferable for App { - type Abi = winrt::RawComPtr; - fn get_abi(&self) -> Self::Abi { - as winrt::AbiTransferable>::get_abi(&self.ptr) - } - fn set_abi(&mut self) -> *mut Self::Abi { - as winrt::AbiTransferable>::set_abi(&mut self.ptr) - } -} - -#[repr(C)] -pub struct abi_IApp { - iinspectable: abi_IInspectable, -} - -#[repr(C)] -pub struct abi_IFrameworkView_Full { - iinspectable: abi_IInspectable, - pub initialize: unsafe extern "system" fn( - ::winrt::NonNullRawComPtr, - application_view: ::Abi, - ) -> ::winrt::ErrorCode, - pub set_window: unsafe extern "system" fn( - ::winrt::NonNullRawComPtr, - window: ::Abi, - ) -> ::winrt::ErrorCode, - pub load: unsafe extern "system" fn( - ::winrt::NonNullRawComPtr, - entry_point: ::Abi, - ) -> ::winrt::ErrorCode, - pub run: unsafe extern "system" fn( - ::winrt::NonNullRawComPtr, - ) -> ::winrt::ErrorCode, - pub uninitialize: unsafe extern "system" fn( - ::winrt::NonNullRawComPtr, - ) -> ::winrt::ErrorCode, -} - -#[repr(C)] -pub struct abi_IFrameworkViewSource_Full { - iinspectable: abi_IInspectable, - pub create_view: unsafe extern "system" fn( - ::winrt::NonNullRawComPtr, - result__: *mut ::Abi, - ) -> ::winrt::ErrorCode, -} +use crate::uwp::app_adapter::UwpApp; +use crate::minesweeper::Minesweeper; struct AppState { + window: CoreWindow, compositor: Compositor, target: CompositionTarget, + + game: Minesweeper, } -struct AppInner { +pub struct MinesweeperApp { state: Option } -impl AppInner { +impl MinesweeperApp { pub fn new() -> Self { Self { state: None, } } +} - pub fn initialize(&self, window: &CoreApplicationView) -> winrt::Result<()> { +impl UwpApp for MinesweeperApp { + fn initialize(&mut self, window: &CoreApplicationView) -> winrt::Result<()> { Ok(()) } - pub fn set_window(&self, window: &CoreWindow) -> winrt::Result<()> { + fn set_window(&mut self, window: &CoreWindow) -> winrt::Result<()> { Ok(()) } - pub fn load(&self, entry_point: &winrt::HString) -> winrt::Result<()> { + fn load(&mut self, entry_point: &winrt::HString) -> winrt::Result<()> { Ok(()) } - pub fn run(&self) -> winrt::Result<()> { + fn run(&mut self) -> winrt::Result<()> { + let window = CoreWindow::get_for_current_thread()?; + + // Init Composition let compositor = Compositor::new()?; let root = compositor.create_container_visual()?; root.set_relative_size_adjustment(Vector2 { x:1.0, y:1.0 })?; let target = compositor.create_target_for_current_view()?; target.set_root(&root)?; - // TODO: Remove - let test = compositor.create_sprite_visual()?; - test.set_size(Vector2 { x: 200.0, y: 200.0 })?; - test.set_brush(compositor.create_color_brush_with_color(Colors::red()?)?)?; - root.children()?.insert_at_top(&test)?; - - // TODO: Init minesweeper + // Init minesweeper + let window_size = get_window_size(&window)?; + let mut game = Minesweeper::new(&root, &window_size)?; // TODO: Hook events - let window = CoreWindow::get_for_current_thread()?; + let state = AppState { + window, + compositor, + target, + + game, + }; + self.state = Some(state); + + let window = &self.state.as_ref().unwrap().window; window.activate()?; let dispatcher = window.dispatcher()?; @@ -170,421 +88,15 @@ impl AppInner { Ok(()) } - pub fn uninitialize(&self) -> winrt::Result<()> { + fn uninitialize(&mut self) -> winrt::Result<()> { Ok(()) } } -struct AppRc { - count: winrt::RefCount, - this: *mut AppRc, - app_abi: *mut impl_App, - view_abi: *mut impl_App_IFrameworkView, - view_source_abi: *mut impl_App_IFrameworkViewSource, - inner: AppInner, -} - -impl AppRc { - pub fn new() -> *mut Self { - let count = winrt::RefCount::new(); - let inner = AppInner::new(); - unsafe { - let base = Self { - count, - this: std::ptr::null_mut::(), - app_abi: std::ptr::null_mut::(), - view_abi: std::ptr::null_mut::(), - view_source_abi: std::ptr::null_mut::(), - inner - }; - let base = Box::into_raw(Box::new(base)); - - let app_abi = impl_App::from_base(base); - let view_abi = impl_App_IFrameworkView::from_base(base); - let view_source_abi = impl_App_IFrameworkViewSource::from_base(base); - - (*base).this = base; - (*base).app_abi = app_abi; - (*base).view_abi = view_abi; - (*base).view_source_abi = view_source_abi; - - base - } - } - - pub fn add_ref(&self) -> u32 { - self.count.add_ref() - } - - pub unsafe fn release(&self) -> u32 { - let remaining = self.count.release(); - if remaining == 0 { - Box::from_raw(self.this); - } - remaining - } - - pub unsafe fn get_inner(&self) -> &AppInner { - &self.inner - } - - pub fn get_app_abi(&self) -> *mut impl_App { - self.app_abi - } - - pub fn get_view_abi(&self) -> *mut impl_App_IFrameworkView { - self.view_abi - } - - pub fn get_view_source_abi(&self) -> *mut impl_App_IFrameworkViewSource { - self.view_source_abi - } -} - -impl Drop for AppRc { - fn drop(&mut self) { - unsafe { - Box::from_raw(self.app_abi); - Box::from_raw(self.view_abi); - Box::from_raw(self.view_source_abi); - } - } -} - -#[repr(C)] -struct impl_App_IFrameworkView { - vtable: *const abi_IFrameworkView_Full, - base: *mut AppRc, -} - -#[repr(C)] -struct impl_App_IFrameworkViewSource { - vtable: *const abi_IFrameworkViewSource_Full, - base: *mut AppRc, -} - -#[repr(C)] -struct impl_App { - vtable: *const abi_IApp, - base: *mut AppRc, -} - -impl impl_App { - const VTABLE: abi_IApp = abi_IApp { - iinspectable: abi_IInspectable { - iunknown: abi_IUnknown { - unknown_query_interface: impl_App::unknown_query_interface, - unknown_add_ref: impl_App::unknown_add_ref, - unknown_release: impl_App::unknown_release, - }, - inspectable_iids: impl_App::inspectable_iids, - inspectable_type_name: impl_App::inspectable_type_name, - inspectable_trust_level: impl_App::inspectable_trust_level, - }, - }; - - unsafe fn from_base(base: *mut AppRc) -> *mut Self { - Box::into_raw(Box::new(Self { - vtable: &Self::VTABLE, - base - })) - } - - extern "system" fn unknown_query_interface( - this: winrt::NonNullRawComPtr, - iid: &winrt::Guid, - interface: *mut winrt::RawPtr, - ) -> winrt::ErrorCode { - unsafe { - let this: *mut Self = this.as_raw() as _; - if iid == &::iid() - || iid == &::iid() - || iid == &::iid() - || iid == &::iid() - { - *interface = this as winrt::RawPtr; - (*this).base.as_ref().unwrap().add_ref(); - return winrt::ErrorCode(0); - } else if iid == &::iid() { - (*this).base.as_ref().unwrap().add_ref(); - let base = (*this).base; - *interface = (*base).get_view_abi() as winrt::RawPtr; - return winrt::ErrorCode(0); - } else if iid == &::iid() { - (*this).base.as_ref().unwrap().add_ref(); - let base = (*this).base; - *interface = (*base).get_view_source_abi() as winrt::RawPtr; - return winrt::ErrorCode(0); - } - *interface = std::ptr::null_mut(); - winrt::ErrorCode(0x80004002) - } - } - extern "system" fn unknown_add_ref(this: winrt::NonNullRawComPtr) -> u32 { - unsafe { - let this: *mut Self = this.as_raw() as _; - (*this).base.as_ref().unwrap().add_ref() - } - } - extern "system" fn unknown_release(this: winrt::NonNullRawComPtr) -> u32 { - unsafe { - let this: *mut Self = this.as_raw() as _; - (*this).base.as_ref().unwrap().release() - } - } - extern "system" fn inspectable_iids( - _this: winrt::NonNullRawComPtr, - _iidcount: *mut u32, - _iids: *mut *mut winrt::Guid, - ) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) - } - extern "system" fn inspectable_type_name( - _this: winrt::NonNullRawComPtr, - _class_name: *mut ::Abi, - ) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) - } - extern "system" fn inspectable_trust_level( - _this: winrt::NonNullRawComPtr, - _trust_level: *mut i32, - ) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) - } -} - -impl impl_App_IFrameworkView { - const VTABLE: abi_IFrameworkView_Full = abi_IFrameworkView_Full { - iinspectable: abi_IInspectable { - iunknown: abi_IUnknown { - unknown_query_interface: impl_App_IFrameworkView::unknown_query_interface, - unknown_add_ref: impl_App_IFrameworkView::unknown_add_ref, - unknown_release: impl_App_IFrameworkView::unknown_release, - }, - inspectable_iids: impl_App_IFrameworkView::inspectable_iids, - inspectable_type_name: impl_App_IFrameworkView::inspectable_type_name, - inspectable_trust_level: impl_App_IFrameworkView::inspectable_trust_level, - }, - initialize: impl_App_IFrameworkView::initialize, - set_window: impl_App_IFrameworkView::set_window, - load: impl_App_IFrameworkView::load, - run: impl_App_IFrameworkView::run, - uninitialize: impl_App_IFrameworkView::uninitialize, - }; - - unsafe fn from_base(base: *mut AppRc) -> *mut Self { - Box::into_raw(Box::new(Self { - vtable: &Self::VTABLE, - base - })) - } - - extern "system" fn unknown_query_interface( - this: winrt::NonNullRawComPtr, - iid: &winrt::Guid, - interface: *mut winrt::RawPtr, - ) -> winrt::ErrorCode { - unsafe { - let this: *mut Self = this.as_raw() as _; - if iid == &::iid() - || iid == &::iid() - || iid == &::iid() - || iid == &::iid() - { - *interface = this as winrt::RawPtr; - (*this).base.as_ref().unwrap().add_ref(); - return winrt::ErrorCode(0); - } else if iid == &::iid() { - (*this).base.as_ref().unwrap().add_ref(); - let base = (*this).base; - *interface = (*base).get_app_abi() as winrt::RawPtr; - return winrt::ErrorCode(0); - } else if iid == &::iid() { - (*this).base.as_ref().unwrap().add_ref(); - let base = (*this).base; - *interface = (*base).get_view_source_abi() as winrt::RawPtr; - return winrt::ErrorCode(0); - } - *interface = std::ptr::null_mut(); - winrt::ErrorCode(0x80004002) - } - } - extern "system" fn unknown_add_ref(this: winrt::NonNullRawComPtr) -> u32 { - unsafe { - let this: *mut Self = this.as_raw() as _; - (*this).base.as_ref().unwrap().add_ref() - } - } - extern "system" fn unknown_release(this: winrt::NonNullRawComPtr) -> u32 { - unsafe { - let this: *mut Self = this.as_raw() as _; - (*this).base.as_ref().unwrap().release() - } - } - extern "system" fn inspectable_iids( - _this: winrt::NonNullRawComPtr, - _iidcount: *mut u32, - _iids: *mut *mut winrt::Guid, - ) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) - } - extern "system" fn inspectable_type_name( - _this: winrt::NonNullRawComPtr, - _class_name: *mut ::Abi, - ) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) - } - extern "system" fn inspectable_trust_level( - _this: winrt::NonNullRawComPtr, - _trust_level: *mut i32, - ) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) - } - unsafe extern "system" fn initialize( - this: winrt::NonNullRawComPtr, - application_view: ::Abi, - ) -> ::winrt::ErrorCode { - let this: *mut Self = this.as_raw() as _; - let application_view = CoreApplicationView::from_abi(&application_view); - let result = (*this).base.as_ref().unwrap().get_inner() - .initialize(&application_view) - .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)); - std::mem::forget(application_view); - result - } - unsafe extern "system" fn set_window( - this: ::winrt::NonNullRawComPtr, - window: ::Abi, - ) -> ::winrt::ErrorCode { - let this: *mut Self = this.as_raw() as _; - let window = CoreWindow::from_abi(&window); - let result = (*this).base.as_ref().unwrap().get_inner() - .set_window(&window) - .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)); - std::mem::forget(window); - result - } - unsafe extern "system" fn load( - this: ::winrt::NonNullRawComPtr, - entry_point: ::Abi, - ) -> ::winrt::ErrorCode { - let this: *mut Self = this.as_raw() as _; - let entry_point = winrt::HString::from_abi(&entry_point); - let result = (*this).base.as_ref().unwrap().get_inner() - .load(&entry_point) - .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)); - std::mem::forget(entry_point); - result - } - unsafe extern "system" fn run( - this: ::winrt::NonNullRawComPtr, - ) -> ::winrt::ErrorCode { - let this: *mut Self = this.as_raw() as _; - (*this).base.as_ref().unwrap().get_inner() - .run() - .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)) - } - unsafe extern "system" fn uninitialize( - this: ::winrt::NonNullRawComPtr, - ) -> ::winrt::ErrorCode { - let this: *mut Self = this.as_raw() as _; - (*this).base.as_ref().unwrap().get_inner() - .uninitialize() - .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)) - } -} - -impl impl_App_IFrameworkViewSource { - const VTABLE: abi_IFrameworkViewSource_Full = abi_IFrameworkViewSource_Full { - iinspectable: abi_IInspectable { - iunknown: abi_IUnknown { - unknown_query_interface: impl_App_IFrameworkViewSource::unknown_query_interface, - unknown_add_ref: impl_App_IFrameworkViewSource::unknown_add_ref, - unknown_release: impl_App_IFrameworkViewSource::unknown_release, - }, - inspectable_iids: impl_App_IFrameworkViewSource::inspectable_iids, - inspectable_type_name: impl_App_IFrameworkViewSource::inspectable_type_name, - inspectable_trust_level: impl_App_IFrameworkViewSource::inspectable_trust_level, - }, - create_view: impl_App_IFrameworkViewSource::create_view, - }; - - unsafe fn from_base(base: *mut AppRc) -> *mut Self { - Box::into_raw(Box::new(Self { - vtable: &Self::VTABLE, - base - })) - } - - extern "system" fn unknown_query_interface( - this: winrt::NonNullRawComPtr, - iid: &winrt::Guid, - interface: *mut winrt::RawPtr, - ) -> winrt::ErrorCode { - unsafe { - let this: *mut Self = this.as_raw() as _; - if iid == &::iid() - || iid == &::iid() - || iid == &::iid() - || iid == &::iid() - { - *interface = this as winrt::RawPtr; - (*this).base.as_ref().unwrap().add_ref(); - return winrt::ErrorCode(0); - } else if iid == &::iid() { - (*this).base.as_ref().unwrap().add_ref(); - let base = (*this).base; - *interface = (*base).get_view_abi() as winrt::RawPtr; - return winrt::ErrorCode(0); - } else if iid == &::iid() { - (*this).base.as_ref().unwrap().add_ref(); - let base = (*this).base; - *interface = (*base).get_app_abi() as winrt::RawPtr; - return winrt::ErrorCode(0); - } - *interface = std::ptr::null_mut(); - winrt::ErrorCode(0x80004002) - } - } - extern "system" fn unknown_add_ref(this: winrt::NonNullRawComPtr) -> u32 { - unsafe { - let this: *mut Self = this.as_raw() as _; - (*this).base.as_ref().unwrap().add_ref() - } - } - extern "system" fn unknown_release(this: winrt::NonNullRawComPtr) -> u32 { - unsafe { - let this: *mut Self = this.as_raw() as _; - (*this).base.as_ref().unwrap().release() - } - } - extern "system" fn inspectable_iids( - _this: winrt::NonNullRawComPtr, - _iidcount: *mut u32, - _iids: *mut *mut winrt::Guid, - ) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) - } - extern "system" fn inspectable_type_name( - _this: winrt::NonNullRawComPtr, - _class_name: *mut ::Abi, - ) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) - } - extern "system" fn inspectable_trust_level( - _this: winrt::NonNullRawComPtr, - _trust_level: *mut i32, - ) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) - } - unsafe extern "system" fn create_view( - this: ::winrt::NonNullRawComPtr, - result__: *mut ::Abi, - ) -> ::winrt::ErrorCode { - let this: *mut Self = this.as_raw() as _; - (*this).base.as_ref().unwrap().add_ref(); - let base = (*this).base; - *result__ = std::mem::transmute((*base).get_view_abi()); - winrt::ErrorCode(0) - } +fn get_window_size(window: &CoreWindow) -> winrt::Result { + let bounds = window.bounds()?; + Ok(Vector2 { + x: bounds.width as f32, + y: bounds.height as f32, + }) } \ No newline at end of file diff --git a/src/uwp/app_adapter.rs b/src/uwp/app_adapter.rs new file mode 100644 index 0000000..2d00813 --- /dev/null +++ b/src/uwp/app_adapter.rs @@ -0,0 +1,539 @@ +use bindings::{ + windows::{ + application_model::core::{ + CoreApplication, CoreApplicationView, IFrameworkViewSource, IFrameworkView, + abi_IFrameworkViewSource, abi_IFrameworkView, + }, + foundation::numerics::Vector2, + ui::Colors, + ui::core::{ + CoreDispatcher, CoreWindow, CoreProcessEventsOption, WindowSizeChangedEventArgs, + PointerEventArgs + }, + ui::composition::{ + Compositor, CompositionTarget + } + } +}; +use std::rc::Rc; +use winrt::AbiTransferable; +use winrt_guid::winrt_guid; + +#[repr(C)] +pub struct abi_IUnknown { + pub unknown_query_interface: + unsafe extern "system" fn(winrt::NonNullRawComPtr, &winrt::Guid, *mut winrt::RawPtr) -> winrt::ErrorCode, + pub unknown_add_ref: extern "system" fn(winrt::NonNullRawComPtr) -> u32, + pub unknown_release: extern "system" fn(winrt::NonNullRawComPtr) -> u32, +} + +#[repr(C)] +pub struct abi_IInspectable { + iunknown: abi_IUnknown, + + pub inspectable_iids: + unsafe extern "system" fn(winrt::NonNullRawComPtr, *mut u32, *mut *mut winrt::Guid) -> winrt::ErrorCode, + pub inspectable_type_name: unsafe extern "system" fn( + winrt::NonNullRawComPtr, + *mut ::Abi, + ) -> winrt::ErrorCode, + pub inspectable_trust_level: + unsafe extern "system" fn(winrt::NonNullRawComPtr, *mut i32) -> winrt::ErrorCode, +} + +#[derive(Default, Clone, PartialEq)] +#[repr(transparent)] +pub struct App { + ptr: winrt::ComPtr, +} + +impl App { + pub fn new(app_inner: Box) -> winrt::Result { + unsafe { + let raw = AppRc::new(app_inner); + + let mut result: App = std::mem::zeroed(); + let mut ptr: std::ptr::NonNull = std::ptr::NonNull::new_unchecked(raw.as_ref().unwrap().get_app_abi() as _); + *::set_abi(&mut result) = + Some(winrt::NonNullRawComPtr::new(ptr.cast())); + + Ok(result) + } + } +} + +unsafe impl winrt::ComInterface for App { + type VTable = abi_IApp; + fn iid() -> winrt::Guid { + winrt_guid!(DF36D812-3CF5-4B3D-BFA6-AC1A74F3C5C0) + } +} + +unsafe impl winrt::AbiTransferable for App { + type Abi = winrt::RawComPtr; + fn get_abi(&self) -> Self::Abi { + as winrt::AbiTransferable>::get_abi(&self.ptr) + } + fn set_abi(&mut self) -> *mut Self::Abi { + as winrt::AbiTransferable>::set_abi(&mut self.ptr) + } +} + +#[repr(C)] +pub struct abi_IApp { + iinspectable: abi_IInspectable, +} + +#[repr(C)] +pub struct abi_IFrameworkView_Full { + iinspectable: abi_IInspectable, + pub initialize: unsafe extern "system" fn( + ::winrt::NonNullRawComPtr, + application_view: ::Abi, + ) -> ::winrt::ErrorCode, + pub set_window: unsafe extern "system" fn( + ::winrt::NonNullRawComPtr, + window: ::Abi, + ) -> ::winrt::ErrorCode, + pub load: unsafe extern "system" fn( + ::winrt::NonNullRawComPtr, + entry_point: ::Abi, + ) -> ::winrt::ErrorCode, + pub run: unsafe extern "system" fn( + ::winrt::NonNullRawComPtr, + ) -> ::winrt::ErrorCode, + pub uninitialize: unsafe extern "system" fn( + ::winrt::NonNullRawComPtr, + ) -> ::winrt::ErrorCode, +} + +#[repr(C)] +pub struct abi_IFrameworkViewSource_Full { + iinspectable: abi_IInspectable, + pub create_view: unsafe extern "system" fn( + ::winrt::NonNullRawComPtr, + result__: *mut ::Abi, + ) -> ::winrt::ErrorCode, +} + +pub trait UwpApp { + fn initialize(&mut self, window: &CoreApplicationView) -> winrt::Result<()>; + fn set_window(&mut self, window: &CoreWindow) -> winrt::Result<()>; + fn load(&mut self, entry_point: &winrt::HString) -> winrt::Result<()>; + fn run(&mut self) -> winrt::Result<()>; + fn uninitialize(&mut self) -> winrt::Result<()>; +} + +struct AppRc { + count: winrt::RefCount, + this: *mut AppRc, + app_abi: *mut impl_App, + view_abi: *mut impl_App_IFrameworkView, + view_source_abi: *mut impl_App_IFrameworkViewSource, + inner: Box, +} + +impl AppRc { + pub fn new(inner: Box) -> *mut Self { + let count = winrt::RefCount::new(); + unsafe { + let base = Self { + count, + this: std::ptr::null_mut::(), + app_abi: std::ptr::null_mut::(), + view_abi: std::ptr::null_mut::(), + view_source_abi: std::ptr::null_mut::(), + inner, + }; + let base = Box::into_raw(Box::new(base)); + + let app_abi = impl_App::from_base(base); + let view_abi = impl_App_IFrameworkView::from_base(base); + let view_source_abi = impl_App_IFrameworkViewSource::from_base(base); + + (*base).this = base; + (*base).app_abi = app_abi; + (*base).view_abi = view_abi; + (*base).view_source_abi = view_source_abi; + + base + } + } + + pub fn add_ref(&self) -> u32 { + self.count.add_ref() + } + + pub unsafe fn release(&self) -> u32 { + let remaining = self.count.release(); + if remaining == 0 { + Box::from_raw(self.this); + } + remaining + } + + pub fn get_inner(&mut self) -> &mut dyn UwpApp { + self.inner.as_mut() + } + + pub fn get_app_abi(&self) -> *mut impl_App { + self.app_abi + } + + pub fn get_view_abi(&self) -> *mut impl_App_IFrameworkView { + self.view_abi + } + + pub fn get_view_source_abi(&self) -> *mut impl_App_IFrameworkViewSource { + self.view_source_abi + } +} + +impl Drop for AppRc { + fn drop(&mut self) { + unsafe { + Box::from_raw(self.app_abi); + Box::from_raw(self.view_abi); + Box::from_raw(self.view_source_abi); + } + } +} + +#[repr(C)] +struct impl_App_IFrameworkView { + vtable: *const abi_IFrameworkView_Full, + base: *mut AppRc, +} + +#[repr(C)] +struct impl_App_IFrameworkViewSource { + vtable: *const abi_IFrameworkViewSource_Full, + base: *mut AppRc, +} + +#[repr(C)] +struct impl_App { + vtable: *const abi_IApp, + base: *mut AppRc, +} + +impl impl_App { + const VTABLE: abi_IApp = abi_IApp { + iinspectable: abi_IInspectable { + iunknown: abi_IUnknown { + unknown_query_interface: impl_App::unknown_query_interface, + unknown_add_ref: impl_App::unknown_add_ref, + unknown_release: impl_App::unknown_release, + }, + inspectable_iids: impl_App::inspectable_iids, + inspectable_type_name: impl_App::inspectable_type_name, + inspectable_trust_level: impl_App::inspectable_trust_level, + }, + }; + + unsafe fn from_base(base: *mut AppRc) -> *mut Self { + Box::into_raw(Box::new(Self { + vtable: &Self::VTABLE, + base + })) + } + + extern "system" fn unknown_query_interface( + this: winrt::NonNullRawComPtr, + iid: &winrt::Guid, + interface: *mut winrt::RawPtr, + ) -> winrt::ErrorCode { + unsafe { + let this: *mut Self = this.as_raw() as _; + if iid == &::iid() + || iid == &::iid() + || iid == &::iid() + || iid == &::iid() + { + *interface = this as winrt::RawPtr; + (*this).base.as_ref().unwrap().add_ref(); + return winrt::ErrorCode(0); + } else if iid == &::iid() { + (*this).base.as_ref().unwrap().add_ref(); + let base = (*this).base; + *interface = (*base).get_view_abi() as winrt::RawPtr; + return winrt::ErrorCode(0); + } else if iid == &::iid() { + (*this).base.as_ref().unwrap().add_ref(); + let base = (*this).base; + *interface = (*base).get_view_source_abi() as winrt::RawPtr; + return winrt::ErrorCode(0); + } + *interface = std::ptr::null_mut(); + winrt::ErrorCode(0x80004002) + } + } + extern "system" fn unknown_add_ref(this: winrt::NonNullRawComPtr) -> u32 { + unsafe { + let this: *mut Self = this.as_raw() as _; + (*this).base.as_ref().unwrap().add_ref() + } + } + extern "system" fn unknown_release(this: winrt::NonNullRawComPtr) -> u32 { + unsafe { + let this: *mut Self = this.as_raw() as _; + (*this).base.as_ref().unwrap().release() + } + } + extern "system" fn inspectable_iids( + _this: winrt::NonNullRawComPtr, + _iidcount: *mut u32, + _iids: *mut *mut winrt::Guid, + ) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) + } + extern "system" fn inspectable_type_name( + _this: winrt::NonNullRawComPtr, + _class_name: *mut ::Abi, + ) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) + } + extern "system" fn inspectable_trust_level( + _this: winrt::NonNullRawComPtr, + _trust_level: *mut i32, + ) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) + } +} + +impl impl_App_IFrameworkView { + const VTABLE: abi_IFrameworkView_Full = abi_IFrameworkView_Full { + iinspectable: abi_IInspectable { + iunknown: abi_IUnknown { + unknown_query_interface: impl_App_IFrameworkView::unknown_query_interface, + unknown_add_ref: impl_App_IFrameworkView::unknown_add_ref, + unknown_release: impl_App_IFrameworkView::unknown_release, + }, + inspectable_iids: impl_App_IFrameworkView::inspectable_iids, + inspectable_type_name: impl_App_IFrameworkView::inspectable_type_name, + inspectable_trust_level: impl_App_IFrameworkView::inspectable_trust_level, + }, + initialize: impl_App_IFrameworkView::initialize, + set_window: impl_App_IFrameworkView::set_window, + load: impl_App_IFrameworkView::load, + run: impl_App_IFrameworkView::run, + uninitialize: impl_App_IFrameworkView::uninitialize, + }; + + unsafe fn from_base(base: *mut AppRc) -> *mut Self { + Box::into_raw(Box::new(Self { + vtable: &Self::VTABLE, + base + })) + } + + extern "system" fn unknown_query_interface( + this: winrt::NonNullRawComPtr, + iid: &winrt::Guid, + interface: *mut winrt::RawPtr, + ) -> winrt::ErrorCode { + unsafe { + let this: *mut Self = this.as_raw() as _; + if iid == &::iid() + || iid == &::iid() + || iid == &::iid() + || iid == &::iid() + { + *interface = this as winrt::RawPtr; + (*this).base.as_ref().unwrap().add_ref(); + return winrt::ErrorCode(0); + } else if iid == &::iid() { + (*this).base.as_ref().unwrap().add_ref(); + let base = (*this).base; + *interface = (*base).get_app_abi() as winrt::RawPtr; + return winrt::ErrorCode(0); + } else if iid == &::iid() { + (*this).base.as_ref().unwrap().add_ref(); + let base = (*this).base; + *interface = (*base).get_view_source_abi() as winrt::RawPtr; + return winrt::ErrorCode(0); + } + *interface = std::ptr::null_mut(); + winrt::ErrorCode(0x80004002) + } + } + extern "system" fn unknown_add_ref(this: winrt::NonNullRawComPtr) -> u32 { + unsafe { + let this: *mut Self = this.as_raw() as _; + (*this).base.as_ref().unwrap().add_ref() + } + } + extern "system" fn unknown_release(this: winrt::NonNullRawComPtr) -> u32 { + unsafe { + let this: *mut Self = this.as_raw() as _; + (*this).base.as_ref().unwrap().release() + } + } + extern "system" fn inspectable_iids( + _this: winrt::NonNullRawComPtr, + _iidcount: *mut u32, + _iids: *mut *mut winrt::Guid, + ) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) + } + extern "system" fn inspectable_type_name( + _this: winrt::NonNullRawComPtr, + _class_name: *mut ::Abi, + ) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) + } + extern "system" fn inspectable_trust_level( + _this: winrt::NonNullRawComPtr, + _trust_level: *mut i32, + ) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) + } + unsafe extern "system" fn initialize( + this: winrt::NonNullRawComPtr, + application_view: ::Abi, + ) -> ::winrt::ErrorCode { + let this: *mut Self = this.as_raw() as _; + let base = (*this).base.as_mut().unwrap(); + let application_view = CoreApplicationView::from_abi(&application_view); + let result = base.get_inner() + .initialize(&application_view) + .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)); + std::mem::forget(application_view); + result + } + unsafe extern "system" fn set_window( + this: ::winrt::NonNullRawComPtr, + window: ::Abi, + ) -> ::winrt::ErrorCode { + let this: *mut Self = this.as_raw() as _; + let window = CoreWindow::from_abi(&window); + let result = (*this).base.as_mut().unwrap().get_inner() + .set_window(&window) + .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)); + std::mem::forget(window); + result + } + unsafe extern "system" fn load( + this: ::winrt::NonNullRawComPtr, + entry_point: ::Abi, + ) -> ::winrt::ErrorCode { + let this: *mut Self = this.as_raw() as _; + let entry_point = winrt::HString::from_abi(&entry_point); + let result = (*this).base.as_mut().unwrap().get_inner() + .load(&entry_point) + .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)); + std::mem::forget(entry_point); + result + } + unsafe extern "system" fn run( + this: ::winrt::NonNullRawComPtr, + ) -> ::winrt::ErrorCode { + let this: *mut Self = this.as_raw() as _; + (*this).base.as_mut().unwrap().get_inner() + .run() + .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)) + } + unsafe extern "system" fn uninitialize( + this: ::winrt::NonNullRawComPtr, + ) -> ::winrt::ErrorCode { + let this: *mut Self = this.as_raw() as _; + (*this).base.as_mut().unwrap().get_inner() + .uninitialize() + .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)) + } +} + +impl impl_App_IFrameworkViewSource { + const VTABLE: abi_IFrameworkViewSource_Full = abi_IFrameworkViewSource_Full { + iinspectable: abi_IInspectable { + iunknown: abi_IUnknown { + unknown_query_interface: impl_App_IFrameworkViewSource::unknown_query_interface, + unknown_add_ref: impl_App_IFrameworkViewSource::unknown_add_ref, + unknown_release: impl_App_IFrameworkViewSource::unknown_release, + }, + inspectable_iids: impl_App_IFrameworkViewSource::inspectable_iids, + inspectable_type_name: impl_App_IFrameworkViewSource::inspectable_type_name, + inspectable_trust_level: impl_App_IFrameworkViewSource::inspectable_trust_level, + }, + create_view: impl_App_IFrameworkViewSource::create_view, + }; + + unsafe fn from_base(base: *mut AppRc) -> *mut Self { + Box::into_raw(Box::new(Self { + vtable: &Self::VTABLE, + base + })) + } + + extern "system" fn unknown_query_interface( + this: winrt::NonNullRawComPtr, + iid: &winrt::Guid, + interface: *mut winrt::RawPtr, + ) -> winrt::ErrorCode { + unsafe { + let this: *mut Self = this.as_raw() as _; + if iid == &::iid() + || iid == &::iid() + || iid == &::iid() + || iid == &::iid() + { + *interface = this as winrt::RawPtr; + (*this).base.as_ref().unwrap().add_ref(); + return winrt::ErrorCode(0); + } else if iid == &::iid() { + (*this).base.as_ref().unwrap().add_ref(); + let base = (*this).base; + *interface = (*base).get_view_abi() as winrt::RawPtr; + return winrt::ErrorCode(0); + } else if iid == &::iid() { + (*this).base.as_ref().unwrap().add_ref(); + let base = (*this).base; + *interface = (*base).get_app_abi() as winrt::RawPtr; + return winrt::ErrorCode(0); + } + *interface = std::ptr::null_mut(); + winrt::ErrorCode(0x80004002) + } + } + extern "system" fn unknown_add_ref(this: winrt::NonNullRawComPtr) -> u32 { + unsafe { + let this: *mut Self = this.as_raw() as _; + (*this).base.as_ref().unwrap().add_ref() + } + } + extern "system" fn unknown_release(this: winrt::NonNullRawComPtr) -> u32 { + unsafe { + let this: *mut Self = this.as_raw() as _; + (*this).base.as_ref().unwrap().release() + } + } + extern "system" fn inspectable_iids( + _this: winrt::NonNullRawComPtr, + _iidcount: *mut u32, + _iids: *mut *mut winrt::Guid, + ) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) + } + extern "system" fn inspectable_type_name( + _this: winrt::NonNullRawComPtr, + _class_name: *mut ::Abi, + ) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) + } + extern "system" fn inspectable_trust_level( + _this: winrt::NonNullRawComPtr, + _trust_level: *mut i32, + ) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) + } + unsafe extern "system" fn create_view( + this: ::winrt::NonNullRawComPtr, + result__: *mut ::Abi, + ) -> ::winrt::ErrorCode { + let this: *mut Self = this.as_raw() as _; + (*this).base.as_ref().unwrap().add_ref(); + let base = (*this).base; + *result__ = std::mem::transmute((*base).get_view_abi()); + winrt::ErrorCode(0) + } +} \ No newline at end of file diff --git a/src/uwp/mod.rs b/src/uwp/mod.rs index 6e10c56..8317436 100644 --- a/src/uwp/mod.rs +++ b/src/uwp/mod.rs @@ -1,5 +1,6 @@ pub mod interop; mod run; mod app; +mod app_adapter; pub use run::run; \ No newline at end of file diff --git a/src/uwp/run.rs b/src/uwp/run.rs index 709967e..94246ca 100644 --- a/src/uwp/run.rs +++ b/src/uwp/run.rs @@ -10,10 +10,11 @@ use bindings::{ } }; use winrt::TryInto; -use crate::uwp::app::App; +use crate::uwp::app::MinesweeperApp; +use crate::uwp::app_adapter::App; pub fn run() -> winrt::Result<()> { - let app = App::new()?; + let app = App::new(Box::new(MinesweeperApp::new()))?; let view_source: IFrameworkViewSource = app.try_into()?; CoreApplication::run(&view_source)?; Ok(()) From a87c1f40923f284dc16d943047777e2560b4253a Mon Sep 17 00:00:00 2001 From: Robert Mikhayelyan Date: Sun, 26 Jul 2020 19:12:00 -0700 Subject: [PATCH 06/20] clean up --- AppxManifest.xml | 8 ++++---- {Assets => assets}/LockScreenLogo.png | Bin {Assets => assets}/SplashScreen.png | Bin {Assets => assets}/Square150x150Logo.png | Bin {Assets => assets}/Square44x44Logo.png | Bin {Assets => assets}/StoreLogo.png | Bin {Assets => assets}/Wide310x150Logo.png | Bin src/main.rs | 25 ----------------------- 8 files changed, 4 insertions(+), 29 deletions(-) rename {Assets => assets}/LockScreenLogo.png (100%) rename {Assets => assets}/SplashScreen.png (100%) rename {Assets => assets}/Square150x150Logo.png (100%) rename {Assets => assets}/Square44x44Logo.png (100%) rename {Assets => assets}/StoreLogo.png (100%) rename {Assets => assets}/Wide310x150Logo.png (100%) diff --git a/AppxManifest.xml b/AppxManifest.xml index 8d505f5..afd3877 100644 --- a/AppxManifest.xml +++ b/AppxManifest.xml @@ -5,7 +5,7 @@ Minesweeper-rs robmi - Assets\StoreLogo.png + assets\StoreLogo.png @@ -16,9 +16,9 @@ - - - + + + diff --git a/Assets/LockScreenLogo.png b/assets/LockScreenLogo.png similarity index 100% rename from Assets/LockScreenLogo.png rename to assets/LockScreenLogo.png diff --git a/Assets/SplashScreen.png b/assets/SplashScreen.png similarity index 100% rename from Assets/SplashScreen.png rename to assets/SplashScreen.png diff --git a/Assets/Square150x150Logo.png b/assets/Square150x150Logo.png similarity index 100% rename from Assets/Square150x150Logo.png rename to assets/Square150x150Logo.png diff --git a/Assets/Square44x44Logo.png b/assets/Square44x44Logo.png similarity index 100% rename from Assets/Square44x44Logo.png rename to assets/Square44x44Logo.png diff --git a/Assets/StoreLogo.png b/assets/StoreLogo.png similarity index 100% rename from Assets/StoreLogo.png rename to assets/StoreLogo.png diff --git a/Assets/Wide310x150Logo.png b/assets/Wide310x150Logo.png similarity index 100% rename from Assets/Wide310x150Logo.png rename to assets/Wide310x150Logo.png diff --git a/src/main.rs b/src/main.rs index f77340e..260b4cc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,17 +14,6 @@ use desktop::run; #[cfg(target_vendor = "uwp")] use uwp::run; -// TODO: Validate that this works -#[cfg(target_vendor = "uwp")] -fn test() { - println!("UWP"); -} - -#[cfg(target_vendor = "pc")] -fn test() { - println!("Win32") -} - fn main() { let result = run(); @@ -33,17 +22,3 @@ fn main() { error.code().unwrap(); } } - - -#[no_mangle] -extern "system" fn wWinMain( - _h_instance: *const i32, - _h_prev_instance: *const i32, - _cmd_line: *const u16, - _n_cmd_show: i32, -) -> i32 { - match run() { - Ok(()) => 0, - Err(e) => e.code().0 as i32, - } -} \ No newline at end of file From bc96f911699e89e6286ee2f7187fb258d6d488f5 Mon Sep 17 00:00:00 2001 From: Robert Mikhayelyan Date: Sun, 26 Jul 2020 20:30:28 -0700 Subject: [PATCH 07/20] fully working uwp --- src/uwp/app.rs | 69 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 12 deletions(-) diff --git a/src/uwp/app.rs b/src/uwp/app.rs index e47e74a..ff65477 100644 --- a/src/uwp/app.rs +++ b/src/uwp/app.rs @@ -4,6 +4,7 @@ use bindings::{ CoreApplication, CoreApplicationView, IFrameworkViewSource, IFrameworkView, abi_IFrameworkViewSource, abi_IFrameworkView, }, + foundation::TypedEventHandler, foundation::numerics::Vector2, ui::Colors, ui::core::{ @@ -15,9 +16,7 @@ use bindings::{ } } }; -use std::rc::Rc; -use winrt::AbiTransferable; -use winrt_guid::winrt_guid; +use std::sync::{Arc, Mutex}; use crate::uwp::app_adapter::UwpApp; use crate::minesweeper::Minesweeper; @@ -30,13 +29,13 @@ struct AppState { } pub struct MinesweeperApp { - state: Option + state: Arc>> } impl MinesweeperApp { pub fn new() -> Self { Self { - state: None, + state: Arc::new(Mutex::new(None)), } } } @@ -66,20 +65,66 @@ impl UwpApp for MinesweeperApp { // Init minesweeper let window_size = get_window_size(&window)?; - let mut game = Minesweeper::new(&root, &window_size)?; - - // TODO: Hook events + let game = Minesweeper::new(&root, &window_size)?; + // Initialize our internal state let state = AppState { - window, + window: window.clone(), compositor, target, game, }; - self.state = Some(state); - - let window = &self.state.as_ref().unwrap().window; + self.state.lock().unwrap().replace(state); + + // Hook events + type SizeChangedHandler = TypedEventHandler; + type PointerMovedHandler = TypedEventHandler; + type PointerPressedHandler = TypedEventHandler; + + let size_changed_handler = SizeChangedHandler::new({ + let mut state = self.state.clone(); + move |sender, args| { + let size = args.size()?; + let size = Vector2{ x: size.width as f32, y: size.height as f32 }; + let mut state = state.lock().unwrap(); + let state = state.as_mut().unwrap(); + let game = &mut state.game; + game.on_parent_size_changed(&size)?; + Ok(()) + } + }); + let pointer_moved_handler = PointerMovedHandler::new({ + let mut state = self.state.clone(); + move |sender, args| { + let point = args.current_point()?.position()?; + let point = Vector2{ x: point.x as f32, y: point.y as f32 }; + let mut state = state.lock().unwrap(); + let state = state.as_mut().unwrap(); + let game = &mut state.game; + game.on_pointer_moved(&point)?; + Ok(()) + } + }); + let pointer_pressed_handler = PointerPressedHandler::new({ + let mut state = self.state.clone(); + move |sender, args| { + let properties = args.current_point()?.properties()?; + let is_right = properties.is_right_button_pressed()?; + let is_eraser = properties.is_eraser()?; + let mut state = state.lock().unwrap(); + let state = state.as_mut().unwrap(); + let game = &mut state.game; + game.on_pointer_pressed(is_right, is_eraser)?; + Ok(()) + } + }); + + window.size_changed(size_changed_handler)?; + window.pointer_moved(pointer_moved_handler)?; + window.pointer_pressed(pointer_pressed_handler)?; + + // Activate the window and start running the dispatcher window.activate()?; let dispatcher = window.dispatcher()?; From 31c691bae4d33540061992aa774141d7fc6fa22a Mon Sep 17 00:00:00 2001 From: Robert Mikhayelyan Date: Sun, 26 Jul 2020 20:41:37 -0700 Subject: [PATCH 08/20] update readme --- README.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/README.md b/README.md index 8ac2469..7a926a3 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,41 @@ A port of [robmikh/Minesweeper](https://github.com/robmikh/Minesweeper) using [w ## Running Running this sample requires at least Windows build 1803 (v10.0.17134.0). To compile and run, use [cargo](https://www.rust-lang.org/learn/get-started): +### Desktop +Running the sample as a normal desktop application can be done as follows: ``` cargo run --release ``` +### UWP +Running the sample as a UWP application can be done by building for a `*-uwp-windows-msvc` target and then registering the app. NOTE: AppManifest.xml currently assumes `x86_64-uwp-windows-msvc` but can be updated. +``` +cargo +local build --target x86_64-uwp-windows-msvc +Add-AppxPackage -Register AppxManifest.xml +``` + +Then launch Minesweeper-rs from the Start Menu. + ![minesweeper-opt2](https://user-images.githubusercontent.com/7089228/80656536-45ac2c80-8a36-11ea-8521-ab40fc922ce1.gif) + + +#### Building the `*-uwp-windows-msvc` toolchain +Clone the [rust](https://github.com/rust-lang/rust) repo. You'll need to setup a `config.toml` file by copying the existing `config.toml.example` file and editing it: + +``` +# In addition to all host triples, other triples to produce the standard library +# for. Each host triple will be used to produce a copy of the standard library +# for each target triple. +# +# Defaults to just the build triple +target = ["x86_64-uwp-windows-msvc"] +``` + +Then follow the instructions on the README to build and then add the toolchain: + +``` +python x.py build +rustup toolchain link local build\x86_64-pc-windows-msvc\stage2 +``` + +You'll also need to copy an existing copy of `rustfmt.ext` into `build\x86_64-pc-windows-msvc\stage2\bin`. If you hit compilation issues, make sure you're using Visual Studio 2019 (not preview!). \ No newline at end of file From 946a74c26cfe13f8bd6d42f422619dc07dca3d1c Mon Sep 17 00:00:00 2001 From: Robert Mikhayelyan Date: Sun, 26 Jul 2020 20:45:27 -0700 Subject: [PATCH 09/20] disclaimer in readme about uwp code quality --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 7a926a3..a562d8c 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ cargo run --release ``` ### UWP +**The current IFrameworkView/IFrameworkViewSource implementation is incredibly hacky. It probably leaks. The current state is for research only.** + Running the sample as a UWP application can be done by building for a `*-uwp-windows-msvc` target and then registering the app. NOTE: AppManifest.xml currently assumes `x86_64-uwp-windows-msvc` but can be updated. ``` cargo +local build --target x86_64-uwp-windows-msvc From 264dd2c59774be44df3eefe87a35f7fa2863259b Mon Sep 17 00:00:00 2001 From: Robert Mikhayelyan Date: Mon, 27 Jul 2020 00:42:44 -0700 Subject: [PATCH 10/20] use com-rs --- Cargo.lock | 32 +++ Cargo.toml | 1 + src/desktop/mod.rs | 2 +- src/desktop/run.rs | 6 +- src/main.rs | 6 +- src/uwp/app.rs | 73 +++--- src/uwp/app_adapter.rs | 578 +++++++---------------------------------- src/uwp/interop.rs | 3 +- src/uwp/mod.rs | 6 +- src/uwp/run.rs | 20 +- 10 files changed, 177 insertions(+), 550 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 94b8168..ac40811 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -107,6 +107,37 @@ dependencies = [ "objc", ] +[[package]] +name = "com" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a30a2b2a013da986dc5cc3eda3d19c0d59d53f835be1b2356eb8d00f000c793" +dependencies = [ + "com_macros", +] + +[[package]] +name = "com_macros" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7606b05842fea68ddcc89e8053b8860ebcb2a0ba8d6abfe3a148e5d5a8d3f0c1" +dependencies = [ + "com_macros_support", + "proc-macro2 1.0.18", + "syn", +] + +[[package]] +name = "com_macros_support" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97e9a6d20f4ac8830e309a455d7e9416e65c6af5a97c88c55fbb4c2012e107da" +dependencies = [ + "proc-macro2 1.0.18", + "quote 1.0.7", + "syn", +] + [[package]] name = "core-foundation" version = "0.7.0" @@ -343,6 +374,7 @@ name = "minesweeper-rs" version = "0.1.0" dependencies = [ "bindings", + "com", "rand", "raw-window-handle", "winit", diff --git a/Cargo.toml b/Cargo.toml index f37c803..d6af07e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ winrt = "0.7.1" rand = "0.7.3" bindings = { path = "bindings" } winrt_guid = { path = "winrt_guid" } +com = "0.2.0" [target.'cfg(target_vendor = "pc")'.dependencies] winit = "0.22.2" diff --git a/src/desktop/mod.rs b/src/desktop/mod.rs index ebafa84..f90c95e 100644 --- a/src/desktop/mod.rs +++ b/src/desktop/mod.rs @@ -2,4 +2,4 @@ pub mod interop; mod run; pub mod window_target; -pub use run::run; \ No newline at end of file +pub use run::run; diff --git a/src/desktop/run.rs b/src/desktop/run.rs index d7668af..d50f85e 100644 --- a/src/desktop/run.rs +++ b/src/desktop/run.rs @@ -1,7 +1,7 @@ use crate::desktop::interop::create_dispatcher_queue_controller_for_current_thread; -use crate::uwp::interop::{ro_initialize, RoInitType}; -use crate::minesweeper::Minesweeper; use crate::desktop::window_target::CompositionDesktopWindowTargetSource; +use crate::minesweeper::Minesweeper; +use crate::uwp::interop::{ro_initialize, RoInitType}; use winit::{ event::{ElementState, Event, MouseButton, WindowEvent}, event_loop::{ControlFlow, EventLoop}, @@ -71,4 +71,4 @@ pub fn run() -> winrt::Result<()> { _ => (), } }); -} \ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs index 260b4cc..01fa234 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,12 +2,12 @@ mod comp_assets; mod comp_ui; +#[cfg(target_vendor = "pc")] +mod desktop; mod minesweeper; mod numerics; -mod visual_grid; mod uwp; -#[cfg(target_vendor = "pc")] -mod desktop; +mod visual_grid; #[cfg(target_vendor = "pc")] use desktop::run; diff --git a/src/uwp/app.rs b/src/uwp/app.rs index ff65477..46a4e8a 100644 --- a/src/uwp/app.rs +++ b/src/uwp/app.rs @@ -1,35 +1,24 @@ -use bindings::{ - windows::{ - application_model::core::{ - CoreApplication, CoreApplicationView, IFrameworkViewSource, IFrameworkView, - abi_IFrameworkViewSource, abi_IFrameworkView, - }, - foundation::TypedEventHandler, - foundation::numerics::Vector2, - ui::Colors, - ui::core::{ - CoreDispatcher, CoreWindow, CoreProcessEventsOption, WindowSizeChangedEventArgs, - PointerEventArgs - }, - ui::composition::{ - Compositor, CompositionTarget - } - } +use crate::minesweeper::Minesweeper; +use crate::uwp::app_adapter::UwpApp; +use bindings::windows::{ + application_model::core::CoreApplicationView, + foundation::numerics::Vector2, + foundation::TypedEventHandler, + ui::composition::{CompositionTarget, Compositor}, + ui::core::{CoreProcessEventsOption, CoreWindow, PointerEventArgs, WindowSizeChangedEventArgs}, }; use std::sync::{Arc, Mutex}; -use crate::uwp::app_adapter::UwpApp; -use crate::minesweeper::Minesweeper; struct AppState { - window: CoreWindow, - compositor: Compositor, - target: CompositionTarget, + _window: CoreWindow, + _compositor: Compositor, + _target: CompositionTarget, game: Minesweeper, } pub struct MinesweeperApp { - state: Arc>> + state: Arc>>, } impl MinesweeperApp { @@ -41,15 +30,15 @@ impl MinesweeperApp { } impl UwpApp for MinesweeperApp { - fn initialize(&mut self, window: &CoreApplicationView) -> winrt::Result<()> { + fn initialize(&mut self, _window: &CoreApplicationView) -> winrt::Result<()> { Ok(()) } - fn set_window(&mut self, window: &CoreWindow) -> winrt::Result<()> { + fn set_window(&mut self, _window: &CoreWindow) -> winrt::Result<()> { Ok(()) } - fn load(&mut self, entry_point: &winrt::HString) -> winrt::Result<()> { + fn load(&mut self, _entry_point: &winrt::HString) -> winrt::Result<()> { Ok(()) } @@ -59,7 +48,7 @@ impl UwpApp for MinesweeperApp { // Init Composition let compositor = Compositor::new()?; let root = compositor.create_container_visual()?; - root.set_relative_size_adjustment(Vector2 { x:1.0, y:1.0 })?; + root.set_relative_size_adjustment(Vector2 { x: 1.0, y: 1.0 })?; let target = compositor.create_target_for_current_view()?; target.set_root(&root)?; @@ -69,9 +58,9 @@ impl UwpApp for MinesweeperApp { // Initialize our internal state let state = AppState { - window: window.clone(), - compositor, - target, + _window: window.clone(), + _compositor: compositor, + _target: target, game, }; @@ -83,10 +72,13 @@ impl UwpApp for MinesweeperApp { type PointerPressedHandler = TypedEventHandler; let size_changed_handler = SizeChangedHandler::new({ - let mut state = self.state.clone(); - move |sender, args| { + let state = self.state.clone(); + move |_sender, args| { let size = args.size()?; - let size = Vector2{ x: size.width as f32, y: size.height as f32 }; + let size = Vector2 { + x: size.width as f32, + y: size.height as f32, + }; let mut state = state.lock().unwrap(); let state = state.as_mut().unwrap(); let game = &mut state.game; @@ -95,10 +87,13 @@ impl UwpApp for MinesweeperApp { } }); let pointer_moved_handler = PointerMovedHandler::new({ - let mut state = self.state.clone(); - move |sender, args| { + let state = self.state.clone(); + move |_sender, args| { let point = args.current_point()?.position()?; - let point = Vector2{ x: point.x as f32, y: point.y as f32 }; + let point = Vector2 { + x: point.x as f32, + y: point.y as f32, + }; let mut state = state.lock().unwrap(); let state = state.as_mut().unwrap(); let game = &mut state.game; @@ -107,8 +102,8 @@ impl UwpApp for MinesweeperApp { } }); let pointer_pressed_handler = PointerPressedHandler::new({ - let mut state = self.state.clone(); - move |sender, args| { + let state = self.state.clone(); + move |_sender, args| { let properties = args.current_point()?.properties()?; let is_right = properties.is_right_button_pressed()?; let is_eraser = properties.is_eraser()?; @@ -144,4 +139,4 @@ fn get_window_size(window: &CoreWindow) -> winrt::Result { x: bounds.width as f32, y: bounds.height as f32, }) -} \ No newline at end of file +} diff --git a/src/uwp/app_adapter.rs b/src/uwp/app_adapter.rs index 2d00813..ab57723 100644 --- a/src/uwp/app_adapter.rs +++ b/src/uwp/app_adapter.rs @@ -1,120 +1,11 @@ -use bindings::{ - windows::{ - application_model::core::{ - CoreApplication, CoreApplicationView, IFrameworkViewSource, IFrameworkView, - abi_IFrameworkViewSource, abi_IFrameworkView, - }, - foundation::numerics::Vector2, - ui::Colors, - ui::core::{ - CoreDispatcher, CoreWindow, CoreProcessEventsOption, WindowSizeChangedEventArgs, - PointerEventArgs - }, - ui::composition::{ - Compositor, CompositionTarget - } - } +use bindings::windows::{ + application_model::core::{CoreApplicationView, IFrameworkView, IFrameworkViewSource}, + ui::core::CoreWindow, }; -use std::rc::Rc; +use com::{co_class, com_interface, interfaces::iunknown::IUnknown, sys::HRESULT}; +use std::cell::RefCell; use winrt::AbiTransferable; -use winrt_guid::winrt_guid; - -#[repr(C)] -pub struct abi_IUnknown { - pub unknown_query_interface: - unsafe extern "system" fn(winrt::NonNullRawComPtr, &winrt::Guid, *mut winrt::RawPtr) -> winrt::ErrorCode, - pub unknown_add_ref: extern "system" fn(winrt::NonNullRawComPtr) -> u32, - pub unknown_release: extern "system" fn(winrt::NonNullRawComPtr) -> u32, -} - -#[repr(C)] -pub struct abi_IInspectable { - iunknown: abi_IUnknown, - - pub inspectable_iids: - unsafe extern "system" fn(winrt::NonNullRawComPtr, *mut u32, *mut *mut winrt::Guid) -> winrt::ErrorCode, - pub inspectable_type_name: unsafe extern "system" fn( - winrt::NonNullRawComPtr, - *mut ::Abi, - ) -> winrt::ErrorCode, - pub inspectable_trust_level: - unsafe extern "system" fn(winrt::NonNullRawComPtr, *mut i32) -> winrt::ErrorCode, -} - -#[derive(Default, Clone, PartialEq)] -#[repr(transparent)] -pub struct App { - ptr: winrt::ComPtr, -} - -impl App { - pub fn new(app_inner: Box) -> winrt::Result { - unsafe { - let raw = AppRc::new(app_inner); - - let mut result: App = std::mem::zeroed(); - let mut ptr: std::ptr::NonNull = std::ptr::NonNull::new_unchecked(raw.as_ref().unwrap().get_app_abi() as _); - *::set_abi(&mut result) = - Some(winrt::NonNullRawComPtr::new(ptr.cast())); - - Ok(result) - } - } -} - -unsafe impl winrt::ComInterface for App { - type VTable = abi_IApp; - fn iid() -> winrt::Guid { - winrt_guid!(DF36D812-3CF5-4B3D-BFA6-AC1A74F3C5C0) - } -} - -unsafe impl winrt::AbiTransferable for App { - type Abi = winrt::RawComPtr; - fn get_abi(&self) -> Self::Abi { - as winrt::AbiTransferable>::get_abi(&self.ptr) - } - fn set_abi(&mut self) -> *mut Self::Abi { - as winrt::AbiTransferable>::set_abi(&mut self.ptr) - } -} - -#[repr(C)] -pub struct abi_IApp { - iinspectable: abi_IInspectable, -} - -#[repr(C)] -pub struct abi_IFrameworkView_Full { - iinspectable: abi_IInspectable, - pub initialize: unsafe extern "system" fn( - ::winrt::NonNullRawComPtr, - application_view: ::Abi, - ) -> ::winrt::ErrorCode, - pub set_window: unsafe extern "system" fn( - ::winrt::NonNullRawComPtr, - window: ::Abi, - ) -> ::winrt::ErrorCode, - pub load: unsafe extern "system" fn( - ::winrt::NonNullRawComPtr, - entry_point: ::Abi, - ) -> ::winrt::ErrorCode, - pub run: unsafe extern "system" fn( - ::winrt::NonNullRawComPtr, - ) -> ::winrt::ErrorCode, - pub uninitialize: unsafe extern "system" fn( - ::winrt::NonNullRawComPtr, - ) -> ::winrt::ErrorCode, -} - -#[repr(C)] -pub struct abi_IFrameworkViewSource_Full { - iinspectable: abi_IInspectable, - pub create_view: unsafe extern "system" fn( - ::winrt::NonNullRawComPtr, - result__: *mut ::Abi, - ) -> ::winrt::ErrorCode, -} +use winrt::TryInto; pub trait UwpApp { fn initialize(&mut self, window: &CoreApplicationView) -> winrt::Result<()>; @@ -124,416 +15,135 @@ pub trait UwpApp { fn uninitialize(&mut self) -> winrt::Result<()>; } -struct AppRc { - count: winrt::RefCount, - this: *mut AppRc, - app_abi: *mut impl_App, - view_abi: *mut impl_App_IFrameworkView, - view_source_abi: *mut impl_App_IFrameworkViewSource, - inner: Box, -} - -impl AppRc { - pub fn new(inner: Box) -> *mut Self { - let count = winrt::RefCount::new(); - unsafe { - let base = Self { - count, - this: std::ptr::null_mut::(), - app_abi: std::ptr::null_mut::(), - view_abi: std::ptr::null_mut::(), - view_source_abi: std::ptr::null_mut::(), - inner, - }; - let base = Box::into_raw(Box::new(base)); - - let app_abi = impl_App::from_base(base); - let view_abi = impl_App_IFrameworkView::from_base(base); - let view_source_abi = impl_App_IFrameworkViewSource::from_base(base); - - (*base).this = base; - (*base).app_abi = app_abi; - (*base).view_abi = view_abi; - (*base).view_source_abi = view_source_abi; - - base - } - } - - pub fn add_ref(&self) -> u32 { - self.count.add_ref() - } - - pub unsafe fn release(&self) -> u32 { - let remaining = self.count.release(); - if remaining == 0 { - Box::from_raw(self.this); - } - remaining - } - - pub fn get_inner(&mut self) -> &mut dyn UwpApp { - self.inner.as_mut() - } - - pub fn get_app_abi(&self) -> *mut impl_App { - self.app_abi - } - - pub fn get_view_abi(&self) -> *mut impl_App_IFrameworkView { - self.view_abi - } - - pub fn get_view_source_abi(&self) -> *mut impl_App_IFrameworkViewSource { - self.view_source_abi - } -} - -impl Drop for AppRc { - fn drop(&mut self) { - unsafe { - Box::from_raw(self.app_abi); - Box::from_raw(self.view_abi); - Box::from_raw(self.view_source_abi); - } - } +#[com_interface("AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90")] +pub trait IInspectable: IUnknown { + unsafe fn get_iids(&self, iid_count: *mut u32, iids: *mut *mut winrt::Guid) -> HRESULT; + unsafe fn get_runtime_class_name( + &self, + class_name: *mut ::Abi, + ) -> HRESULT; + unsafe fn get_trust_level(&self, trust_level: *mut i32) -> HRESULT; } -#[repr(C)] -struct impl_App_IFrameworkView { - vtable: *const abi_IFrameworkView_Full, - base: *mut AppRc, +#[com_interface("FAAB5CD0-8924-45AC-AD0F-A08FAE5D0324")] +pub trait IFrameworkViewImpl: IInspectable { + unsafe fn initialize( + &self, + application_view: ::Abi, + ) -> HRESULT; + unsafe fn set_window(&self, window: ::Abi) -> HRESULT; + unsafe fn load( + &self, + entry_point: ::Abi, + ) -> HRESULT; + unsafe fn run(&self) -> HRESULT; + unsafe fn uninitialize(&self) -> HRESULT; } -#[repr(C)] -struct impl_App_IFrameworkViewSource { - vtable: *const abi_IFrameworkViewSource_Full, - base: *mut AppRc, +#[com_interface("CD770614-65C4-426C-9494-34FC43554862")] +pub trait IFrameworkViewSourceImpl: IInspectable { + unsafe fn create_view( + &self, + result: *mut ::Abi, + ) -> HRESULT; } -#[repr(C)] -struct impl_App { - vtable: *const abi_IApp, - base: *mut AppRc, +#[co_class(implements(IInspectable, IFrameworkViewImpl, IFrameworkViewSourceImpl))] +pub struct AppView { + inner: RefCell>, } -impl impl_App { - const VTABLE: abi_IApp = abi_IApp { - iinspectable: abi_IInspectable { - iunknown: abi_IUnknown { - unknown_query_interface: impl_App::unknown_query_interface, - unknown_add_ref: impl_App::unknown_add_ref, - unknown_release: impl_App::unknown_release, - }, - inspectable_iids: impl_App::inspectable_iids, - inspectable_type_name: impl_App::inspectable_type_name, - inspectable_trust_level: impl_App::inspectable_trust_level, - }, - }; - - unsafe fn from_base(base: *mut AppRc) -> *mut Self { - Box::into_raw(Box::new(Self { - vtable: &Self::VTABLE, - base - })) - } - - extern "system" fn unknown_query_interface( - this: winrt::NonNullRawComPtr, - iid: &winrt::Guid, - interface: *mut winrt::RawPtr, - ) -> winrt::ErrorCode { - unsafe { - let this: *mut Self = this.as_raw() as _; - if iid == &::iid() - || iid == &::iid() - || iid == &::iid() - || iid == &::iid() - { - *interface = this as winrt::RawPtr; - (*this).base.as_ref().unwrap().add_ref(); - return winrt::ErrorCode(0); - } else if iid == &::iid() { - (*this).base.as_ref().unwrap().add_ref(); - let base = (*this).base; - *interface = (*base).get_view_abi() as winrt::RawPtr; - return winrt::ErrorCode(0); - } else if iid == &::iid() { - (*this).base.as_ref().unwrap().add_ref(); - let base = (*this).base; - *interface = (*base).get_view_source_abi() as winrt::RawPtr; - return winrt::ErrorCode(0); - } - *interface = std::ptr::null_mut(); - winrt::ErrorCode(0x80004002) - } +impl AppView { + pub(crate) fn new() -> Box { + panic!("Not supported!"); } - extern "system" fn unknown_add_ref(this: winrt::NonNullRawComPtr) -> u32 { - unsafe { - let this: *mut Self = this.as_raw() as _; - (*this).base.as_ref().unwrap().add_ref() - } - } - extern "system" fn unknown_release(this: winrt::NonNullRawComPtr) -> u32 { + + pub fn create_view_source(inner: Box) -> winrt::Result { + let app_view = Box::into_raw(AppView::allocate(RefCell::new(inner))); + let mut object = winrt::Object::default(); unsafe { - let this: *mut Self = this.as_raw() as _; - (*this).base.as_ref().unwrap().release() + *object.set_abi() = std::mem::transmute(app_view); } - } - extern "system" fn inspectable_iids( - _this: winrt::NonNullRawComPtr, - _iidcount: *mut u32, - _iids: *mut *mut winrt::Guid, - ) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) - } - extern "system" fn inspectable_type_name( - _this: winrt::NonNullRawComPtr, - _class_name: *mut ::Abi, - ) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) - } - extern "system" fn inspectable_trust_level( - _this: winrt::NonNullRawComPtr, - _trust_level: *mut i32, - ) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) + let view_source: IFrameworkViewSource = object.try_into()?; + std::mem::forget(object); + Ok(view_source) } } -impl impl_App_IFrameworkView { - const VTABLE: abi_IFrameworkView_Full = abi_IFrameworkView_Full { - iinspectable: abi_IInspectable { - iunknown: abi_IUnknown { - unknown_query_interface: impl_App_IFrameworkView::unknown_query_interface, - unknown_add_ref: impl_App_IFrameworkView::unknown_add_ref, - unknown_release: impl_App_IFrameworkView::unknown_release, - }, - inspectable_iids: impl_App_IFrameworkView::inspectable_iids, - inspectable_type_name: impl_App_IFrameworkView::inspectable_type_name, - inspectable_trust_level: impl_App_IFrameworkView::inspectable_trust_level, - }, - initialize: impl_App_IFrameworkView::initialize, - set_window: impl_App_IFrameworkView::set_window, - load: impl_App_IFrameworkView::load, - run: impl_App_IFrameworkView::run, - uninitialize: impl_App_IFrameworkView::uninitialize, - }; - - unsafe fn from_base(base: *mut AppRc) -> *mut Self { - Box::into_raw(Box::new(Self { - vtable: &Self::VTABLE, - base - })) - } - - extern "system" fn unknown_query_interface( - this: winrt::NonNullRawComPtr, - iid: &winrt::Guid, - interface: *mut winrt::RawPtr, - ) -> winrt::ErrorCode { - unsafe { - let this: *mut Self = this.as_raw() as _; - if iid == &::iid() - || iid == &::iid() - || iid == &::iid() - || iid == &::iid() - { - *interface = this as winrt::RawPtr; - (*this).base.as_ref().unwrap().add_ref(); - return winrt::ErrorCode(0); - } else if iid == &::iid() { - (*this).base.as_ref().unwrap().add_ref(); - let base = (*this).base; - *interface = (*base).get_app_abi() as winrt::RawPtr; - return winrt::ErrorCode(0); - } else if iid == &::iid() { - (*this).base.as_ref().unwrap().add_ref(); - let base = (*this).base; - *interface = (*base).get_view_source_abi() as winrt::RawPtr; - return winrt::ErrorCode(0); - } - *interface = std::ptr::null_mut(); - winrt::ErrorCode(0x80004002) - } +impl IInspectable for AppView { + unsafe fn get_iids(&self, _iid_count: *mut u32, _iids: *mut *mut winrt::Guid) -> HRESULT { + 0x80004001 as u32 as _ } - extern "system" fn unknown_add_ref(this: winrt::NonNullRawComPtr) -> u32 { - unsafe { - let this: *mut Self = this.as_raw() as _; - (*this).base.as_ref().unwrap().add_ref() - } - } - extern "system" fn unknown_release(this: winrt::NonNullRawComPtr) -> u32 { - unsafe { - let this: *mut Self = this.as_raw() as _; - (*this).base.as_ref().unwrap().release() - } - } - extern "system" fn inspectable_iids( - _this: winrt::NonNullRawComPtr, - _iidcount: *mut u32, - _iids: *mut *mut winrt::Guid, - ) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) - } - extern "system" fn inspectable_type_name( - _this: winrt::NonNullRawComPtr, + unsafe fn get_runtime_class_name( + &self, _class_name: *mut ::Abi, - ) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) + ) -> HRESULT { + 0x80004001 as u32 as _ } - extern "system" fn inspectable_trust_level( - _this: winrt::NonNullRawComPtr, - _trust_level: *mut i32, - ) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) + unsafe fn get_trust_level(&self, _trust_level: *mut i32) -> HRESULT { + 0x80004001 as u32 as _ } - unsafe extern "system" fn initialize( - this: winrt::NonNullRawComPtr, +} + +impl IFrameworkViewImpl for AppView { + unsafe fn initialize( + &self, application_view: ::Abi, - ) -> ::winrt::ErrorCode { - let this: *mut Self = this.as_raw() as _; - let base = (*this).base.as_mut().unwrap(); + ) -> HRESULT { let application_view = CoreApplicationView::from_abi(&application_view); - let result = base.get_inner() + let result = self + .inner + .borrow_mut() .initialize(&application_view) .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)); std::mem::forget(application_view); - result + result.0 as HRESULT } - unsafe extern "system" fn set_window( - this: ::winrt::NonNullRawComPtr, - window: ::Abi, - ) -> ::winrt::ErrorCode { - let this: *mut Self = this.as_raw() as _; + unsafe fn set_window(&self, window: ::Abi) -> HRESULT { let window = CoreWindow::from_abi(&window); - let result = (*this).base.as_mut().unwrap().get_inner() + let result = self + .inner + .borrow_mut() .set_window(&window) .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)); std::mem::forget(window); - result + result.0 as HRESULT } - unsafe extern "system" fn load( - this: ::winrt::NonNullRawComPtr, + unsafe fn load( + &self, entry_point: ::Abi, - ) -> ::winrt::ErrorCode { - let this: *mut Self = this.as_raw() as _; + ) -> HRESULT { let entry_point = winrt::HString::from_abi(&entry_point); - let result = (*this).base.as_mut().unwrap().get_inner() + let result = self + .inner + .borrow_mut() .load(&entry_point) .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)); std::mem::forget(entry_point); - result + result.0 as HRESULT } - unsafe extern "system" fn run( - this: ::winrt::NonNullRawComPtr, - ) -> ::winrt::ErrorCode { - let this: *mut Self = this.as_raw() as _; - (*this).base.as_mut().unwrap().get_inner() + unsafe fn run(&self) -> HRESULT { + self.inner + .borrow_mut() .run() .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)) + .0 as HRESULT } - unsafe extern "system" fn uninitialize( - this: ::winrt::NonNullRawComPtr, - ) -> ::winrt::ErrorCode { - let this: *mut Self = this.as_raw() as _; - (*this).base.as_mut().unwrap().get_inner() + unsafe fn uninitialize(&self) -> HRESULT { + self.inner + .borrow_mut() .uninitialize() .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)) + .0 as HRESULT } } -impl impl_App_IFrameworkViewSource { - const VTABLE: abi_IFrameworkViewSource_Full = abi_IFrameworkViewSource_Full { - iinspectable: abi_IInspectable { - iunknown: abi_IUnknown { - unknown_query_interface: impl_App_IFrameworkViewSource::unknown_query_interface, - unknown_add_ref: impl_App_IFrameworkViewSource::unknown_add_ref, - unknown_release: impl_App_IFrameworkViewSource::unknown_release, - }, - inspectable_iids: impl_App_IFrameworkViewSource::inspectable_iids, - inspectable_type_name: impl_App_IFrameworkViewSource::inspectable_type_name, - inspectable_trust_level: impl_App_IFrameworkViewSource::inspectable_trust_level, - }, - create_view: impl_App_IFrameworkViewSource::create_view, - }; - - unsafe fn from_base(base: *mut AppRc) -> *mut Self { - Box::into_raw(Box::new(Self { - vtable: &Self::VTABLE, - base - })) - } - - extern "system" fn unknown_query_interface( - this: winrt::NonNullRawComPtr, - iid: &winrt::Guid, - interface: *mut winrt::RawPtr, - ) -> winrt::ErrorCode { - unsafe { - let this: *mut Self = this.as_raw() as _; - if iid == &::iid() - || iid == &::iid() - || iid == &::iid() - || iid == &::iid() - { - *interface = this as winrt::RawPtr; - (*this).base.as_ref().unwrap().add_ref(); - return winrt::ErrorCode(0); - } else if iid == &::iid() { - (*this).base.as_ref().unwrap().add_ref(); - let base = (*this).base; - *interface = (*base).get_view_abi() as winrt::RawPtr; - return winrt::ErrorCode(0); - } else if iid == &::iid() { - (*this).base.as_ref().unwrap().add_ref(); - let base = (*this).base; - *interface = (*base).get_app_abi() as winrt::RawPtr; - return winrt::ErrorCode(0); - } - *interface = std::ptr::null_mut(); - winrt::ErrorCode(0x80004002) - } +impl IFrameworkViewSourceImpl for AppView { + unsafe fn create_view( + &self, + result: *mut ::Abi, + ) -> HRESULT { + let guid = &::iid(); + self.query_interface(std::mem::transmute(guid), result as _) } - extern "system" fn unknown_add_ref(this: winrt::NonNullRawComPtr) -> u32 { - unsafe { - let this: *mut Self = this.as_raw() as _; - (*this).base.as_ref().unwrap().add_ref() - } - } - extern "system" fn unknown_release(this: winrt::NonNullRawComPtr) -> u32 { - unsafe { - let this: *mut Self = this.as_raw() as _; - (*this).base.as_ref().unwrap().release() - } - } - extern "system" fn inspectable_iids( - _this: winrt::NonNullRawComPtr, - _iidcount: *mut u32, - _iids: *mut *mut winrt::Guid, - ) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) - } - extern "system" fn inspectable_type_name( - _this: winrt::NonNullRawComPtr, - _class_name: *mut ::Abi, - ) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) - } - extern "system" fn inspectable_trust_level( - _this: winrt::NonNullRawComPtr, - _trust_level: *mut i32, - ) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) - } - unsafe extern "system" fn create_view( - this: ::winrt::NonNullRawComPtr, - result__: *mut ::Abi, - ) -> ::winrt::ErrorCode { - let this: *mut Self = this.as_raw() as _; - (*this).base.as_ref().unwrap().add_ref(); - let base = (*this).base; - *result__ = std::mem::transmute((*base).get_view_abi()); - winrt::ErrorCode(0) - } -} \ No newline at end of file +} diff --git a/src/uwp/interop.rs b/src/uwp/interop.rs index 1f07149..61f7b39 100644 --- a/src/uwp/interop.rs +++ b/src/uwp/interop.rs @@ -10,6 +10,7 @@ pub enum RoInitType { SingleThreaded = 1, } +#[allow(dead_code)] pub fn ro_initialize(init_type: RoInitType) -> winrt::Result<()> { unsafe { RoInitialize(init_type).ok() } -} \ No newline at end of file +} diff --git a/src/uwp/mod.rs b/src/uwp/mod.rs index 8317436..4dc2360 100644 --- a/src/uwp/mod.rs +++ b/src/uwp/mod.rs @@ -1,6 +1,6 @@ -pub mod interop; -mod run; mod app; mod app_adapter; +pub mod interop; +mod run; -pub use run::run; \ No newline at end of file +pub use run::run; diff --git a/src/uwp/run.rs b/src/uwp/run.rs index 94246ca..3cded7e 100644 --- a/src/uwp/run.rs +++ b/src/uwp/run.rs @@ -1,21 +1,9 @@ -use bindings::{ - windows::{ - application_model::core::{ - CoreApplication, CoreApplicationView, IFrameworkViewSource, IFrameworkView, - }, - ui::core::{ - CoreDispatcher, CoreWindow, CoreProcessEventsOption, WindowSizeChangedEventArgs, - PointerEventArgs - } - } -}; -use winrt::TryInto; use crate::uwp::app::MinesweeperApp; -use crate::uwp::app_adapter::App; +use crate::uwp::app_adapter::AppView; +use bindings::windows::application_model::core::CoreApplication; pub fn run() -> winrt::Result<()> { - let app = App::new(Box::new(MinesweeperApp::new()))?; - let view_source: IFrameworkViewSource = app.try_into()?; + let view_source = AppView::create_view_source(Box::new(MinesweeperApp::new()))?; CoreApplication::run(&view_source)?; Ok(()) -} \ No newline at end of file +} From f6c2e03d9eac62c2d2d385c9cd037ebf4e3c3ec5 Mon Sep 17 00:00:00 2001 From: Robert Mikhayelyan Date: Mon, 27 Jul 2020 00:51:27 -0700 Subject: [PATCH 11/20] remove HRESULT usage --- src/uwp/app.rs | 1 + src/uwp/app_adapter.rs | 65 ++++++++++++++++++++++++------------------ 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/src/uwp/app.rs b/src/uwp/app.rs index 46a4e8a..a57385d 100644 --- a/src/uwp/app.rs +++ b/src/uwp/app.rs @@ -17,6 +17,7 @@ struct AppState { game: Minesweeper, } +// TOOD: A way to do this without the arc/mutex? pub struct MinesweeperApp { state: Arc>>, } diff --git a/src/uwp/app_adapter.rs b/src/uwp/app_adapter.rs index ab57723..4b36049 100644 --- a/src/uwp/app_adapter.rs +++ b/src/uwp/app_adapter.rs @@ -2,7 +2,7 @@ use bindings::windows::{ application_model::core::{CoreApplicationView, IFrameworkView, IFrameworkViewSource}, ui::core::CoreWindow, }; -use com::{co_class, com_interface, interfaces::iunknown::IUnknown, sys::HRESULT}; +use com::{co_class, com_interface, interfaces::iunknown::IUnknown}; use std::cell::RefCell; use winrt::AbiTransferable; use winrt::TryInto; @@ -17,12 +17,13 @@ pub trait UwpApp { #[com_interface("AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90")] pub trait IInspectable: IUnknown { - unsafe fn get_iids(&self, iid_count: *mut u32, iids: *mut *mut winrt::Guid) -> HRESULT; + unsafe fn get_iids(&self, iid_count: *mut u32, iids: *mut *mut winrt::Guid) + -> winrt::ErrorCode; unsafe fn get_runtime_class_name( &self, class_name: *mut ::Abi, - ) -> HRESULT; - unsafe fn get_trust_level(&self, trust_level: *mut i32) -> HRESULT; + ) -> winrt::ErrorCode; + unsafe fn get_trust_level(&self, trust_level: *mut i32) -> winrt::ErrorCode; } #[com_interface("FAAB5CD0-8924-45AC-AD0F-A08FAE5D0324")] @@ -30,14 +31,17 @@ pub trait IFrameworkViewImpl: IInspectable { unsafe fn initialize( &self, application_view: ::Abi, - ) -> HRESULT; - unsafe fn set_window(&self, window: ::Abi) -> HRESULT; + ) -> winrt::ErrorCode; + unsafe fn set_window( + &self, + window: ::Abi, + ) -> winrt::ErrorCode; unsafe fn load( &self, entry_point: ::Abi, - ) -> HRESULT; - unsafe fn run(&self) -> HRESULT; - unsafe fn uninitialize(&self) -> HRESULT; + ) -> winrt::ErrorCode; + unsafe fn run(&self) -> winrt::ErrorCode; + unsafe fn uninitialize(&self) -> winrt::ErrorCode; } #[com_interface("CD770614-65C4-426C-9494-34FC43554862")] @@ -45,7 +49,7 @@ pub trait IFrameworkViewSourceImpl: IInspectable { unsafe fn create_view( &self, result: *mut ::Abi, - ) -> HRESULT; + ) -> winrt::ErrorCode; } #[co_class(implements(IInspectable, IFrameworkViewImpl, IFrameworkViewSourceImpl))] @@ -71,17 +75,21 @@ impl AppView { } impl IInspectable for AppView { - unsafe fn get_iids(&self, _iid_count: *mut u32, _iids: *mut *mut winrt::Guid) -> HRESULT { - 0x80004001 as u32 as _ + unsafe fn get_iids( + &self, + _iid_count: *mut u32, + _iids: *mut *mut winrt::Guid, + ) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) } unsafe fn get_runtime_class_name( &self, _class_name: *mut ::Abi, - ) -> HRESULT { - 0x80004001 as u32 as _ + ) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) } - unsafe fn get_trust_level(&self, _trust_level: *mut i32) -> HRESULT { - 0x80004001 as u32 as _ + unsafe fn get_trust_level(&self, _trust_level: *mut i32) -> winrt::ErrorCode { + winrt::ErrorCode(0x80004001) } } @@ -89,7 +97,7 @@ impl IFrameworkViewImpl for AppView { unsafe fn initialize( &self, application_view: ::Abi, - ) -> HRESULT { + ) -> winrt::ErrorCode { let application_view = CoreApplicationView::from_abi(&application_view); let result = self .inner @@ -97,9 +105,12 @@ impl IFrameworkViewImpl for AppView { .initialize(&application_view) .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)); std::mem::forget(application_view); - result.0 as HRESULT + result } - unsafe fn set_window(&self, window: ::Abi) -> HRESULT { + unsafe fn set_window( + &self, + window: ::Abi, + ) -> winrt::ErrorCode { let window = CoreWindow::from_abi(&window); let result = self .inner @@ -107,12 +118,12 @@ impl IFrameworkViewImpl for AppView { .set_window(&window) .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)); std::mem::forget(window); - result.0 as HRESULT + result } unsafe fn load( &self, entry_point: ::Abi, - ) -> HRESULT { + ) -> winrt::ErrorCode { let entry_point = winrt::HString::from_abi(&entry_point); let result = self .inner @@ -120,21 +131,19 @@ impl IFrameworkViewImpl for AppView { .load(&entry_point) .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)); std::mem::forget(entry_point); - result.0 as HRESULT + result } - unsafe fn run(&self) -> HRESULT { + unsafe fn run(&self) -> winrt::ErrorCode { self.inner .borrow_mut() .run() .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)) - .0 as HRESULT } - unsafe fn uninitialize(&self) -> HRESULT { + unsafe fn uninitialize(&self) -> winrt::ErrorCode { self.inner .borrow_mut() .uninitialize() .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)) - .0 as HRESULT } } @@ -142,8 +151,8 @@ impl IFrameworkViewSourceImpl for AppView { unsafe fn create_view( &self, result: *mut ::Abi, - ) -> HRESULT { + ) -> winrt::ErrorCode { let guid = &::iid(); - self.query_interface(std::mem::transmute(guid), result as _) + winrt::ErrorCode(self.query_interface(std::mem::transmute(guid), result as _) as u32) } } From d30002ec15508d8afadc226cf920df82abb225d5 Mon Sep 17 00:00:00 2001 From: Robert Mikhayelyan Date: Mon, 27 Jul 2020 01:09:26 -0700 Subject: [PATCH 12/20] clean up --- AppxManifest.xml | 3 +- Cargo.lock | 5 --- Cargo.toml | 5 ++- src/desktop/interop.rs | 4 +- src/desktop/mod.rs | 4 +- src/desktop/run.rs | 2 +- src/{uwp => }/interop.rs | 0 src/main.rs | 9 +++-- src/uwp/mod.rs | 1 - winrt_guid/Cargo.toml | 8 ---- winrt_guid/src/guid.rs | 85 ---------------------------------------- winrt_guid/src/lib.rs | 35 ----------------- 12 files changed, 14 insertions(+), 147 deletions(-) rename src/{uwp => }/interop.rs (100%) delete mode 100644 winrt_guid/Cargo.toml delete mode 100644 winrt_guid/src/guid.rs delete mode 100644 winrt_guid/src/lib.rs diff --git a/AppxManifest.xml b/AppxManifest.xml index afd3877..af6e5dc 100644 --- a/AppxManifest.xml +++ b/AppxManifest.xml @@ -8,7 +8,7 @@ assets\StoreLogo.png - + @@ -23,6 +23,5 @@ - \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index ac40811..3fa52f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -379,7 +379,6 @@ dependencies = [ "raw-window-handle", "winit", "winrt", - "winrt_guid", ] [[package]] @@ -997,10 +996,6 @@ dependencies = [ "syn", ] -[[package]] -name = "winrt_guid" -version = "0.1.0" - [[package]] name = "winrt_macros" version = "0.7.1" diff --git a/Cargo.toml b/Cargo.toml index d6af07e..76d751e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,12 +8,13 @@ edition = "2018" winrt = "0.7.1" rand = "0.7.3" bindings = { path = "bindings" } -winrt_guid = { path = "winrt_guid" } -com = "0.2.0" [target.'cfg(target_vendor = "pc")'.dependencies] winit = "0.22.2" raw-window-handle = "0.3.3" +[target.'cfg(target_vendor = "uwp")'.dependencies] +com = "0.2.0" + [features] show-mines = [] diff --git a/src/desktop/interop.rs b/src/desktop/interop.rs index b8c5b0b..45cce15 100644 --- a/src/desktop/interop.rs +++ b/src/desktop/interop.rs @@ -2,7 +2,6 @@ use bindings::windows::{ system::DispatcherQueueController, ui::composition::desktop::DesktopWindowTarget, }; use winrt::AbiTransferable; -use winrt_guid::winrt_guid; #[repr(C)] pub struct abi_ICompositorDesktopInterop { @@ -19,8 +18,7 @@ unsafe impl winrt::ComInterface for CompositorDesktopInterop { type VTable = abi_ICompositorDesktopInterop; fn iid() -> winrt::Guid { - winrt_guid!(29E691FA-4567-4DCA-B319-D0F207EB6807) - //winrt::Guid::from_values(702976506, 17767, 19914, [179, 25, 208, 242, 7, 235, 104, 7]) + winrt::Guid::from_values(702976506, 17767, 19914, [179, 25, 208, 242, 7, 235, 104, 7]) } } diff --git a/src/desktop/mod.rs b/src/desktop/mod.rs index f90c95e..41837be 100644 --- a/src/desktop/mod.rs +++ b/src/desktop/mod.rs @@ -1,5 +1,5 @@ -pub mod interop; +mod interop; mod run; -pub mod window_target; +mod window_target; pub use run::run; diff --git a/src/desktop/run.rs b/src/desktop/run.rs index d50f85e..c7a08ee 100644 --- a/src/desktop/run.rs +++ b/src/desktop/run.rs @@ -1,7 +1,7 @@ use crate::desktop::interop::create_dispatcher_queue_controller_for_current_thread; use crate::desktop::window_target::CompositionDesktopWindowTargetSource; +use crate::interop::{ro_initialize, RoInitType}; use crate::minesweeper::Minesweeper; -use crate::uwp::interop::{ro_initialize, RoInitType}; use winit::{ event::{ElementState, Event, MouseButton, WindowEvent}, event_loop::{ControlFlow, EventLoop}, diff --git a/src/uwp/interop.rs b/src/interop.rs similarity index 100% rename from src/uwp/interop.rs rename to src/interop.rs diff --git a/src/main.rs b/src/main.rs index 01fa234..ce7e997 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,13 +2,16 @@ mod comp_assets; mod comp_ui; -#[cfg(target_vendor = "pc")] -mod desktop; +mod interop; mod minesweeper; mod numerics; -mod uwp; mod visual_grid; +#[cfg(target_vendor = "pc")] +mod desktop; +#[cfg(target_vendor = "uwp")] +mod uwp; + #[cfg(target_vendor = "pc")] use desktop::run; #[cfg(target_vendor = "uwp")] diff --git a/src/uwp/mod.rs b/src/uwp/mod.rs index 4dc2360..5531ca1 100644 --- a/src/uwp/mod.rs +++ b/src/uwp/mod.rs @@ -1,6 +1,5 @@ mod app; mod app_adapter; -pub mod interop; mod run; pub use run::run; diff --git a/winrt_guid/Cargo.toml b/winrt_guid/Cargo.toml deleted file mode 100644 index 1559b7a..0000000 --- a/winrt_guid/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "winrt_guid" -version = "0.1.0" -authors = ["Robert Mikhayelyan "] -edition = "2018" - -[lib] -proc-macro = true diff --git a/winrt_guid/src/guid.rs b/winrt_guid/src/guid.rs deleted file mode 100644 index 1fc7ff6..0000000 --- a/winrt_guid/src/guid.rs +++ /dev/null @@ -1,85 +0,0 @@ -// Taken from winrt-rs -// TODO: upstream? - -/// A globally unique identifier [(GUID)](https://docs.microsoft.com/en-us/dotnet/api/system.guid?view=netcore-3.1) -/// used to uniquely identify COM and WinRT interfaces. -#[repr(C)] -#[derive(Clone, Default, PartialEq)] -pub(crate) struct Guid { - pub data1: u32, - pub data2: u16, - pub data3: u16, - pub data4: [u8; 8], -} - -impl Guid { - /// Creates a `Guid` with the given constant values. - pub const fn from_values(data1: u32, data2: u16, data3: u16, data4: [u8; 8]) -> Guid { - Guid { - data1, - data2, - data3, - data4, - } - } -} - -impl From<&str> for Guid { - fn from(value: &str) -> Guid { - assert!(value.len() == 36, "Invalid GUID string"); - let mut bytes = value.bytes(); - - let a = ((bytes.next_u32() * 16 + bytes.next_u32()) << 24) - + ((bytes.next_u32() * 16 + bytes.next_u32()) << 16) - + ((bytes.next_u32() * 16 + bytes.next_u32()) << 8) - + bytes.next_u32() * 16 - + bytes.next_u32(); - assert!(bytes.next().unwrap() == b'-', "Invalid GUID string"); - let b = ((bytes.next_u16() * 16 + (bytes.next_u16())) << 8) - + bytes.next_u16() * 16 - + bytes.next_u16(); - assert!(bytes.next().unwrap() == b'-', "Invalid GUID string"); - let c = ((bytes.next_u16() * 16 + bytes.next_u16()) << 8) - + bytes.next_u16() * 16 - + bytes.next_u16(); - assert!(bytes.next().unwrap() == b'-', "Invalid GUID string"); - let d = bytes.next_u8() * 16 + bytes.next_u8(); - let e = bytes.next_u8() * 16 + bytes.next_u8(); - assert!(bytes.next().unwrap() == b'-', "Invalid GUID string"); - - let f = bytes.next_u8() * 16 + bytes.next_u8(); - let g = bytes.next_u8() * 16 + bytes.next_u8(); - let h = bytes.next_u8() * 16 + bytes.next_u8(); - let i = bytes.next_u8() * 16 + bytes.next_u8(); - let j = bytes.next_u8() * 16 + bytes.next_u8(); - let k = bytes.next_u8() * 16 + bytes.next_u8(); - - Guid::from_values(a, b, c, [d, e, f, g, h, i, j, k]) - } -} - -trait HexReader { - fn next_u8(&mut self) -> u8; - fn next_u16(&mut self) -> u16; - fn next_u32(&mut self) -> u32; -} - -impl HexReader for std::str::Bytes<'_> { - fn next_u8(&mut self) -> u8 { - let value = self.next().unwrap(); - match value { - b'0'..=b'9' => value - b'0', - b'A'..=b'F' => 10 + value - b'A', - b'a'..=b'f' => 10 + value - b'a', - _ => panic!("Invalid GUID string"), - } - } - - fn next_u16(&mut self) -> u16 { - self.next_u8().into() - } - - fn next_u32(&mut self) -> u32 { - self.next_u8().into() - } -} \ No newline at end of file diff --git a/winrt_guid/src/lib.rs b/winrt_guid/src/lib.rs deleted file mode 100644 index 311702e..0000000 --- a/winrt_guid/src/lib.rs +++ /dev/null @@ -1,35 +0,0 @@ -mod guid; - -use guid::Guid; -use proc_macro::{TokenStream, TokenTree}; - -#[proc_macro] -pub fn winrt_guid(input: TokenStream) -> TokenStream { - let input = { - let mut input_string = String::new(); - println!("{:#?}", input); - for part in input { - match part { - TokenTree::Literal(part) => input_string.push_str(&part.to_string()), - TokenTree::Ident(part) => input_string.push_str(&part.to_string()), - TokenTree::Punct(part) => input_string.push(part.as_char()), - _ => assert!(false, "Invalid GUID string"), - } - } - input_string - }; - let guid = Guid::from(input.as_str()); - let data4 = { - let mut data4 = String::new(); - data4.push_str("["); - for data in &guid.data4 { - data4.push_str(&format!("{}, ", data)); - } - data4.pop(); - data4.pop(); - data4.push_str("]"); - data4 - }; - let output = format!("winrt::Guid::from_values({}, {}, {}, {})", guid.data1, guid.data2, guid.data3, data4); - output.parse().unwrap() -} \ No newline at end of file From eb2336be4728cc68b2b8876252dc8ca2e26f2392 Mon Sep 17 00:00:00 2001 From: Robert Mikhayelyan Date: Mon, 27 Jul 2020 01:40:40 -0700 Subject: [PATCH 13/20] cleanup readme --- AppxManifest.xml | 2 +- README.md | 35 +++++++---------------------------- UWP.md | 31 +++++++++++++++++++++++++++++++ bindings/build.rs | 12 +++++++++--- 4 files changed, 48 insertions(+), 32 deletions(-) create mode 100644 UWP.md diff --git a/AppxManifest.xml b/AppxManifest.xml index af6e5dc..1b11d22 100644 --- a/AppxManifest.xml +++ b/AppxManifest.xml @@ -16,7 +16,7 @@ - + diff --git a/README.md b/README.md index a562d8c..fad9973 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,25 @@ # minesweeper-rs A port of [robmikh/Minesweeper](https://github.com/robmikh/Minesweeper) using [winrt-rs](https://github.com/microsoft/winrt-rs). -## Running +## Getting started Running this sample requires at least Windows build 1803 (v10.0.17134.0). To compile and run, use [cargo](https://www.rust-lang.org/learn/get-started): ### Desktop -Running the sample as a normal desktop application can be done as follows: +Running Minesweeper as a normal desktop application can be done as follows: + ``` cargo run --release ``` ### UWP -**The current IFrameworkView/IFrameworkViewSource implementation is incredibly hacky. It probably leaks. The current state is for research only.** -Running the sample as a UWP application can be done by building for a `*-uwp-windows-msvc` target and then registering the app. NOTE: AppManifest.xml currently assumes `x86_64-uwp-windows-msvc` but can be updated. +Running Minesweeper as a UWP application can be done by building for a `*-uwp-windows-msvc` target and then registering the app. Because the `*-uwp-windows-msvc` targets are currently tier 3, you'll need to compile a toolchain yourself. More information can be found [here](UWP.md). *NOTE: AppManifest.xml currently assumes the `x86_64-uwp-windows-msvc` target but can be updated.* + ``` cargo +local build --target x86_64-uwp-windows-msvc -Add-AppxPackage -Register AppxManifest.xml +(powershell.exe) Add-AppxPackage -Register AppxManifest.xml ``` -Then launch Minesweeper-rs from the Start Menu. +Then launch minesweeper-rs from the Start Menu. ![minesweeper-opt2](https://user-images.githubusercontent.com/7089228/80656536-45ac2c80-8a36-11ea-8521-ab40fc922ce1.gif) - - -#### Building the `*-uwp-windows-msvc` toolchain -Clone the [rust](https://github.com/rust-lang/rust) repo. You'll need to setup a `config.toml` file by copying the existing `config.toml.example` file and editing it: - -``` -# In addition to all host triples, other triples to produce the standard library -# for. Each host triple will be used to produce a copy of the standard library -# for each target triple. -# -# Defaults to just the build triple -target = ["x86_64-uwp-windows-msvc"] -``` - -Then follow the instructions on the README to build and then add the toolchain: - -``` -python x.py build -rustup toolchain link local build\x86_64-pc-windows-msvc\stage2 -``` - -You'll also need to copy an existing copy of `rustfmt.ext` into `build\x86_64-pc-windows-msvc\stage2\bin`. If you hit compilation issues, make sure you're using Visual Studio 2019 (not preview!). \ No newline at end of file diff --git a/UWP.md b/UWP.md new file mode 100644 index 0000000..00055ab --- /dev/null +++ b/UWP.md @@ -0,0 +1,31 @@ +# Building the `*-uwp-windows-msvc` toolchain +Clone the [rust](https://github.com/rust-lang/rust) repo. You'll need to setup a `config.toml` file by copying the existing `config.toml.example` file and editing it: + +``` +# In addition to all host triples, other triples to produce the standard library +# for. Each host triple will be used to produce a copy of the standard library +# for each target triple. +# +# Defaults to just the build triple +target = ["x86_64-uwp-windows-msvc"] +``` + +Then follow the instructions in the [README](https://github.com/rust-lang/rust/blob/master/README.md#msvc) to build the toolchain. Afterwards you can link your newly built toolchain to rustup for easier use. + +``` +python x.py build +rustup toolchain link local build\x86_64-pc-windows-msvc\stage2 +``` + +There's one last step. You'll need put a copy of `rustfmt.exe` into the `bin` directory for your toolchain. For example, I placed mine in `build\x86_64-pc-windows-msvc\stage2\bin`. + +Once you have everything in place, you'll be able to build using you're new toolchain: + +``` +cargo +local build --target x86_64-uwp-windows-msvc +(powershell.exe) Add-AppxPackage -Register AppxManifest.xml +``` + +## Troubleshooting + +In the event you're getting errors when compiling llvm, make sure you use a **non-preview** version of Visual Studio 2019. I believe there's a fix, but it wasn't present in the snapshot I built from (stable - [5c1f21c3b82](https://github.com/rust-lang/rust/tree/5c1f21c3b82297671ad3ae1e8c942d2ca92e84f2)). diff --git a/bindings/build.rs b/bindings/build.rs index 221198c..4a1a904 100644 --- a/bindings/build.rs +++ b/bindings/build.rs @@ -3,7 +3,10 @@ winrt::build!( os types windows::application_model::core::{ - CoreApplication, CoreApplicationView, IFrameworkViewSource, IFrameworkView, + CoreApplication, + CoreApplicationView, + IFrameworkViewSource, + IFrameworkView, } windows::foundation::numerics::{Vector2, Vector3} windows::foundation::TimeSpan @@ -25,8 +28,11 @@ winrt::build!( windows::ui::composition::desktop::DesktopWindowTarget windows::ui::Colors windows::ui::core::{ - CoreDispatcher, CoreWindow, CoreProcessEventsOption, WindowSizeChangedEventArgs, - PointerEventArgs + CoreDispatcher, + CoreWindow, + CoreProcessEventsOption, + WindowSizeChangedEventArgs, + PointerEventArgs, } ); From 1c7b169c0dc7cb51e51365ad4099858696624959 Mon Sep 17 00:00:00 2001 From: Robert Mikhayelyan Date: Mon, 27 Jul 2020 01:42:56 -0700 Subject: [PATCH 14/20] update readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fad9973..9f30233 100644 --- a/README.md +++ b/README.md @@ -13,12 +13,13 @@ cargo run --release ### UWP -Running Minesweeper as a UWP application can be done by building for a `*-uwp-windows-msvc` target and then registering the app. Because the `*-uwp-windows-msvc` targets are currently tier 3, you'll need to compile a toolchain yourself. More information can be found [here](UWP.md). *NOTE: AppManifest.xml currently assumes the `x86_64-uwp-windows-msvc` target but can be updated.* +Running Minesweeper as a UWP application can be done by building for a `*-uwp-windows-msvc` target and then registering the app. Because the `*-uwp-windows-msvc` targets are currently tier 3, you'll need to compile a toolchain yourself. More information can be found [here](UWP.md). ``` cargo +local build --target x86_64-uwp-windows-msvc (powershell.exe) Add-AppxPackage -Register AppxManifest.xml ``` +*NOTE: AppManifest.xml currently assumes the `x86_64-uwp-windows-msvc` target but can be updated.* Then launch minesweeper-rs from the Start Menu. From b003f85d4ad81a96c4924e70bab940f5efc00a88 Mon Sep 17 00:00:00 2001 From: robmikh Date: Tue, 24 Nov 2020 14:36:45 -0800 Subject: [PATCH 15/20] update to new winrt-rs --- Cargo.lock | 451 +++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 9 +- bindings/Cargo.lock | 372 --------------------------------- src/uwp/app.rs | 35 ++-- src/uwp/app_adapter.rs | 158 --------------- src/uwp/mod.rs | 1 - src/uwp/run.rs | 10 +- 7 files changed, 482 insertions(+), 554 deletions(-) delete mode 100644 bindings/Cargo.lock delete mode 100644 src/uwp/app_adapter.rs diff --git a/Cargo.lock b/Cargo.lock index e69de29..3875723 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -0,0 +1,451 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "anyhow" +version = "1.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7" + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "bindings" +version = "0.1.0" +dependencies = [ + "winrt", +] + +[[package]] +name = "cargo_toml" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513d17226888c7b8283ac02a1c1b0d8a9d4cbf6db65dfadb79f598f5d7966fe9" +dependencies = [ + "serde", + "serde_derive", + "toml", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "const-sha1" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb58b6451e8c2a812ad979ed1d83378caa5e927eef2622017a45f251457c2c9d" + +[[package]] +name = "const_fn" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c478836e029dcef17fb47c89023448c64f781a046e0300e257ad8225ae59afab" + +[[package]] +name = "crossbeam-channel" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0f606a85340376eef0d6d8fec399e6d4a544d648386c6645eb6d0653b27d9f" +dependencies = [ + "cfg-if 1.0.0", + "const_fn", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec91540d98355f690a86367e566ecad2e9e579f230230eb7c21398372be73ea5" +dependencies = [ + "autocfg", + "cfg-if 1.0.0", + "const_fn", + "lazy_static", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "getrandom" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "wasi", +] + +[[package]] +name = "hermit-abi" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" +dependencies = [ + "libc", +] + +[[package]] +name = "itoa" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" + +[[package]] +name = "memoffset" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" +dependencies = [ + "autocfg", +] + +[[package]] +name = "minesweeper-rs" +version = "0.1.0" +dependencies = [ + "bindings", + "rand", + "winrt", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "proc-macro2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rayon" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "serde" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" + +[[package]] +name = "serde_derive" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" + +[[package]] +name = "squote" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fccf17fd09e2455ea796d2ad267b64fa2c5cbd8701b2a93b555d2aa73449f7d" + +[[package]] +name = "syn" +version = "1.0.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b4f34193997d92804d359ed09953e25d5138df6bcc055a71bf68ee89fdf9223" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "thiserror" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "toml" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645" +dependencies = [ + "serde", +] + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "winmd" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b74dd1bf09feda89c3ab7456f413c89e4f964f3151a3c4f25a1ce439e11603" +dependencies = [ + "winmd-macros", +] + +[[package]] +name = "winmd-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44e088988554d1f9f4b79815c29d02daf95268c47389e54bfb3c0d5a4c587974" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "winrt" +version = "0.8.0" +source = "git+https://github.com/microsoft/winrt-rs#38b7bea9a17930e55145a2b577b956e8193521ad" +dependencies = [ + "const-sha1", + "winmd", + "winrt-macros", +] + +[[package]] +name = "winrt-deps" +version = "0.1.0" +source = "git+https://github.com/microsoft/winrt-rs#38b7bea9a17930e55145a2b577b956e8193521ad" +dependencies = [ + "anyhow", + "cargo_toml", + "serde_json", + "thiserror", +] + +[[package]] +name = "winrt-gen" +version = "0.8.0" +source = "git+https://github.com/microsoft/winrt-rs#38b7bea9a17930e55145a2b577b956e8193521ad" +dependencies = [ + "proc-macro2", + "quote", + "rayon", + "sha1", + "squote", + "syn", + "winmd", + "winrt-gen-macros", +] + +[[package]] +name = "winrt-gen-macros" +version = "0.8.0" +source = "git+https://github.com/microsoft/winrt-rs#38b7bea9a17930e55145a2b577b956e8193521ad" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "winrt-macros" +version = "0.8.0" +source = "git+https://github.com/microsoft/winrt-rs#38b7bea9a17930e55145a2b577b956e8193521ad" +dependencies = [ + "cargo_toml", + "proc-macro2", + "quote", + "rayon", + "serde_json", + "squote", + "syn", + "winmd", + "winrt-deps", + "winrt-gen", +] diff --git a/Cargo.toml b/Cargo.toml index 1ec7605..f9ab49a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,12 +9,9 @@ winrt = { git = "https://github.com/microsoft/winrt-rs" } rand = "0.7.3" bindings = { path = "bindings" } -[target.'cfg(target_vendor = "pc")'.dependencies] -winit = "0.22.2" -raw-window-handle = "0.3.3" - -[target.'cfg(target_vendor = "uwp")'.dependencies] -com = "0.2.0" +#[target.'cfg(target_vendor = "pc")'.dependencies] +#winit = "0.22.2" +#raw-window-handle = "0.3.3" [features] show-mines = [] diff --git a/bindings/Cargo.lock b/bindings/Cargo.lock deleted file mode 100644 index b8eaf73..0000000 --- a/bindings/Cargo.lock +++ /dev/null @@ -1,372 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "anyhow" -version = "1.0.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7" - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "bindings" -version = "0.1.0" -dependencies = [ - "winrt", -] - -[[package]] -name = "cargo_toml" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "513d17226888c7b8283ac02a1c1b0d8a9d4cbf6db65dfadb79f598f5d7966fe9" -dependencies = [ - "serde", - "serde_derive", - "toml", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "const-sha1" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb58b6451e8c2a812ad979ed1d83378caa5e927eef2622017a45f251457c2c9d" - -[[package]] -name = "const_fn" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c478836e029dcef17fb47c89023448c64f781a046e0300e257ad8225ae59afab" - -[[package]] -name = "crossbeam-channel" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0f606a85340376eef0d6d8fec399e6d4a544d648386c6645eb6d0653b27d9f" -dependencies = [ - "cfg-if", - "const_fn", - "crossbeam-utils", - "lazy_static", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec91540d98355f690a86367e566ecad2e9e579f230230eb7c21398372be73ea5" -dependencies = [ - "autocfg", - "cfg-if", - "const_fn", - "lazy_static", -] - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "hermit-abi" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" -dependencies = [ - "libc", -] - -[[package]] -name = "itoa" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" - -[[package]] -name = "memoffset" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "proc-macro2" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quote" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rayon" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" -dependencies = [ - "autocfg", - "crossbeam-deque", - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "lazy_static", - "num_cpus", -] - -[[package]] -name = "ryu" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "serde" -version = "1.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" - -[[package]] -name = "serde_derive" -version = "1.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.53" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993948e75b189211a9b31a7528f950c6adc21f9720b6438ff80a7fa2f864cea2" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha1" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" - -[[package]] -name = "squote" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fccf17fd09e2455ea796d2ad267b64fa2c5cbd8701b2a93b555d2aa73449f7d" - -[[package]] -name = "syn" -version = "1.0.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "thiserror" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "toml" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645" -dependencies = [ - "serde", -] - -[[package]] -name = "unicode-xid" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" - -[[package]] -name = "winmd" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463cc556cfe827d918c903818fd07f96c802d14fa8174242c26863d33714ffdf" -dependencies = [ - "winmd-macros", -] - -[[package]] -name = "winmd-macros" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3b40684a97b141cccb473d5575c855ff0bbeef6a28b48c59a0be255bed49e8c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "winrt" -version = "0.7.2" -source = "git+https://github.com/microsoft/winrt-rs#1da36f73246f02fadba6c243b0dbc7f3ffa596b0" -dependencies = [ - "const-sha1", - "winmd", - "winrt-macros", -] - -[[package]] -name = "winrt-deps" -version = "0.1.0" -source = "git+https://github.com/microsoft/winrt-rs#1da36f73246f02fadba6c243b0dbc7f3ffa596b0" -dependencies = [ - "anyhow", - "cargo_toml", - "serde_json", - "thiserror", -] - -[[package]] -name = "winrt-gen" -version = "0.7.2" -source = "git+https://github.com/microsoft/winrt-rs#1da36f73246f02fadba6c243b0dbc7f3ffa596b0" -dependencies = [ - "proc-macro2", - "quote", - "rayon", - "sha1", - "squote", - "syn", - "winmd", - "winrt-gen-macros", -] - -[[package]] -name = "winrt-gen-macros" -version = "0.7.2" -source = "git+https://github.com/microsoft/winrt-rs#1da36f73246f02fadba6c243b0dbc7f3ffa596b0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "winrt-macros" -version = "0.7.2" -source = "git+https://github.com/microsoft/winrt-rs#1da36f73246f02fadba6c243b0dbc7f3ffa596b0" -dependencies = [ - "cargo_toml", - "proc-macro2", - "quote", - "rayon", - "serde_json", - "squote", - "syn", - "winmd", - "winrt-deps", - "winrt-gen", -] diff --git a/src/uwp/app.rs b/src/uwp/app.rs index a57385d..a4ce1fc 100644 --- a/src/uwp/app.rs +++ b/src/uwp/app.rs @@ -1,7 +1,7 @@ use crate::minesweeper::Minesweeper; -use crate::uwp::app_adapter::UwpApp; +use bindings::*; use bindings::windows::{ - application_model::core::CoreApplicationView, + application_model::core::{CoreApplicationView, IFrameworkView}, foundation::numerics::Vector2, foundation::TypedEventHandler, ui::composition::{CompositionTarget, Compositor}, @@ -17,25 +17,31 @@ struct AppState { game: Minesweeper, } +#[winrt::implement(windows::application_model::core::IFrameworkViewSource)] +pub struct MinesweeperAppSource {} + +impl MinesweeperAppSource { + fn create_view(&mut self) -> winrt::Result { + let app = MinesweeperApp { + state: Arc::new(Mutex::new(None)), + }; + let view: IFrameworkView = app.into(); + Ok(view) + } +} + // TOOD: A way to do this without the arc/mutex? +#[winrt::implement(windows::application_model::core::IFrameworkView)] pub struct MinesweeperApp { state: Arc>>, } impl MinesweeperApp { - pub fn new() -> Self { - Self { - state: Arc::new(Mutex::new(None)), - } - } -} - -impl UwpApp for MinesweeperApp { - fn initialize(&mut self, _window: &CoreApplicationView) -> winrt::Result<()> { + fn initialize(&mut self, _window: &Option) -> winrt::Result<()> { Ok(()) } - fn set_window(&mut self, _window: &CoreWindow) -> winrt::Result<()> { + fn set_window(&mut self, _window: &Option) -> winrt::Result<()> { Ok(()) } @@ -75,6 +81,7 @@ impl UwpApp for MinesweeperApp { let size_changed_handler = SizeChangedHandler::new({ let state = self.state.clone(); move |_sender, args| { + let args = args.as_ref().unwrap(); let size = args.size()?; let size = Vector2 { x: size.width as f32, @@ -90,6 +97,7 @@ impl UwpApp for MinesweeperApp { let pointer_moved_handler = PointerMovedHandler::new({ let state = self.state.clone(); move |_sender, args| { + let args = args.as_ref().unwrap(); let point = args.current_point()?.position()?; let point = Vector2 { x: point.x as f32, @@ -105,6 +113,7 @@ impl UwpApp for MinesweeperApp { let pointer_pressed_handler = PointerPressedHandler::new({ let state = self.state.clone(); move |_sender, args| { + let args = args.as_ref().unwrap(); let properties = args.current_point()?.properties()?; let is_right = properties.is_right_button_pressed()?; let is_eraser = properties.is_eraser()?; @@ -125,7 +134,7 @@ impl UwpApp for MinesweeperApp { let dispatcher = window.dispatcher()?; dispatcher.process_events(CoreProcessEventsOption::ProcessUntilQuit)?; - + Ok(()) } diff --git a/src/uwp/app_adapter.rs b/src/uwp/app_adapter.rs deleted file mode 100644 index 4b36049..0000000 --- a/src/uwp/app_adapter.rs +++ /dev/null @@ -1,158 +0,0 @@ -use bindings::windows::{ - application_model::core::{CoreApplicationView, IFrameworkView, IFrameworkViewSource}, - ui::core::CoreWindow, -}; -use com::{co_class, com_interface, interfaces::iunknown::IUnknown}; -use std::cell::RefCell; -use winrt::AbiTransferable; -use winrt::TryInto; - -pub trait UwpApp { - fn initialize(&mut self, window: &CoreApplicationView) -> winrt::Result<()>; - fn set_window(&mut self, window: &CoreWindow) -> winrt::Result<()>; - fn load(&mut self, entry_point: &winrt::HString) -> winrt::Result<()>; - fn run(&mut self) -> winrt::Result<()>; - fn uninitialize(&mut self) -> winrt::Result<()>; -} - -#[com_interface("AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90")] -pub trait IInspectable: IUnknown { - unsafe fn get_iids(&self, iid_count: *mut u32, iids: *mut *mut winrt::Guid) - -> winrt::ErrorCode; - unsafe fn get_runtime_class_name( - &self, - class_name: *mut ::Abi, - ) -> winrt::ErrorCode; - unsafe fn get_trust_level(&self, trust_level: *mut i32) -> winrt::ErrorCode; -} - -#[com_interface("FAAB5CD0-8924-45AC-AD0F-A08FAE5D0324")] -pub trait IFrameworkViewImpl: IInspectable { - unsafe fn initialize( - &self, - application_view: ::Abi, - ) -> winrt::ErrorCode; - unsafe fn set_window( - &self, - window: ::Abi, - ) -> winrt::ErrorCode; - unsafe fn load( - &self, - entry_point: ::Abi, - ) -> winrt::ErrorCode; - unsafe fn run(&self) -> winrt::ErrorCode; - unsafe fn uninitialize(&self) -> winrt::ErrorCode; -} - -#[com_interface("CD770614-65C4-426C-9494-34FC43554862")] -pub trait IFrameworkViewSourceImpl: IInspectable { - unsafe fn create_view( - &self, - result: *mut ::Abi, - ) -> winrt::ErrorCode; -} - -#[co_class(implements(IInspectable, IFrameworkViewImpl, IFrameworkViewSourceImpl))] -pub struct AppView { - inner: RefCell>, -} - -impl AppView { - pub(crate) fn new() -> Box { - panic!("Not supported!"); - } - - pub fn create_view_source(inner: Box) -> winrt::Result { - let app_view = Box::into_raw(AppView::allocate(RefCell::new(inner))); - let mut object = winrt::Object::default(); - unsafe { - *object.set_abi() = std::mem::transmute(app_view); - } - let view_source: IFrameworkViewSource = object.try_into()?; - std::mem::forget(object); - Ok(view_source) - } -} - -impl IInspectable for AppView { - unsafe fn get_iids( - &self, - _iid_count: *mut u32, - _iids: *mut *mut winrt::Guid, - ) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) - } - unsafe fn get_runtime_class_name( - &self, - _class_name: *mut ::Abi, - ) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) - } - unsafe fn get_trust_level(&self, _trust_level: *mut i32) -> winrt::ErrorCode { - winrt::ErrorCode(0x80004001) - } -} - -impl IFrameworkViewImpl for AppView { - unsafe fn initialize( - &self, - application_view: ::Abi, - ) -> winrt::ErrorCode { - let application_view = CoreApplicationView::from_abi(&application_view); - let result = self - .inner - .borrow_mut() - .initialize(&application_view) - .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)); - std::mem::forget(application_view); - result - } - unsafe fn set_window( - &self, - window: ::Abi, - ) -> winrt::ErrorCode { - let window = CoreWindow::from_abi(&window); - let result = self - .inner - .borrow_mut() - .set_window(&window) - .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)); - std::mem::forget(window); - result - } - unsafe fn load( - &self, - entry_point: ::Abi, - ) -> winrt::ErrorCode { - let entry_point = winrt::HString::from_abi(&entry_point); - let result = self - .inner - .borrow_mut() - .load(&entry_point) - .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)); - std::mem::forget(entry_point); - result - } - unsafe fn run(&self) -> winrt::ErrorCode { - self.inner - .borrow_mut() - .run() - .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)) - } - unsafe fn uninitialize(&self) -> winrt::ErrorCode { - self.inner - .borrow_mut() - .uninitialize() - .map_or_else(|e| e.code(), |()| winrt::ErrorCode(0)) - } -} - -impl IFrameworkViewSourceImpl for AppView { - unsafe fn create_view( - &self, - result: *mut ::Abi, - ) -> winrt::ErrorCode { - let guid = &::iid(); - winrt::ErrorCode(self.query_interface(std::mem::transmute(guid), result as _) as u32) - } -} diff --git a/src/uwp/mod.rs b/src/uwp/mod.rs index 5531ca1..648d42f 100644 --- a/src/uwp/mod.rs +++ b/src/uwp/mod.rs @@ -1,5 +1,4 @@ mod app; -mod app_adapter; mod run; pub use run::run; diff --git a/src/uwp/run.rs b/src/uwp/run.rs index 3cded7e..2b60717 100644 --- a/src/uwp/run.rs +++ b/src/uwp/run.rs @@ -1,9 +1,11 @@ -use crate::uwp::app::MinesweeperApp; -use crate::uwp::app_adapter::AppView; -use bindings::windows::application_model::core::CoreApplication; +use crate::uwp::app::MinesweeperAppSource; +use bindings::windows::{ + application_model::core::{CoreApplication, IFrameworkViewSource}, +}; pub fn run() -> winrt::Result<()> { - let view_source = AppView::create_view_source(Box::new(MinesweeperApp::new()))?; + let app_source = MinesweeperAppSource {}; + let view_source: IFrameworkViewSource = app_source.into(); CoreApplication::run(&view_source)?; Ok(()) } From c53f77fd3c6c2866d61b38cf86eef94eee4d1c48 Mon Sep 17 00:00:00 2001 From: robmikh Date: Tue, 24 Nov 2020 16:56:30 -0800 Subject: [PATCH 16/20] restore pc build --- Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f9ab49a..8d762c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,9 +9,9 @@ winrt = { git = "https://github.com/microsoft/winrt-rs" } rand = "0.7.3" bindings = { path = "bindings" } -#[target.'cfg(target_vendor = "pc")'.dependencies] -#winit = "0.22.2" -#raw-window-handle = "0.3.3" +[target.'cfg(target_vendor = "pc")'.dependencies] +winit = "0.22.2" +raw-window-handle = "0.3.3" [features] show-mines = [] From 4612e3c1287b438c1ec106a4697934d3c2418ab3 Mon Sep 17 00:00:00 2001 From: robmikh Date: Tue, 24 Nov 2020 17:10:21 -0800 Subject: [PATCH 17/20] update instructions --- Cargo.lock | 812 +++++++++++++++++++++++++++++++++++++++++++++++++++-- README.md | 4 +- UWP.md | 31 +- 3 files changed, 810 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3875723..04ac114 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,11 +1,40 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "andrew" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7f09f89872c2b6b29e319377b1fbe91c6f5947df19a25596e121cf19a7b35e" +dependencies = [ + "bitflags", + "line_drawing", + "rusttype 0.7.9", + "walkdir", + "xdg", + "xml-rs", +] + +[[package]] +name = "android_log-sys" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8052e2d8aabbb8d556d6abbcce2a22b9590996c5f849b9c7ce4544a2e3b984e" + [[package]] name = "anyhow" version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7" +[[package]] +name = "approx" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" +dependencies = [ + "num-traits", +] + [[package]] name = "autocfg" version = "1.0.1" @@ -19,6 +48,35 @@ dependencies = [ "winrt", ] +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" + +[[package]] +name = "calloop" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aa2097be53a00de9e8fc349fea6d76221f398f5c4fa550d420669906962d160" +dependencies = [ + "mio", + "mio-extras", + "nix", +] + [[package]] name = "cargo_toml" version = "0.8.1" @@ -30,6 +88,12 @@ dependencies = [ "toml", ] +[[package]] +name = "cc" +version = "1.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95752358c8f7552394baf48cd82695b345628ad3f170d607de3ca03b8dacca15" + [[package]] name = "cfg-if" version = "0.1.10" @@ -42,6 +106,30 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "cocoa" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c49e86fc36d5704151f5996b7b3795385f50ce09e3be0f47a0cfde869681cf8" +dependencies = [ + "bitflags", + "block", + "core-foundation", + "core-graphics", + "foreign-types", + "libc", + "objc", +] + [[package]] name = "const-sha1" version = "0.2.0" @@ -54,6 +142,47 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c478836e029dcef17fb47c89023448c64f781a046e0300e257ad8225ae59afab" +[[package]] +name = "core-foundation" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" + +[[package]] +name = "core-graphics" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923" +dependencies = [ + "bitflags", + "core-foundation", + "foreign-types", + "libc", +] + +[[package]] +name = "core-video-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34ecad23610ad9757664d644e369246edde1803fcb43ed72876565098a5d3828" +dependencies = [ + "cfg-if 0.1.10", + "core-foundation-sys", + "core-graphics", + "libc", + "objc", +] + [[package]] name = "crossbeam-channel" version = "0.5.0" @@ -101,12 +230,75 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "derivative" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb582b60359da160a9477ee80f15c8d784c477e69c217ef2cdd4169c24ea380f" +dependencies = [ + "proc-macro2 1.0.24", + "quote 1.0.7", + "syn", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dlib" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b11f15d1e3268f140f68d390637d5e76d849782d971ae7063e0da69fe9709a76" +dependencies = [ + "libloading", +] + +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + [[package]] name = "either" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +dependencies = [ + "bitflags", + "fuchsia-zircon-sys", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" + [[package]] name = "getrandom" version = "0.1.15" @@ -127,24 +319,126 @@ dependencies = [ "libc", ] +[[package]] +name = "instant" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + [[package]] name = "itoa" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "libc" version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" +[[package]] +name = "libloading" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1090080fe06ec2648d0da3881d9453d97e71a45f00eb179af7fdd7e3f686fdb0" +dependencies = [ + "cfg-if 1.0.0", + "winapi 0.3.9", +] + +[[package]] +name = "line_drawing" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc7ad3d82c845bdb5dde34ffdcc7a5fb4d2996e1e1ee0f19c33bc80e15196b9" +dependencies = [ + "num-traits", +] + +[[package]] +name = "lock_api" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +dependencies = [ + "cfg-if 0.1.10", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] +name = "memmap" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" +dependencies = [ + "libc", + "winapi 0.3.9", +] + [[package]] name = "memoffset" version = "0.5.6" @@ -160,9 +454,118 @@ version = "0.1.0" dependencies = [ "bindings", "rand", + "raw-window-handle", + "winit", "winrt", ] +[[package]] +name = "mio" +version = "0.6.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" +dependencies = [ + "cfg-if 0.1.10", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow", + "net2", + "slab", + "winapi 0.2.8", +] + +[[package]] +name = "mio-extras" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" +dependencies = [ + "lazycell", + "log", + "mio", + "slab", +] + +[[package]] +name = "miow" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", +] + +[[package]] +name = "ndk" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a356cafe20aee088789830bfea3a61336e84ded9e545e00d3869ce95dcb80c" +dependencies = [ + "jni-sys", + "ndk-sys", + "num_enum", +] + +[[package]] +name = "ndk-glue" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1730ee2e3de41c3321160a6da815f008c4006d71b095880ea50e17cf52332b8" +dependencies = [ + "android_log-sys", + "lazy_static", + "libc", + "log", + "ndk", + "ndk-sys", +] + +[[package]] +name = "ndk-sys" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2820aca934aba5ed91c79acc72b6a44048ceacc5d36c035ed4e051f12d887d" + +[[package]] +name = "net2" +version = "0.2.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ebc3ec692ed7c9a255596c67808dee269f64655d8baf7b4f0638e51ba1d6853" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "nix" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" +dependencies = [ + "bitflags", + "cc", + "cfg-if 0.1.10", + "libc", + "void", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + [[package]] name = "num_cpus" version = "1.13.0" @@ -173,19 +576,122 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca565a7df06f3d4b485494f25ba05da1435950f4dc263440eda7a6fa9b8e36e4" +dependencies = [ + "derivative", + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffa5a33ddddfee04c0283a7653987d634e880347e96b5b2ed64de07efb59db9d" +dependencies = [ + "proc-macro-crate", + "proc-macro2 1.0.24", + "quote 1.0.7", + "syn", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "ordered-float" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3741934be594d77de1c8461ebcbbe866f585ea616a9753aa78f2bdc69f0e4579" +dependencies = [ + "num-traits", +] + +[[package]] +name = "parking_lot" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" +dependencies = [ + "cfg-if 0.1.10", + "cloudabi", + "libc", + "redox_syscall", + "smallvec", + "winapi 0.3.9", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pkg-config" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" + [[package]] name = "ppv-lite86" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +dependencies = [ + "unicode-xid 0.1.0", +] + [[package]] name = "proc-macro2" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" dependencies = [ - "unicode-xid", + "unicode-xid 0.2.1", +] + +[[package]] +name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +dependencies = [ + "proc-macro2 0.4.30", ] [[package]] @@ -194,7 +700,7 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" dependencies = [ - "proc-macro2", + "proc-macro2 1.0.24", ] [[package]] @@ -238,6 +744,15 @@ dependencies = [ "rand_core", ] +[[package]] +name = "raw-window-handle" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a441a7a6c80ad6473bd4b74ec1c9a4c951794285bf941c2126f607c72e48211" +dependencies = [ + "libc", +] + [[package]] name = "rayon" version = "1.5.0" @@ -263,12 +778,47 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "rusttype" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "310942406a39981bed7e12b09182a221a29e0990f3e7e0c971f131922ed135d5" +dependencies = [ + "rusttype 0.8.3", +] + +[[package]] +name = "rusttype" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f61411055101f7b60ecf1041d87fb74205fb20b0c7a723f07ef39174cf6b4c0" +dependencies = [ + "approx", + "ordered-float", + "stb_truetype", +] + [[package]] name = "ryu" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -287,8 +837,8 @@ version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.24", + "quote 1.0.7", "syn", ] @@ -309,21 +859,58 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" +[[package]] +name = "slab" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" + +[[package]] +name = "smallvec" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7acad6f34eb9e8a259d3283d1e8c1d34d7415943d4895f65cc73813c7396fc85" + +[[package]] +name = "smithay-client-toolkit" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "421c8dc7acf5cb205b88160f8b4cc2c5cfabe210e43b2f80f009f4c1ef910f1d" +dependencies = [ + "andrew", + "bitflags", + "dlib", + "lazy_static", + "memmap", + "nix", + "wayland-client", + "wayland-protocols", +] + [[package]] name = "squote" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fccf17fd09e2455ea796d2ad267b64fa2c5cbd8701b2a93b555d2aa73449f7d" +[[package]] +name = "stb_truetype" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f77b6b07e862c66a9f3e62a07588fee67cd90a9135a2b942409f195507b4fb51" +dependencies = [ + "byteorder", +] + [[package]] name = "syn" version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b4f34193997d92804d359ed09953e25d5138df6bcc055a71bf68ee89fdf9223" dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", + "proc-macro2 1.0.24", + "quote 1.0.7", + "unicode-xid 0.2.1", ] [[package]] @@ -341,8 +928,8 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.24", + "quote 1.0.7", "syn", ] @@ -355,18 +942,175 @@ dependencies = [ "serde", ] +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + [[package]] name = "unicode-xid" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "walkdir" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +dependencies = [ + "same-file", + "winapi 0.3.9", + "winapi-util", +] + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +[[package]] +name = "wayland-client" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1080ebe0efabcf12aef2132152f616038f2d7dcbbccf7b2d8c5270fe14bcda" +dependencies = [ + "bitflags", + "calloop", + "downcast-rs", + "libc", + "mio", + "nix", + "wayland-commons", + "wayland-scanner", + "wayland-sys", +] + +[[package]] +name = "wayland-commons" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb66b0d1a27c39bbce712b6372131c6e25149f03ffb0cd017cf8f7de8d66dbdb" +dependencies = [ + "nix", + "wayland-sys", +] + +[[package]] +name = "wayland-protocols" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cc286643656742777d55dc8e70d144fa4699e426ca8e9d4ef454f4bf15ffcf9" +dependencies = [ + "bitflags", + "wayland-client", + "wayland-commons", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93b02247366f395b9258054f964fe293ddd019c3237afba9be2ccbe9e1651c3d" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "xml-rs", +] + +[[package]] +name = "wayland-sys" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d94e89a86e6d6d7c7c9b19ebf48a03afaac4af6bc22ae570e9a24124b75358f4" +dependencies = [ + "dlib", + "lazy_static", +] + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi 0.3.9", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "winit" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e4ccbf7ddb6627828eace16cacde80fc6bf4dbb3469f88487262a02cf8e7862" +dependencies = [ + "bitflags", + "cocoa", + "core-foundation", + "core-graphics", + "core-video-sys", + "dispatch", + "instant", + "lazy_static", + "libc", + "log", + "mio", + "mio-extras", + "ndk", + "ndk-glue", + "ndk-sys", + "objc", + "parking_lot", + "percent-encoding", + "raw-window-handle", + "smithay-client-toolkit", + "wayland-client", + "winapi 0.3.9", + "x11-dl", +] + [[package]] name = "winmd" version = "0.6.0" @@ -382,8 +1126,8 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44e088988554d1f9f4b79815c29d02daf95268c47389e54bfb3c0d5a4c587974" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.24", + "quote 1.0.7", "syn", ] @@ -413,8 +1157,8 @@ name = "winrt-gen" version = "0.8.0" source = "git+https://github.com/microsoft/winrt-rs#38b7bea9a17930e55145a2b577b956e8193521ad" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.24", + "quote 1.0.7", "rayon", "sha1", "squote", @@ -428,8 +1172,8 @@ name = "winrt-gen-macros" version = "0.8.0" source = "git+https://github.com/microsoft/winrt-rs#38b7bea9a17930e55145a2b577b956e8193521ad" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.24", + "quote 1.0.7", "syn", ] @@ -439,8 +1183,8 @@ version = "0.8.0" source = "git+https://github.com/microsoft/winrt-rs#38b7bea9a17930e55145a2b577b956e8193521ad" dependencies = [ "cargo_toml", - "proc-macro2", - "quote", + "proc-macro2 1.0.24", + "quote 1.0.7", "rayon", "serde_json", "squote", @@ -449,3 +1193,37 @@ dependencies = [ "winrt-deps", "winrt-gen", ] + +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + +[[package]] +name = "x11-dl" +version = "2.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf981e3a5b3301209754218f962052d4d9ee97e478f4d26d4a6eced34c1fef8" +dependencies = [ + "lazy_static", + "libc", + "maybe-uninit", + "pkg-config", +] + +[[package]] +name = "xdg" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" + +[[package]] +name = "xml-rs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a" diff --git a/README.md b/README.md index c9cfa9c..a45881c 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,10 @@ cargo run --release ### UWP -Running Minesweeper as a UWP application can be done by building for a `*-uwp-windows-msvc` target and then registering the app. Because the `*-uwp-windows-msvc` targets are currently tier 3, you'll need to compile a toolchain yourself. More information can be found [here](UWP.md). +Running Minesweeper as a UWP application can be done by building for a `*-uwp-windows-msvc` target and then registering the app. More information can be found [here](UWP.md). ``` -cargo +local build --target x86_64-uwp-windows-msvc +cargo +nightly build -Z build-std=std,panic_abort --target x86_64-uwp-windows-msvc (powershell.exe) Add-AppxPackage -Register AppxManifest.xml ``` *NOTE: AppManifest.xml currently assumes the `x86_64-uwp-windows-msvc` target but can be updated.* diff --git a/UWP.md b/UWP.md index 00055ab..14a7a57 100644 --- a/UWP.md +++ b/UWP.md @@ -1,31 +1,26 @@ -# Building the `*-uwp-windows-msvc` toolchain -Clone the [rust](https://github.com/rust-lang/rust) repo. You'll need to setup a `config.toml` file by copying the existing `config.toml.example` file and editing it: +# Building for `*-uwp-windows-msvc` targets + +## Required tools +First, you'll need to install the nightly toolchain: ``` -# In addition to all host triples, other triples to produce the standard library -# for. Each host triple will be used to produce a copy of the standard library -# for each target triple. -# -# Defaults to just the build triple -target = ["x86_64-uwp-windows-msvc"] +rustup toolchain install nightly +rustup component add rust-src ``` -Then follow the instructions in the [README](https://github.com/rust-lang/rust/blob/master/README.md#msvc) to build the toolchain. Afterwards you can link your newly built toolchain to rustup for easier use. +I'm using version `1.50.0-nightly (1c389ffef 2020-11-24)`. If you already have a nightly toolchain installed and you're seeing an error about `SetThreadStackGuarantee`, update your nightly toolchain. + +## Building Minesweeper +From the appropriate VS command prompt (e.g. "x64 Native Tools Command Prompt for VS 2019" when building for x86_64), run cargo but target a uwp target: ``` -python x.py build -rustup toolchain link local build\x86_64-pc-windows-msvc\stage2 +cargo +nightly build -Z build-std=std,panic_abort --target x86_64-uwp-windows-msvc ``` -There's one last step. You'll need put a copy of `rustfmt.exe` into the `bin` directory for your toolchain. For example, I placed mine in `build\x86_64-pc-windows-msvc\stage2\bin`. - -Once you have everything in place, you'll be able to build using you're new toolchain: +After that, you should be able to register your application: ``` -cargo +local build --target x86_64-uwp-windows-msvc (powershell.exe) Add-AppxPackage -Register AppxManifest.xml ``` -## Troubleshooting - -In the event you're getting errors when compiling llvm, make sure you use a **non-preview** version of Visual Studio 2019. I believe there's a fix, but it wasn't present in the snapshot I built from (stable - [5c1f21c3b82](https://github.com/rust-lang/rust/tree/5c1f21c3b82297671ad3ae1e8c942d2ca92e84f2)). +Special thanks to [bdbai](https://github.com/bdbai) for the [firstuwp-rs](https://github.com/bdbai/firstuwp-rs) project. Without that, I wouldn't have known about the [build-std](https://doc.rust-lang.org/cargo/reference/unstable.html#build-std) cargo feature. \ No newline at end of file From 6124e707b80bb4e44d9d4acd4effd92befbb1898 Mon Sep 17 00:00:00 2001 From: robmikh Date: Sun, 29 Nov 2020 16:21:57 -0800 Subject: [PATCH 18/20] run cargo fmt --- bindings/Cargo.lock | 372 +++++++++++++++++++++++++++++++++++++++++ bindings/build.rs | 14 +- src/desktop/interop.rs | 2 +- src/uwp/app.rs | 4 +- src/uwp/run.rs | 4 +- 5 files changed, 383 insertions(+), 13 deletions(-) create mode 100644 bindings/Cargo.lock diff --git a/bindings/Cargo.lock b/bindings/Cargo.lock new file mode 100644 index 0000000..83188a5 --- /dev/null +++ b/bindings/Cargo.lock @@ -0,0 +1,372 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "anyhow" +version = "1.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7" + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "bindings" +version = "0.1.0" +dependencies = [ + "winrt", +] + +[[package]] +name = "cargo_toml" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513d17226888c7b8283ac02a1c1b0d8a9d4cbf6db65dfadb79f598f5d7966fe9" +dependencies = [ + "serde", + "serde_derive", + "toml", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "const-sha1" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb58b6451e8c2a812ad979ed1d83378caa5e927eef2622017a45f251457c2c9d" + +[[package]] +name = "const_fn" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c478836e029dcef17fb47c89023448c64f781a046e0300e257ad8225ae59afab" + +[[package]] +name = "crossbeam-channel" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0f606a85340376eef0d6d8fec399e6d4a544d648386c6645eb6d0653b27d9f" +dependencies = [ + "cfg-if", + "const_fn", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec91540d98355f690a86367e566ecad2e9e579f230230eb7c21398372be73ea5" +dependencies = [ + "autocfg", + "cfg-if", + "const_fn", + "lazy_static", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "hermit-abi" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" +dependencies = [ + "libc", +] + +[[package]] +name = "itoa" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" + +[[package]] +name = "memoffset" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "proc-macro2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "serde" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" + +[[package]] +name = "serde_derive" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" + +[[package]] +name = "squote" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fccf17fd09e2455ea796d2ad267b64fa2c5cbd8701b2a93b555d2aa73449f7d" + +[[package]] +name = "syn" +version = "1.0.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b4f34193997d92804d359ed09953e25d5138df6bcc055a71bf68ee89fdf9223" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "thiserror" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "toml" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645" +dependencies = [ + "serde", +] + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "winmd" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b74dd1bf09feda89c3ab7456f413c89e4f964f3151a3c4f25a1ce439e11603" +dependencies = [ + "winmd-macros", +] + +[[package]] +name = "winmd-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44e088988554d1f9f4b79815c29d02daf95268c47389e54bfb3c0d5a4c587974" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "winrt" +version = "0.8.0" +source = "git+https://github.com/microsoft/winrt-rs#38b7bea9a17930e55145a2b577b956e8193521ad" +dependencies = [ + "const-sha1", + "winmd", + "winrt-macros", +] + +[[package]] +name = "winrt-deps" +version = "0.1.0" +source = "git+https://github.com/microsoft/winrt-rs#38b7bea9a17930e55145a2b577b956e8193521ad" +dependencies = [ + "anyhow", + "cargo_toml", + "serde_json", + "thiserror", +] + +[[package]] +name = "winrt-gen" +version = "0.8.0" +source = "git+https://github.com/microsoft/winrt-rs#38b7bea9a17930e55145a2b577b956e8193521ad" +dependencies = [ + "proc-macro2", + "quote", + "rayon", + "sha1", + "squote", + "syn", + "winmd", + "winrt-gen-macros", +] + +[[package]] +name = "winrt-gen-macros" +version = "0.8.0" +source = "git+https://github.com/microsoft/winrt-rs#38b7bea9a17930e55145a2b577b956e8193521ad" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "winrt-macros" +version = "0.8.0" +source = "git+https://github.com/microsoft/winrt-rs#38b7bea9a17930e55145a2b577b956e8193521ad" +dependencies = [ + "cargo_toml", + "proc-macro2", + "quote", + "rayon", + "serde_json", + "squote", + "syn", + "winmd", + "winrt-deps", + "winrt-gen", +] diff --git a/bindings/build.rs b/bindings/build.rs index 5cb809e..5f63de9 100644 --- a/bindings/build.rs +++ b/bindings/build.rs @@ -2,9 +2,9 @@ fn main() { winrt::build!( types windows::application_model::core::{ - CoreApplication, - CoreApplicationView, - IFrameworkViewSource, + CoreApplication, + CoreApplicationView, + IFrameworkViewSource, IFrameworkView, } windows::foundation::numerics::{Vector2, Vector3} @@ -26,10 +26,10 @@ fn main() { windows::ui::composition::desktop::DesktopWindowTarget windows::ui::Colors windows::ui::core::{ - CoreDispatcher, - CoreWindow, - CoreProcessEventsOption, - WindowSizeChangedEventArgs, + CoreDispatcher, + CoreWindow, + CoreProcessEventsOption, + WindowSizeChangedEventArgs, PointerEventArgs, } ); diff --git a/src/desktop/interop.rs b/src/desktop/interop.rs index 56e7438..746571c 100644 --- a/src/desktop/interop.rs +++ b/src/desktop/interop.rs @@ -92,4 +92,4 @@ pub fn create_dispatcher_queue_controller_for_current_thread( DispatcherQueueThreadType::Current, DispatcherQueueThreadApartmentType::None, ) -} \ No newline at end of file +} diff --git a/src/uwp/app.rs b/src/uwp/app.rs index a4ce1fc..22bc56d 100644 --- a/src/uwp/app.rs +++ b/src/uwp/app.rs @@ -1,5 +1,4 @@ use crate::minesweeper::Minesweeper; -use bindings::*; use bindings::windows::{ application_model::core::{CoreApplicationView, IFrameworkView}, foundation::numerics::Vector2, @@ -7,6 +6,7 @@ use bindings::windows::{ ui::composition::{CompositionTarget, Compositor}, ui::core::{CoreProcessEventsOption, CoreWindow, PointerEventArgs, WindowSizeChangedEventArgs}, }; +use bindings::*; use std::sync::{Arc, Mutex}; struct AppState { @@ -134,7 +134,7 @@ impl MinesweeperApp { let dispatcher = window.dispatcher()?; dispatcher.process_events(CoreProcessEventsOption::ProcessUntilQuit)?; - + Ok(()) } diff --git a/src/uwp/run.rs b/src/uwp/run.rs index 2b60717..ee75e4b 100644 --- a/src/uwp/run.rs +++ b/src/uwp/run.rs @@ -1,7 +1,5 @@ use crate::uwp::app::MinesweeperAppSource; -use bindings::windows::{ - application_model::core::{CoreApplication, IFrameworkViewSource}, -}; +use bindings::windows::application_model::core::{CoreApplication, IFrameworkViewSource}; pub fn run() -> winrt::Result<()> { let app_source = MinesweeperAppSource {}; From 58a3fa64b12ece03c2d6390bb561bb1f7a652716 Mon Sep 17 00:00:00 2001 From: robmikh Date: Tue, 1 Dec 2020 17:06:35 -0800 Subject: [PATCH 19/20] change back readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 568d4c2..fb77ee8 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ cargo run --release Running Minesweeper as a UWP application can be done by building for a `*-uwp-windows-msvc` target and then registering the app. More information can be found [here](UWP.md). ``` -cargo +nightly build --release -Z build-std=std,panic_abort --target x86_64-uwp-windows-msvc +cargo +nightly build -Z build-std=std,panic_abort --target x86_64-uwp-windows-msvc (powershell.exe) Add-AppxPackage -Register AppxManifest.xml ``` *NOTE: AppManifest.xml currently assumes the `x86_64-uwp-windows-msvc` target but can be updated.* From c6691231cb5ad2629d3fab173cd86268aa930177 Mon Sep 17 00:00:00 2001 From: Cameron Taggart Date: Sun, 20 Dec 2020 21:19:20 -0800 Subject: [PATCH 20/20] add ClickOnce --- .gitignore | 4 +++ ClickOnce/Minesweeper.csproj | 15 ++++++++ ClickOnce/Program.cs | 21 +++++++++++ .../PublishProfiles/ClickOnceProfile.pubxml | 34 ++++++++++++++++++ .../ClickOnceProfile.pubxml.user.template | 6 ++++ ClickOnce/Square44x44Logo.ico | Bin 0 -> 6629 bytes ClickOnce/build.ps1 | 1 + 7 files changed, 81 insertions(+) create mode 100644 ClickOnce/Minesweeper.csproj create mode 100644 ClickOnce/Program.cs create mode 100644 ClickOnce/Properties/PublishProfiles/ClickOnceProfile.pubxml create mode 100644 ClickOnce/Properties/PublishProfiles/ClickOnceProfile.pubxml.user.template create mode 100644 ClickOnce/Square44x44Logo.ico create mode 100644 ClickOnce/build.ps1 diff --git a/.gitignore b/.gitignore index ea8c4bf..dadf223 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ /target +*.user +bin/ +obj/ +.vs/ \ No newline at end of file diff --git a/ClickOnce/Minesweeper.csproj b/ClickOnce/Minesweeper.csproj new file mode 100644 index 0000000..8c67a2c --- /dev/null +++ b/ClickOnce/Minesweeper.csproj @@ -0,0 +1,15 @@ + + + WinExe + net5.0-windows + true + Release + ClickOnceProfile + Square44x44Logo.ico + + + + Always + + + \ No newline at end of file diff --git a/ClickOnce/Program.cs b/ClickOnce/Program.cs new file mode 100644 index 0000000..8ba6fbc --- /dev/null +++ b/ClickOnce/Program.cs @@ -0,0 +1,21 @@ +using System; +using System.Diagnostics; +using System.Windows.Forms; + +namespace WindowsFormsApp1 +{ + static class Program + { + static void Main() + { + try + { + Process.Start(new ProcessStartInfo { CreateNoWindow = true, FileName = "minesweeper-rs.exe" }); + } + catch (Exception x) + { + MessageBox.Show(x.Message, "Error Starting Minesweeper", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } +} diff --git a/ClickOnce/Properties/PublishProfiles/ClickOnceProfile.pubxml b/ClickOnce/Properties/PublishProfiles/ClickOnceProfile.pubxml new file mode 100644 index 0000000..a281a5a --- /dev/null +++ b/ClickOnce/Properties/PublishProfiles/ClickOnceProfile.pubxml @@ -0,0 +1,34 @@ + + + 0 + 0.1.0.* + True + Release + True + True + true + Web + True + True + true + false + Any CPU + bin\publish\ + bin\publish\ + ClickOnce + False + False + False + sha256RSA + True + net5.0-windows + True + Foreground + + + + true + .NET Desktop Runtime 5.0.1 (x64) + + + diff --git a/ClickOnce/Properties/PublishProfiles/ClickOnceProfile.pubxml.user.template b/ClickOnce/Properties/PublishProfiles/ClickOnceProfile.pubxml.user.template new file mode 100644 index 0000000..74cb83e --- /dev/null +++ b/ClickOnce/Properties/PublishProfiles/ClickOnceProfile.pubxml.user.template @@ -0,0 +1,6 @@ + + + https://ctaggart.github.io/minesweeper-rs/ + 1A92BF20220B301077205787F406B1BCEE6DA97E + + diff --git a/ClickOnce/Square44x44Logo.ico b/ClickOnce/Square44x44Logo.ico new file mode 100644 index 0000000000000000000000000000000000000000..ffdfbf61ff73b7c6ee39800d8e36d8537b8ab648 GIT binary patch literal 6629 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 M4J`EE>A61qFYeTRTmS$7 literal 0 HcmV?d00001 diff --git a/ClickOnce/build.ps1 b/ClickOnce/build.ps1 new file mode 100644 index 0000000..49b2f5b --- /dev/null +++ b/ClickOnce/build.ps1 @@ -0,0 +1 @@ +msbuild $PSScriptRoot /t:Restore,Publish /v:m