1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
use std::any::{type_name, Any};
use std::fmt::Debug;
use crate::component::{
HandleMut as ComponentHandleMut,
IntoParts as IntoComponentParts,
};
use crate::system::{Metadata as SystemMetadata, Param as SystemParam};
use crate::uid::Uid;
use crate::World;
/// A component which has a single instance in the [`World`].
pub trait Sole: Any + IntoComponentParts
{
fn id() -> Uid
where
Self: Sized;
fn type_reflection() -> Option<&'static crate::reflection::Type>
where
Self: Sized;
/// Returns the name of this component.
fn name(&self) -> &'static str;
}
impl dyn Sole
{
pub fn downcast_mut<Real: 'static>(&mut self) -> Option<&mut Real>
{
(self as &mut dyn Any).downcast_mut()
}
pub fn downcast_ref<Real: 'static>(&self) -> Option<&Real>
{
(self as &dyn Any).downcast_ref()
}
pub fn is<Other: 'static>(&self) -> bool
{
(self as &dyn Any).is::<Other>()
}
}
impl Debug for dyn Sole
{
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
{
formatter.debug_struct("Sole").finish_non_exhaustive()
}
}
/// Holds a reference to a singleton component.
#[derive(Debug)]
pub struct Single<'world, SoleT: Sole>
{
sole: Option<ComponentHandleMut<'world, SoleT>>,
}
impl<'world, SoleT> Single<'world, SoleT>
where
SoleT: Sole,
{
/// Returns a reference to `SoleT` if it exists. If not, returns `Err`.
pub fn get(&self) -> Result<&SoleT, DoesNotExistError>
{
self.sole
.as_deref()
.ok_or_else(|| DoesNotExistError { name: type_name::<SoleT>() })
}
/// Returns a mutable reference to `SoleT` if it exists. If not, returns `Err`.
pub fn get_mut(&mut self) -> Result<&mut SoleT, DoesNotExistError>
{
self.sole
.as_deref_mut()
.ok_or_else(|| DoesNotExistError { name: type_name::<SoleT>() })
}
pub(crate) fn new(world: &'world World) -> Self
{
let sole = world
.get_entity(SoleT::id())
.and_then(|ent| ent.get_with_id_mut::<SoleT>(SoleT::id()));
Self { sole }
}
}
impl<'world, SoleT> SystemParam<'world> for Single<'world, SoleT>
where
SoleT: Sole,
{
type Input = ();
fn new(world: &'world World, _system_metadata: &SystemMetadata) -> Self
{
Self::new(world)
}
}
#[derive(Debug, thiserror::Error)]
#[error("Sole {name} does not exist")]
pub struct DoesNotExistError
{
pub name: &'static str,
}
|