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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use hecs::TypeInfo;
use smallvec::smallvec;
use std::any::type_name;
use crate::borrow::{Borrows, ComponentBorrow};
#[derive(Copy, Clone, PartialOrd, Ord, Eq, PartialEq)]
pub struct Access {
pub(crate) name: &'static str,
pub(crate) info: TypeInfo,
pub(crate) exclusive: bool,
}
impl std::fmt::Debug for Access {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.exclusive {
write!(f, "mut {}", self.name)
} else {
write!(f, "{}", self.name)
}
}
}
impl Access {
pub fn new<T: IntoAccess>() -> Self {
T::access()
}
#[inline]
pub fn info(&self) -> TypeInfo {
self.info
}
#[inline]
pub fn exclusive(&self) -> bool {
self.exclusive
}
pub(crate) fn id(&self) -> std::any::TypeId {
self.info.id()
}
pub(crate) fn name(&self) -> &'static str {
self.name
}
}
pub trait IntoAccess {
fn access() -> Access;
fn compatible<U: IntoAccess>() -> bool;
}
impl<T: 'static> IntoAccess for &T {
fn access() -> Access {
Access {
info: TypeInfo::of::<T>(),
exclusive: false,
name: type_name::<T>(),
}
}
fn compatible<U: IntoAccess>() -> bool {
let l = Self::access();
let r = U::access();
l.info == r.info && !r.exclusive
}
}
impl<T: 'static> IntoAccess for &mut T {
fn access() -> Access {
Access {
info: TypeInfo::of::<T>(),
exclusive: true,
name: type_name::<T>(),
}
}
fn compatible<U: IntoAccess>() -> bool {
let l = Self::access();
let r = U::access();
l.info == r.info
}
}
pub struct AllAccess;
pub trait Subset: ComponentBorrow {
fn is_subset<U: ComponentBorrow>() -> bool;
}
impl<A: IntoAccess> Subset for A {
fn is_subset<U: ComponentBorrow>() -> bool {
U::has::<A>()
}
}
impl<A: IntoAccess> ComponentBorrow for A {
fn borrows() -> Borrows {
smallvec![A::access()]
}
fn has<U: IntoAccess>() -> bool {
A::compatible::<U>()
}
}
impl ComponentBorrow for AllAccess {
fn borrows() -> Borrows {
smallvec![]
}
fn has<U: IntoAccess>() -> bool {
true
}
}