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§

source

fn interface(&self) -> &'static str

Return the interface name of the concrete object.

source

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.

source

fn cast_mut<T: 'static>(&mut self) -> Option<&mut T>

source

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.

source

fn type_id(&self) -> TypeId

Type id of the concrete object type. If this is an enum of multiple object types, this should return the type id of the inhabited variant.

Implementors§