engine/gavania-core/src/game/handle.rs
2024-08-23 13:22:09 +02:00

76 lines
1.4 KiB
Rust

use std::{
ops::Deref,
sync::{Arc, Weak},
};
use anyhow::{anyhow, Result};
pub struct StrongHandle<T> {
strong: Arc<T>,
}
impl<T> StrongHandle<T> {
pub fn new(t: T) -> Self {
Self {
strong: Arc::new(t),
}
}
}
impl<T> Deref for StrongHandle<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.strong
}
}
#[derive(Debug)]
pub struct WeakHandle<T> {
weak: Weak<T>,
}
impl<T> WeakHandle<T> {
pub fn on<F, R>(&self, f: F) -> Result<R>
where
F: FnOnce(&T) -> Result<R>,
{
let strong: Arc<T> = self
.weak
.upgrade()
.ok_or(anyhow!("failed to get strong handle"))?;
f(&strong)
}
pub fn upgrade(&self) -> StrongHandle<T> {
StrongHandle {
strong: self.weak.upgrade().unwrap(),
}
}
pub fn try_upgrade(&self) -> Result<StrongHandle<T>> {
Ok(StrongHandle {
strong: self
.weak
.upgrade()
.ok_or(anyhow!("failed to upgrade WeakHandle"))?,
})
}
}
impl<T> Clone for WeakHandle<T> {
fn clone(&self) -> Self {
Self {
weak: self.weak.clone(),
}
}
}
impl<T> From<&StrongHandle<T>> for WeakHandle<T> {
fn from(handle: &StrongHandle<T>) -> Self {
Self {
weak: Arc::downgrade(&handle.strong),
}
}
}