1use bevy_ecs::prelude::*;
2use bevy_ecs::query::{QueryData, QueryFilter, QueryItem};
3use moonshine_kind::{prelude::*, Any};
4use moonshine_util::hierarchy::{WorldDescendantsDeepIter, WorldDescendantsWideIter};
5
6use crate::{Object, ObjectName, ObjectRebind, ObjectRef, ObjectWorldRef, Objects};
7
8pub trait ObjectHierarchy<T: Kind = Any>: ObjectRebind<T> + ObjectName {
12 fn parent(&self) -> Option<Self::Rebind<Any>>;
14
15 fn root(&self) -> Self::Rebind<Any> {
17 self.ancestors()
18 .last()
19 .unwrap_or_else(|| unsafe { self.rebind_any(self.entity()) })
21 }
22
23 fn is_root(&self) -> bool {
25 self.parent().is_none()
26 }
27
28 fn is_related_to<U: Kind>(&self, other: &impl ObjectHierarchy<U>) -> bool {
30 self.root().entity() == other.root().entity()
31 }
32
33 fn is_child(&self) -> bool {
35 self.parent().is_some()
36 }
37
38 fn is_child_of(&self, entity: Entity) -> bool {
40 self.parent()
41 .is_some_and(|object| object.entity() == entity)
42 }
43
44 fn children(&self) -> impl Iterator<Item = Self::Rebind<Any>>;
46
47 fn has_children(&self) -> bool {
49 self.children().next().is_some()
50 }
51
52 fn query_children<'a, Q: QueryData, F: QueryFilter>(
54 &'a self,
55 query: &'a Query<Q, F>,
56 ) -> impl Iterator<Item = QueryItem<'a, 'a, Q::ReadOnly>> + 'a {
57 self.children()
58 .filter_map(move |object| query.get(object.entity()).ok())
59 }
60
61 fn children_of_kind<'w, 's, 'a, U: Kind>(
63 &'a self,
64 objects: &'a Objects<'w, 's, U>,
65 ) -> impl Iterator<Item = Object<'w, 's, 'a, U>> + 'a {
66 self.children()
67 .filter_map(move |object| objects.get(object.entity()).ok())
68 }
69
70 fn find_child_of_kind<'w, 's, 'a, U: Kind>(
72 &self,
73 objects: &'a Objects<'w, 's, U>,
74 ) -> Option<Object<'w, 's, 'a, U>> {
75 self.children()
76 .find_map(|object| objects.get(object.entity()).ok())
77 }
78
79 fn ancestors(&self) -> impl Iterator<Item = Self::Rebind<Any>>;
81
82 fn self_and_ancestors(&self) -> impl Iterator<Item = Self::Rebind<Any>> {
84 std::iter::Iterator::chain(std::iter::once(self.as_any()), self.ancestors())
85 }
86
87 fn is_ancestor_of<U: Kind>(&self, other: &impl ObjectHierarchy<U>) -> bool
89 where
90 Self::Rebind<Any>: ObjectHierarchy<Any>,
91 {
92 other
93 .ancestors()
94 .any(|ancestor| ancestor.entity() == self.entity())
95 }
96
97 fn query_ancestors<'a, Q: QueryData, F: QueryFilter>(
99 &'a self,
100 query: &'a Query<Q, F>,
101 ) -> impl Iterator<Item = QueryItem<'a, 'a, Q::ReadOnly>> + 'a {
102 self.ancestors().filter_map(move |object| {
103 let entity = object.entity();
104 query.get(entity).ok()
105 })
106 }
107
108 fn query_self_and_ancestors<'a, Q: QueryData, F: QueryFilter>(
110 &'a self,
111 query: &'a Query<Q, F>,
112 ) -> impl Iterator<Item = QueryItem<'a, 'a, Q::ReadOnly>> + 'a {
113 self.self_and_ancestors().filter_map(move |object| {
114 let entity = object.entity();
115 query.get(entity).ok()
116 })
117 }
118
119 fn ancestors_of_kind<'w, 's, 'a, U: Kind>(
121 &'a self,
122 objects: &'a Objects<'w, 's, U>,
123 ) -> impl Iterator<Item = Object<'w, 's, 'a, U>> {
124 self.ancestors()
125 .filter_map(move |object| objects.get(object.entity()).ok())
126 }
127
128 fn self_and_ancestors_of_kind<'w, 's, 'a, U: Kind>(
130 &'a self,
131 objects: &'a Objects<'w, 's, U>,
132 ) -> impl Iterator<Item = Object<'w, 's, 'a, U>> {
133 self.self_and_ancestors()
134 .filter_map(move |object| objects.get(object.entity()).ok())
135 }
136
137 fn find_ancestor_of_kind<'w, 's, 'a, U: Kind>(
139 &self,
140 objects: &'a Objects<'w, 's, U>,
141 ) -> Option<Object<'w, 's, 'a, U>> {
142 self.ancestors()
143 .find_map(|object| objects.get(object.entity()).ok())
144 }
145
146 fn descendants_wide(&self) -> impl Iterator<Item = Self::Rebind<Any>>;
148
149 fn descendants_deep(&self) -> impl Iterator<Item = Self::Rebind<Any>>;
151
152 fn self_and_descendants_wide(&self) -> impl Iterator<Item = Self::Rebind<Any>> {
154 std::iter::Iterator::chain(std::iter::once(self.as_any()), self.descendants_wide())
155 }
156
157 fn self_and_descendants_deep(&self) -> impl Iterator<Item = Self::Rebind<Any>> {
159 std::iter::Iterator::chain(std::iter::once(self.as_any()), self.descendants_deep())
160 }
161
162 fn is_descendant_of(&self, entity: Entity) -> bool
164 where
165 Self::Rebind<Any>: ObjectHierarchy<Any>,
166 {
167 self.ancestors().any(|ancestor| ancestor.entity() == entity)
168 }
169
170 fn descendants_of_kind_wide<'w, 's, 'a, U: Kind>(
172 &'a self,
173 objects: &'a Objects<'w, 's, U>,
174 ) -> impl Iterator<Item = Object<'w, 's, 'a, U>> {
175 self.descendants_wide()
176 .filter_map(move |object| objects.get(object.entity()).ok())
177 }
178
179 fn descendants_of_kind_deep<'w, 's, 'a, U: Kind>(
181 &'a self,
182 objects: &'a Objects<'w, 's, U>,
183 ) -> impl Iterator<Item = Object<'w, 's, 'a, U>> {
184 self.descendants_deep()
185 .filter_map(move |object| objects.get(object.entity()).ok())
186 }
187
188 fn self_and_descendants_of_kind_wide<'w, 's, 'a, U: Kind>(
190 &'a self,
191 objects: &'a Objects<'w, 's, U>,
192 ) -> impl Iterator<Item = Object<'w, 's, 'a, U>> {
193 self.self_and_descendants_wide()
194 .filter_map(move |object| objects.get(object.entity()).ok())
195 }
196
197 fn self_and_descendants_of_kind_deep<'w, 's, 'a, U: Kind>(
199 &'a self,
200 objects: &'a Objects<'w, 's, U>,
201 ) -> impl Iterator<Item = Object<'w, 's, 'a, U>> {
202 self.self_and_descendants_deep()
203 .filter_map(move |object| objects.get(object.entity()).ok())
204 }
205
206 fn query_descendants_wide<'a, Q: QueryData, F: QueryFilter>(
208 &'a self,
209 query: &'a Query<Q, F>,
210 ) -> impl Iterator<Item = QueryItem<'a, 'a, Q::ReadOnly>> + 'a {
211 self.descendants_wide().filter_map(move |object| {
212 let entity = object.entity();
213 query.get(entity).ok()
214 })
215 }
216
217 fn query_descendants_deep<'a, Q: QueryData, F: QueryFilter>(
219 &'a self,
220 query: &'a Query<Q, F>,
221 ) -> impl Iterator<Item = QueryItem<'a, 'a, Q::ReadOnly>> + 'a {
222 self.descendants_deep().filter_map(move |object| {
223 let entity = object.entity();
224 query.get(entity).ok()
225 })
226 }
227
228 fn query_self_and_descendants_wide<'a, Q: QueryData, F: QueryFilter>(
230 &'a self,
231 query: &'a Query<Q, F>,
232 ) -> impl Iterator<Item = QueryItem<'a, 'a, Q::ReadOnly>> + 'a {
233 self.self_and_descendants_wide().filter_map(move |object| {
234 let entity = object.entity();
235 query.get(entity).ok()
236 })
237 }
238
239 fn query_self_and_descendants_deep<'a, Q: QueryData>(
241 &'a self,
242 query: &'a Query<Q>,
243 ) -> impl Iterator<Item = QueryItem<'a, 'a, Q::ReadOnly>> + 'a {
244 self.self_and_descendants_deep().filter_map(move |object| {
245 let entity = object.entity();
246 query.get(entity).ok()
247 })
248 }
249
250 fn find_descendant_of_kind_wide<'w, 's, 'a, U: Kind>(
252 &self,
253 objects: &'a Objects<'w, 's, U>,
254 ) -> Option<Object<'w, 's, 'a, U>> {
255 self.descendants_wide()
256 .find_map(|object| objects.get(object.entity()).ok())
257 }
258
259 fn find_descendant_of_kind_deep<'w, 's, 'a, U: Kind>(
261 &self,
262 objects: &'a Objects<'w, 's, U>,
263 ) -> Option<Object<'w, 's, 'a, U>> {
264 self.descendants_deep()
265 .find_map(|object| objects.get(object.entity()).ok())
266 }
267
268 fn path(&self) -> String {
270 let mut tokens = self
272 .self_and_ancestors()
273 .map(|ancestor| ancestor.name().unwrap_or_default().to_string())
274 .collect::<Vec<_>>();
275 tokens.reverse();
276 tokens.join("/")
277 }
278
279 fn find_by_path(&self, path: impl AsRef<str>) -> Option<Self::Rebind<Any>>;
300}
301
302impl<T: Kind> ObjectHierarchy<T> for Object<'_, '_, '_, T> {
303 fn parent(&self) -> Option<Self::Rebind<Any>> {
304 self.hierarchy
305 .parent(self.entity())
306 .map(|entity| unsafe { self.rebind_any(entity) })
308 }
309
310 fn children(&self) -> impl Iterator<Item = Self::Rebind<Any>> {
311 self.hierarchy
312 .children(self.entity())
313 .map(|entity| unsafe { self.rebind_any(entity) })
315 }
316
317 fn ancestors(&self) -> impl Iterator<Item = Self::Rebind<Any>> {
318 self.hierarchy
319 .ancestors(self.entity())
320 .map(|entity| unsafe { self.rebind_any(entity) })
322 }
323
324 fn descendants_wide(&self) -> impl Iterator<Item = Self::Rebind<Any>> {
325 self.hierarchy
326 .descendants_wide(self.entity())
327 .map(|entity| unsafe { self.rebind_any(entity) })
329 }
330
331 fn descendants_deep(&self) -> impl Iterator<Item = Self::Rebind<Any>> {
332 self.hierarchy
333 .descendants_deep(self.entity())
334 .map(|entity| unsafe { self.rebind_any(entity) })
336 }
337
338 fn find_by_path(&self, path: impl AsRef<str>) -> Option<Self::Rebind<Any>> {
339 let tail: Vec<&str> = path.as_ref().split('/').collect();
340 find_by_path(self.cast_into_any(), &tail)
341 }
342}
343
344impl<T: Kind> ObjectHierarchy<T> for ObjectRef<'_, '_, '_, T> {
345 fn parent(&self) -> Option<Self::Rebind<Any>> {
346 self.1.parent().map(|object| ObjectRef(self.0, object))
347 }
348
349 fn children(&self) -> impl Iterator<Item = Self::Rebind<Any>> {
350 self.1.children().map(|object| ObjectRef(self.0, object))
351 }
352
353 fn ancestors(&self) -> impl Iterator<Item = Self::Rebind<Any>> {
354 self.1.ancestors().map(|object| ObjectRef(self.0, object))
355 }
356
357 fn descendants_wide(&self) -> impl Iterator<Item = Self::Rebind<Any>> {
358 self.1
359 .descendants_wide()
360 .map(|object| ObjectRef(self.0, object))
361 }
362
363 fn descendants_deep(&self) -> impl Iterator<Item = Self::Rebind<Any>> {
364 self.1
365 .descendants_deep()
366 .map(|object| ObjectRef(self.0, object))
367 }
368
369 fn find_by_path(&self, path: impl AsRef<str>) -> Option<Self::Rebind<Any>> {
370 self.1
371 .find_by_path(path)
372 .map(|object| ObjectRef(self.0, object))
373 }
374}
375
376impl<T: Kind> ObjectHierarchy<T> for ObjectWorldRef<'_, T> {
377 fn parent(&self) -> Option<Self::Rebind<Any>> {
378 let &ChildOf(parent) = self.world.get(self.entity())?;
379 Some(unsafe { self.rebind_any(parent) })
381 }
382
383 fn children(&self) -> impl Iterator<Item = Self::Rebind<Any>> {
384 self.world
385 .get::<Children>(self.entity())
386 .into_iter()
387 .flat_map(|children| children.iter())
388 .map(|entity| unsafe { self.rebind_any(entity) })
390 }
391
392 fn ancestors(&self) -> impl Iterator<Item = Self::Rebind<Any>> {
393 std::iter::successors(self.parent(), |current| current.parent())
394 }
395
396 fn descendants_wide(&self) -> impl Iterator<Item = Self::Rebind<Any>> {
397 WorldDescendantsWideIter::new(self.world, self.entity())
398 .map(|entity| unsafe { self.rebind_any(entity) })
400 }
401
402 fn descendants_deep(&self) -> impl Iterator<Item = Self::Rebind<Any>> {
403 WorldDescendantsDeepIter::new(self.world, self.entity())
404 .map(|entity| unsafe { self.rebind_any(entity) })
406 }
407
408 fn find_by_path(&self, path: impl AsRef<str>) -> Option<Self::Rebind<Any>> {
409 let tail: Vec<&str> = path.as_ref().split('/').collect();
410 find_by_path(self.cast_into_any(), &tail)
411 }
412}
413
414fn find_by_path<T: ObjectHierarchy<Rebind<Any> = T>>(
415 curr: T,
416 tail: &[&str],
417) -> Option<T::Rebind<Any>> {
418 if tail.is_empty() {
419 return Some(curr);
420 }
421
422 let head = tail[0];
423 let tail = &tail[1..];
424
425 if head == "." || head.is_empty() {
426 find_by_path(curr, tail)
427 } else if head == ".." {
428 if let Some(parent) = curr.parent() {
429 find_by_path(parent, tail)
430 } else {
431 None
432 }
433 } else if head == "*" {
434 for child in curr.children() {
435 if let Some(result) = find_by_path(child, tail) {
436 return Some(result);
437 }
438 }
439 None
440 } else if let Some(child) = curr
441 .children()
442 .find(|part| part.name().is_some_and(|name| name == head))
443 {
444 find_by_path(child, tail)
445 } else {
446 None
447 }
448}