pub trait AnyObject: 'static + Sized {
// Required methods
fn interface(&self) -> &'static str;
fn cast<T: 'static>(&self) -> Option<&T>;
fn cast_mut<T: 'static>(&mut self) -> Option<&mut T>;
fn new_singleton_state(&self) -> Box<dyn Any>;
fn type_id(&self) -> TypeId;
}
Expand description
A polymorphic object, i.e. it’s an union of multiple objects types.
A trait for storing “type erased” objects. This trait is separated from the
bigger Object
trait to keep it away from the pollution of the Ctx
parameter.
Example
Normally you won’t need to worry about implementing this trait, as this can
be generated automatically by #[derive(Object)]
,
but here is an example of how to implement this trait.
use std::any::Any;
use wl_server::objects::{AnyObject, MonoObject};
// Define two monomorphic objects
struct A;
impl MonoObject for A {
type SingletonState = usize;
const INTERFACE: &'static str = "A";
fn new_singleton_state() -> Option<Self::SingletonState> {
Some(0usize)
}
}
struct B;
impl MonoObject for B {
type SingletonState = ();
const INTERFACE: &'static str = "B";
fn new_singleton_state() -> Option<Self::SingletonState> {
Some(())
}
}
// Define a polymorphic object as the union of the two monomorphic objects
enum MyObject {
A(A),
B(B),
}
impl AnyObject for MyObject {
fn interface(&self) -> &'static str {
match self {
MyObject::A(_) => A::INTERFACE,
MyObject::B(_) => B::INTERFACE,
}
}
fn type_id(&self) -> std::any::TypeId {
match self {
MyObject::A(_) => std::any::TypeId::of::<A>(),
MyObject::B(_) => std::any::TypeId::of::<B>(),
}
}
fn cast<T: 'static>(&self) -> Option<&T> {
match self {
MyObject::A(a) => (a as &dyn Any).downcast_ref::<T>(),
MyObject::B(b) => (b as &dyn Any).downcast_ref::<T>(),
}
}
fn cast_mut<T: 'static>(&mut self) -> Option<&mut T> {
match self {
MyObject::A(a) => (a as &mut dyn Any).downcast_mut::<T>(),
MyObject::B(b) => (b as &mut dyn Any).downcast_mut::<T>(),
}
}
fn new_singleton_state(&self) -> Option<Box<dyn std::any::Any>> {
match self {
MyObject::A(_) =>
<A as MonoObject>::new_singleton_state().map(|s| Box::new(s) as _),
MyObject::B(_) =>
<B as MonoObject>::new_singleton_state().map(|s| Box::new(s) as _),
}
}
}
Which is equivalent to:
#[derive(Object)]
enum MyObject {
A(A),
B(B),
}
Required Methods§
sourcefn cast<T: 'static>(&self) -> Option<&T>
fn cast<T: 'static>(&self) -> Option<&T>
Cast the object into a more concrete type. This is generated by
#[derive(Object)]
for casting a enum of many object types to the
concrete type. This should also work if T == Self
.
sourcefn cast_mut<T: 'static>(&mut self) -> Option<&mut T>
fn cast_mut<T: 'static>(&mut self) -> Option<&mut T>
See AnyObject::cast
sourcefn new_singleton_state(&self) -> Box<dyn Any>
fn new_singleton_state(&self) -> Box<dyn Any>
Generate the initial value for the singleton state, see
MonoObject::SingletonState
. If None
is returned, there will be no
state associated with this object type.
Note
This concrete type of the returned value must be consistent with
MonoObject::SingletonState
for the MonoObject
object contained in
this AnyObject
, otherwise the Store
implementation might panic.
i.e. if Self::type_id
returns std::any::TypeId::of::<A>()
, then
this method must return Box::new(<A as MonoObject>::new_singleton_state())
.
You don’t need to worry about this if you use #[derive(Object)]
and #[wayland_object]
macros to generate the implementation.