1use serde::{Deserialize, Serialize};
2use specs::{Component, DerefFlaggedStorage, SystemData};
3use std::{
4 any::Any,
5 ops::Deref,
6 sync::{Arc, Weak},
7};
8
9pub trait Link: Sized + Send + Sync + 'static {
10 type Error;
11
12 type CreateData<'a>: SystemData<'a>;
13 fn create(this: &LinkHandle<Self>, data: &mut Self::CreateData<'_>) -> Result<(), Self::Error>;
14
15 type PersistData<'a>: SystemData<'a>;
16 fn persist(this: &LinkHandle<Self>, data: &mut Self::PersistData<'_>) -> bool;
17
18 type DeleteData<'a>: SystemData<'a>;
19 fn delete(this: &LinkHandle<Self>, data: &mut Self::DeleteData<'_>);
20}
21
22pub trait Role {
23 type Link: Link;
24}
25
26#[derive(Serialize, Deserialize, Debug)]
27pub struct Is<R: Role> {
28 #[serde(bound(serialize = "R::Link: Serialize"))]
29 #[serde(bound(deserialize = "R::Link: Deserialize<'de>"))]
30 link: LinkHandle<R::Link>,
31}
32
33impl<R: Role> Is<R> {
34 pub fn delete(&self, data: &mut <R::Link as Link>::DeleteData<'_>) {
35 Link::delete(&self.link, data)
36 }
37
38 pub fn get_link(&self) -> &LinkHandle<R::Link> { &self.link }
39}
40
41impl<R: Role> Clone for Is<R> {
42 fn clone(&self) -> Self {
43 Self {
44 link: self.link.clone(),
45 }
46 }
47}
48
49impl<R: Role> Deref for Is<R> {
50 type Target = R::Link;
51
52 fn deref(&self) -> &Self::Target { &self.link }
53}
54
55impl<R: Role + 'static> Component for Is<R>
56where
57 R::Link: Send + Sync + 'static,
58{
59 type Storage = DerefFlaggedStorage<Self, specs::VecStorage<Self>>;
60}
61
62#[derive(Serialize, Deserialize, Debug)]
63pub struct LinkHandle<L: Link> {
64 link: Arc<L>,
65}
66
67impl<L: Link> Clone for LinkHandle<L> {
68 fn clone(&self) -> Self {
69 Self {
70 link: Arc::clone(&self.link),
71 }
72 }
73}
74
75impl<L: Link> LinkHandle<L> {
76 pub fn from_link(link: L) -> Self {
77 Self {
78 link: Arc::new(link),
79 }
80 }
81
82 pub fn make_role<R: Role<Link = L>>(&self) -> Is<R> { Is { link: self.clone() } }
83
84 pub fn downgrade(&self) -> WeakLinkHandle<L> {
85 WeakLinkHandle {
86 link: Arc::downgrade(&self.link),
87 }
88 }
89}
90
91impl<L: Link> Deref for LinkHandle<L> {
92 type Target = L;
93
94 fn deref(&self) -> &Self::Target { &self.link }
95}
96
97#[derive(Serialize, Deserialize, Debug)]
99pub struct WeakLinkHandle<L: Link> {
100 #[serde(skip)]
101 link: Weak<L>,
102}
103
104impl<L: Link> Clone for WeakLinkHandle<L> {
105 fn clone(&self) -> Self {
106 Self {
107 link: Weak::clone(&self.link),
108 }
109 }
110}
111
112impl<L: Link> WeakLinkHandle<L> {
113 pub fn upgrade(&self) -> Option<LinkHandle<L>> {
114 Some(LinkHandle {
115 link: self.link.upgrade()?,
116 })
117 }
118
119 pub fn into_dyn(self) -> DynWeakLinkHandle {
120 DynWeakLinkHandle {
121 inner: InnerDynWeakLinkHandle(self.link as DynWeak),
122 }
123 }
124}
125
126type DynWeak = Weak<dyn Any + Sync + Send>;
127
128#[derive(Clone)]
129struct InnerDynWeakLinkHandle(DynWeak);
130
131impl Default for InnerDynWeakLinkHandle {
132 fn default() -> Self { Self(Weak::<()>::new() as DynWeak) }
133}
134
135impl PartialEq for InnerDynWeakLinkHandle {
136 fn eq(&self, other: &Self) -> bool { self.0.ptr_eq(&other.0) }
137}
138
139impl Eq for InnerDynWeakLinkHandle {}
140
141#[derive(Clone, Serialize, Deserialize, PartialEq, Eq)]
143pub struct DynWeakLinkHandle {
144 #[serde(skip)]
145 inner: InnerDynWeakLinkHandle,
146}
147
148impl std::fmt::Debug for DynWeakLinkHandle {
149 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
150 f.debug_tuple("DynWeakLinkHandle")
151 .field(&self.exists())
152 .finish()
153 }
154}
155
156impl DynWeakLinkHandle {
157 pub fn exists(&self) -> bool { self.inner.0.strong_count() > 0 }
159
160 pub fn is_link(&self, link: &LinkHandle<impl Link>) -> bool {
162 std::ptr::addr_eq(self.inner.0.as_ptr(), Arc::as_ptr(&link.link))
163 }
164}