winit-core: new crate + split out as_any
This commit is contained in:
parent
bf0bde8067
commit
3493a20173
8 changed files with 73 additions and 4 deletions
30
winit-core/Cargo.toml
Normal file
30
winit-core/Cargo.toml
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
[package]
|
||||
authors = ["The winit contributors", "Kirill Chibisov <contact@kchibisov.com>"]
|
||||
categories = ["gui"]
|
||||
description = "winit core API."
|
||||
documentation = "https://docs.rs/winit-core"
|
||||
edition.workspace = true
|
||||
keywords = ["windowing"]
|
||||
license.workspace = true
|
||||
name = "winit-core"
|
||||
readme = "README.md"
|
||||
repository.workspace = true
|
||||
rust-version.workspace = true
|
||||
version = "0.0.0"
|
||||
|
||||
[features]
|
||||
serde = ["dep:serde", "cursor-icon/serde", "smol_str/serde", "dpi/serde", "bitflags/serde"]
|
||||
|
||||
[dependencies]
|
||||
bitflags = "2"
|
||||
cursor-icon = "1.1.0"
|
||||
dpi = { version = "0.1.1", path = "../dpi" }
|
||||
rwh_06 = { package = "raw-window-handle", version = "0.6", features = ["std"] }
|
||||
serde = { workspace = true, optional = true }
|
||||
smol_str = "0.3"
|
||||
|
||||
[target.'cfg(target_family = "wasm")'.dependencies]
|
||||
web-time = "1"
|
||||
|
||||
[build-dependencies]
|
||||
cfg_aliases = "0.2.1"
|
||||
1
winit-core/LICENSE
Symbolic link
1
winit-core/LICENSE
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../LICENSE
|
||||
1
winit-core/README.md
Symbolic link
1
winit-core/README.md
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../README.md
|
||||
26
winit-core/build.rs
Normal file
26
winit-core/build.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
use cfg_aliases::cfg_aliases;
|
||||
|
||||
fn main() {
|
||||
// The script doesn't depend on our code.
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
|
||||
// Setup cfg aliases.
|
||||
cfg_aliases! {
|
||||
// Systems.
|
||||
android_platform: { target_os = "android" },
|
||||
web_platform: { all(target_family = "wasm", target_os = "unknown") },
|
||||
macos_platform: { target_os = "macos" },
|
||||
ios_platform: { all(target_vendor = "apple", not(target_os = "macos")) },
|
||||
windows_platform: { target_os = "windows" },
|
||||
free_unix: { all(unix, not(target_vendor = "apple"), not(android_platform), not(target_os = "emscripten")) },
|
||||
redox: { target_os = "redox" },
|
||||
|
||||
// Native displays.
|
||||
x11_platform: { all(feature = "x11", free_unix, not(redox)) },
|
||||
wayland_platform: { all(feature = "wayland", free_unix, not(redox)) },
|
||||
orbital_platform: { redox },
|
||||
}
|
||||
|
||||
// Winit defined cfgs.
|
||||
println!("cargo:rustc-check-cfg=cfg(unreleased_changelogs)");
|
||||
}
|
||||
71
winit-core/src/as_any.rs
Normal file
71
winit-core/src/as_any.rs
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
use std::any::Any;
|
||||
|
||||
// NOTE: This is `pub`, but isn't actually exposed outside the crate.
|
||||
// NOTE: Marked as `#[doc(hidden)]` and underscored, because they can be quite difficult to use
|
||||
// correctly, see discussion in #4160.
|
||||
// FIXME: Remove and replace with a coercion once rust-lang/rust#65991 is in MSRV (1.86).
|
||||
#[doc(hidden)]
|
||||
pub trait AsAny: Any {
|
||||
#[doc(hidden)]
|
||||
fn __as_any(&self) -> &dyn Any;
|
||||
#[doc(hidden)]
|
||||
fn __as_any_mut(&mut self) -> &mut dyn Any;
|
||||
#[doc(hidden)]
|
||||
fn __into_any(self: Box<Self>) -> Box<dyn Any>;
|
||||
}
|
||||
|
||||
impl<T: Any> AsAny for T {
|
||||
#[inline(always)]
|
||||
fn __as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn __as_any_mut(&mut self) -> &mut dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn __into_any(self: Box<Self>) -> Box<dyn Any> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_dyn_casting {
|
||||
($trait:ident) => {
|
||||
impl dyn $trait + '_ {
|
||||
/// Downcast to the backend concrete type.
|
||||
///
|
||||
/// Returns `None` if the object was not from that backend.
|
||||
pub fn cast_ref<T: $trait>(&self) -> Option<&T> {
|
||||
let this: &dyn std::any::Any = self.__as_any();
|
||||
this.downcast_ref::<T>()
|
||||
}
|
||||
|
||||
/// Mutable downcast to the backend concrete type.
|
||||
///
|
||||
/// Returns `None` if the object was not from that backend.
|
||||
pub fn cast_mut<T: $trait>(&mut self) -> Option<&mut T> {
|
||||
let this: &mut dyn std::any::Any = self.__as_any_mut();
|
||||
this.downcast_mut::<T>()
|
||||
}
|
||||
|
||||
/// Owned downcast to the backend concrete type.
|
||||
///
|
||||
/// Returns `Err` with `self` if the object was not from that backend.
|
||||
pub fn cast<T: $trait>(self: Box<Self>) -> Result<Box<T>, Box<Self>> {
|
||||
let reference: &dyn std::any::Any = self.__as_any();
|
||||
if reference.is::<T>() {
|
||||
let this: Box<dyn std::any::Any> = self.__into_any();
|
||||
// Unwrap is okay, we just checked the type of `self` is `T`.
|
||||
Ok(this.downcast::<T>().unwrap())
|
||||
} else {
|
||||
Err(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub use impl_dyn_casting;
|
||||
2
winit-core/src/lib.rs
Normal file
2
winit-core/src/lib.rs
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#[macro_use]
|
||||
pub mod as_any;
|
||||
Loading…
Add table
Add a link
Reference in a new issue