use std::{fmt, hash, sync::Arc};
use crate::{
wire::{Arg, Backend, BackendWeak},
Interface,
};
#[derive(Clone)]
pub struct Object(Arc<ObjectInner>);
struct ObjectInner {
backend: BackendWeak,
client_side: bool,
id: u64,
interface: String,
version: u32,
}
impl PartialEq for Object {
fn eq(&self, rhs: &Self) -> bool {
Arc::ptr_eq(&self.0, &rhs.0)
}
}
impl Eq for Object {}
impl hash::Hash for Object {
fn hash<H: hash::Hasher>(&self, hasher: &mut H) {
self.0.id.hash(hasher)
}
}
impl fmt::Debug for Object {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Object(_, {})", self.id())
}
}
impl Object {
pub(crate) fn for_new_id(
backend: BackendWeak,
id: u64,
client_side: bool,
interface: String,
version: u32,
) -> Self {
Self(Arc::new(ObjectInner {
backend,
id,
client_side,
interface,
version,
}))
}
pub fn backend(&self) -> Option<Backend> {
self.0.backend.upgrade()
}
pub(crate) fn backend_weak(&self) -> &BackendWeak {
&self.0.backend
}
pub fn id(&self) -> u64 {
self.0.id
}
pub fn interface(&self) -> &str {
&self.0.interface
}
pub fn version(&self) -> u32 {
self.0.version
}
pub fn request(&self, opcode: u32, args: &[Arg]) {
if let Some(backend) = self.backend() {
backend.request(self.0.id, opcode, args);
}
}
pub(crate) fn downcast_unchecked<T: Interface>(self) -> T {
T::new_unchecked(self)
}
pub(crate) fn as_arg(&self) -> Arg<'_> {
Arg::Id(self.0.id)
}
pub fn downcast<T: Interface>(self) -> Option<T> {
if (self.0.client_side, self.interface()) == (T::CLIENT_SIDE, T::NAME) {
Some(self.downcast_unchecked())
} else {
None
}
}
}