diff --git a/wayland-backend/Cargo.toml b/wayland-backend/Cargo.toml index 3136d3f716c..1377a3ac044 100644 --- a/wayland-backend/Cargo.toml +++ b/wayland-backend/Cargo.toml @@ -14,10 +14,10 @@ readme = "README.md" build = "build.rs" [dependencies] +as-any = "0.3" wayland-sys = { version = "0.31.0", path = "../wayland-sys", features = [] } log = { version = "0.4", optional = true } scoped-tls = "1.0" -downcast-rs = "1.2" raw-window-handle = { version = "0.5.0", optional = true } [dependencies.smallvec] diff --git a/wayland-backend/src/client_api.rs b/wayland-backend/src/client_api.rs index 9908baa6548..59dc5389fef 100644 --- a/wayland-backend/src/client_api.rs +++ b/wayland-backend/src/client_api.rs @@ -12,6 +12,8 @@ use super::client_impl; pub use crate::types::client::{InvalidId, NoWaylandLib, WaylandError}; +use as_any::AsAny; + /// A trait representing your data associated to an object /// /// You will only be given access to it as a `&` reference, so you @@ -19,7 +21,7 @@ pub use crate::types::client::{InvalidId, NoWaylandLib, WaylandError}; /// /// The methods of this trait will be invoked internally every time a /// new object is created to initialize its data. -pub trait ObjectData: downcast_rs::DowncastSync { +pub trait ObjectData: Send + Sync + AsAny { /// Dispatch an event for the associated object /// /// If the event has a `NewId` argument, the callback must return the object data @@ -58,8 +60,6 @@ impl std::fmt::Debug for dyn ObjectData { } } -downcast_rs::impl_downcast!(sync ObjectData); - /// An ID representing a Wayland object /// /// The backend internally tracks which IDs are still valid, invalidates them when the protocol object they diff --git a/wayland-backend/src/rs/server_impl/handle.rs b/wayland-backend/src/rs/server_impl/handle.rs index 0ec5de8e4cf..5081166495a 100644 --- a/wayland-backend/src/rs/server_impl/handle.rs +++ b/wayland-backend/src/rs/server_impl/handle.rs @@ -18,6 +18,8 @@ use super::{ InnerClientId, InnerGlobalId, InnerObjectId, ObjectData, ObjectId, }; +use as_any::Downcast; + pub(crate) type PendingDestructor = (Arc>, InnerClientId, InnerObjectId); #[derive(Debug)] @@ -269,7 +271,7 @@ impl InnerHandle { } } -pub(crate) trait ErasedState: downcast_rs::Downcast { +pub(crate) trait ErasedState: as_any::AsAny { fn object_info(&self, id: InnerObjectId) -> Result; fn insert_client( &mut self, @@ -302,8 +304,6 @@ pub(crate) trait ErasedState: downcast_rs::Downcast { fn flush(&mut self, client: Option) -> std::io::Result<()>; } -downcast_rs::impl_downcast!(ErasedState); - impl ErasedState for State { fn object_info(&self, id: InnerObjectId) -> Result { self.clients.get_client(id.client_id.clone())?.object_info(id) diff --git a/wayland-backend/src/server_api.rs b/wayland-backend/src/server_api.rs index 6e3565db1c0..b4e6b6abe10 100644 --- a/wayland-backend/src/server_api.rs +++ b/wayland-backend/src/server_api.rs @@ -11,6 +11,21 @@ pub use crate::types::server::{Credentials, DisconnectReason, GlobalInfo, InitEr use super::server_impl; +use as_any::AsAny; + +/// Extends `AsAny` to support `Sync` traits that thus support `Arc` downcasting as well. +pub trait IntoAnyArc: Send + Sync + AsAny { + /// Convert `Arc` (where `Trait: Downcast`) to `Arc`. `Arc` can then be + /// further `downcast` into `Arc` where `ConcreteType` implements `Trait`. + fn into_any_arc(self: Arc) -> Arc; +} + +impl IntoAnyArc for T { + fn into_any_arc(self: Arc) -> Arc { + self + } +} + /// A trait representing your data associated to an object /// /// You will only be given access to it as a `&` reference, so you @@ -18,7 +33,7 @@ use super::server_impl; /// /// The methods of this trait will be invoked internally every time a /// new object is created to initialize its data. -pub trait ObjectData: downcast_rs::DowncastSync { +pub trait ObjectData: IntoAnyArc { /// Dispatch a request for the associated object /// /// If the request has a `NewId` argument, the callback must return the object data @@ -47,8 +62,6 @@ pub trait ObjectData: downcast_rs::DowncastSync { } } -downcast_rs::impl_downcast!(sync ObjectData); - impl std::fmt::Debug for dyn ObjectData { #[cfg_attr(coverage, coverage(off))] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -57,7 +70,7 @@ impl std::fmt::Debug for dyn ObjectData { } /// A trait representing the handling of new bound globals -pub trait GlobalHandler: downcast_rs::DowncastSync { +pub trait GlobalHandler: Send + Sync + AsAny { /// Check if given client is allowed to interact with given global /// /// If this function returns false, the client will not be notified of the existence @@ -102,10 +115,8 @@ impl std::fmt::Debug for dyn GlobalHandler { } } -downcast_rs::impl_downcast!(sync GlobalHandler); - /// A trait representing your data associated to a client -pub trait ClientData: downcast_rs::DowncastSync { +pub trait ClientData: Send + Sync + AsAny { /// Notification that the client was initialized fn initialized(&self, _client_id: ClientId) {} /// Notification that the client is disconnected @@ -128,8 +139,6 @@ impl std::fmt::Debug for dyn ClientData { impl ClientData for () {} -downcast_rs::impl_downcast!(sync ClientData); - /// An ID representing a Wayland object /// /// The backend internally tracks which IDs are still valid, invalidates them when the protocol object they diff --git a/wayland-backend/src/sys/server_impl/mod.rs b/wayland-backend/src/sys/server_impl/mod.rs index d80b2d5158e..3a3d1417fc7 100644 --- a/wayland-backend/src/sys/server_impl/mod.rs +++ b/wayland-backend/src/sys/server_impl/mod.rs @@ -18,6 +18,7 @@ use crate::protocol::{ check_for_signature, same_interface, AllowNull, Argument, ArgumentType, Interface, Message, ObjectInfo, ANONYMOUS_INTERFACE, }; +use as_any::Downcast; use scoped_tls::scoped_thread_local; use smallvec::SmallVec; @@ -822,7 +823,7 @@ impl InnerHandle { } } -pub(crate) trait ErasedState: downcast_rs::Downcast { +pub(crate) trait ErasedState: as_any::AsAny { fn object_info(&self, id: InnerObjectId) -> Result; fn insert_client( &self, @@ -857,8 +858,6 @@ pub(crate) trait ErasedState: downcast_rs::Downcast { fn display_ptr(&self) -> *mut wl_display; } -downcast_rs::impl_downcast!(ErasedState); - impl ErasedState for State { fn object_info(&self, id: InnerObjectId) -> Result { if !id.alive.load(Ordering::Acquire) { diff --git a/wayland-backend/tests/rs_sys_impls.rs b/wayland-backend/tests/rs_sys_impls.rs index 45d384cbb5d..27761345f86 100644 --- a/wayland-backend/tests/rs_sys_impls.rs +++ b/wayland-backend/tests/rs_sys_impls.rs @@ -107,17 +107,17 @@ mod server { fn test_impls() { // ObjectData assert_impl!( - dyn server::ObjectData<()>: std::fmt::Debug, downcast_rs::DowncastSync + dyn server::ObjectData<()>: std::fmt::Debug, Send, Sync, as_any::AsAny ); // GlobalHandler assert_impl!( - dyn server::GlobalHandler<()>: std::fmt::Debug, downcast_rs::DowncastSync + dyn server::GlobalHandler<()>: std::fmt::Debug, Send, Sync, as_any::AsAny ); // ClientData assert_impl!( - dyn server::ClientData: std::fmt::Debug, downcast_rs::DowncastSync + dyn server::ClientData: std::fmt::Debug, Send, Sync, as_any::AsAny ); // ObjectId @@ -150,7 +150,7 @@ mod client { fn test_impls() { // ObjectData assert_impl!( - dyn client::ObjectData: std::fmt::Debug, downcast_rs::DowncastSync + dyn client::ObjectData: std::fmt::Debug, Send, Sync, as_any::AsAny ); // ObjectId diff --git a/wayland-server/Cargo.toml b/wayland-server/Cargo.toml index 020d6f37ad8..116e6e895a6 100644 --- a/wayland-server/Cargo.toml +++ b/wayland-server/Cargo.toml @@ -15,10 +15,10 @@ readme = "README.md" [dependencies] wayland-backend = { version = "0.3.0", path = "../wayland-backend" } wayland-scanner = { version = "0.31.0", path = "../wayland-scanner" } +as-any = "0.3" bitflags = "2" log = { version = "0.4", optional = true } nix = { version = "0.26.0", default-features = false } -downcast-rs = "1.2" io-lifetimes = "2" [package.metadata.docs.rs] diff --git a/wayland-server/src/client.rs b/wayland-server/src/client.rs index e98d67f52a8..d80455bb8a6 100644 --- a/wayland-server/src/client.rs +++ b/wayland-server/src/client.rs @@ -29,6 +29,7 @@ impl Client { /// /// Returns [`None`] if the provided `Data` type parameter is not the correct one. pub fn get_data(&self) -> Option<&Data> { + use as_any::Downcast; (*self.data).downcast_ref() }