1use crate::component::{ComponentDesc, ComponentValue};
2
3use super::Metadata;
4
5component! {
6 pub exclusive: Exclusive,
10
11 }
17
18pub struct Exclusive;
22
23impl<T: ComponentValue> Metadata<T> for Exclusive {
29 fn attach(_: ComponentDesc, buffer: &mut crate::buffer::ComponentBuffer) {
30 buffer.set(exclusive(), Exclusive);
31 }
32}
33
34#[cfg(test)]
41mod test {
42 use alloc::sync::Arc;
43
44 use super::*;
45
46 component! {
47 a(id): Arc<()> => [ Exclusive ],
48 }
49
50 #[test]
51 #[cfg(feature = "flume")]
52 fn exclusive_set() {
53 use crate::{
54 entity_ids,
55 events::{Event, EventKind, EventSubscriber},
56 relation::RelationExt,
57 relations_like, Entity, EntityIds, Query, QueryBorrow, Relations, World,
58 };
59 use alloc::{sync::Arc, vec, vec::Vec};
60 use itertools::Itertools;
61 use pretty_assertions::assert_eq;
62
63 let mut world = World::new();
64
65 let (tx, rx) = flume::unbounded();
66 world.subscribe(
67 tx.filter_arch(a.with_relation())
68 .filter(|_, v| v.key.id == a.id()),
69 );
70
71 type Expected<'a> = &'a [(Entity, Vec<(Entity, &'a Arc<()>)>)];
72
73 fn ensure(mut query: QueryBorrow<(EntityIds, Relations<Arc<()>>)>, expected: Expected) {
74 assert_eq!(
75 query
76 .iter()
77 .map(|v| (v.0, v.1.collect_vec()))
78 .sorted()
79 .collect_vec(),
80 expected
81 );
82 }
83
84 let shared = Arc::new(());
85
86 let id1 = world.spawn();
87 let id2 = world.spawn();
88 let id3 = Entity::builder()
89 .set(a(id2), shared.clone())
90 .set(a(id2), shared.clone())
91 .set(a(id1), shared.clone())
92 .spawn(&mut world);
93
94 let mut query = Query::new((entity_ids(), relations_like(a)));
95
96 ensure(
97 query.borrow(&world),
98 &[(id1, vec![]), (id2, vec![]), (id3, vec![(id1, &shared)])],
99 );
100
101 world.set(id1, a(id2), shared.clone()).unwrap();
102
103 assert_eq!(
104 rx.drain().collect_vec(),
105 [
106 Event {
107 id: id3,
108 key: a(id1).key(),
109 kind: EventKind::Added
110 },
111 Event {
112 id: id1,
113 key: a(id2).key(),
114 kind: EventKind::Added
115 }
116 ]
117 );
118
119 world.set(id3, a(id2), shared.clone()).unwrap();
120
121 ensure(
122 query.borrow(&world),
123 &[
124 (id1, vec![(id2, &shared)]),
125 (id2, vec![]),
126 (id3, vec![(id2, &shared)]),
127 ],
128 );
129
130 world.set(id1, a(id3), shared.clone()).unwrap();
131
132 assert_eq!(
133 rx.drain().collect_vec(),
134 [
135 Event {
136 id: id3,
137 key: a(id1).key(),
138 kind: EventKind::Removed
139 },
140 Event {
141 id: id3,
142 key: a(id2).key(),
143 kind: EventKind::Added
144 },
145 Event {
146 id: id1,
147 key: a(id2).key(),
148 kind: EventKind::Removed
149 },
150 Event {
151 id: id1,
152 key: a(id3).key(),
153 kind: EventKind::Added
154 },
155 ]
156 );
157
158 ensure(
159 query.borrow(&world),
160 &[
161 (id1, vec![(id3, &shared)]),
162 (id2, vec![]),
163 (id3, vec![(id2, &shared)]),
164 ],
165 );
166
167 Entity::builder()
168 .set(a(id2), shared.clone())
169 .set(a(id1), shared.clone())
170 .set(a(id3), shared.clone())
171 .set(a(id1), shared.clone())
172 .set(a(id1), shared.clone())
173 .append_to(&mut world, id1)
174 .unwrap();
175
176 ensure(
177 query.borrow(&world),
178 &[
179 (id1, vec![(id1, &shared)]),
180 (id2, vec![]),
181 (id3, vec![(id2, &shared)]),
182 ],
183 );
184
185 assert_eq!(
186 rx.drain().collect_vec(),
187 [
188 Event {
189 id: id1,
190 key: a(id3).key(),
191 kind: EventKind::Removed
192 },
193 Event {
194 id: id1,
195 key: a(id1).key(),
196 kind: EventKind::Added
197 }
198 ]
199 );
200
201 drop(world);
202
203 assert_eq!(
204 rx.drain().sorted_by_key(|v| v.id).collect_vec(),
205 [
206 Event {
207 id: id1,
208 key: a(id1).key(),
209 kind: EventKind::Removed
210 },
211 Event {
212 id: id3,
213 key: a(id2).key(),
214 kind: EventKind::Removed
215 }
216 ]
217 );
218
219 assert_eq!(Arc::strong_count(&shared), 1);
221 }
222}