xecs/group/non_owning/
mod.rs

1use std::{any::TypeId, marker::PhantomData};
2use crate::{component::{Component, ComponentStorage}, entity::EntityId, sparse_set::SparseSet};
3use super::Group;
4
5mod query;
6
7pub use query::{
8    IterRefRef,
9    IterRefMut,
10    IterMutRef,
11    IterMutMut
12};
13
14
15pub struct NonOwningData {
16    sparse_set : SparseSet<EntityId,(usize,usize)>,
17    type_a : TypeId,
18    type_b : TypeId
19}
20
21impl PartialEq for NonOwningData {
22    fn eq(&self, other: &Self) -> bool {
23        self.type_a == other.type_a && self.type_b == other.type_b
24    }
25}
26
27impl NonOwningData {
28    pub(in crate) fn len(&self) -> usize {
29        self.sparse_set.len()
30    }
31    pub(in crate) fn types(&self) -> (TypeId,TypeId) {
32        (self.type_a,self.type_b)
33    }
34
35    pub(in crate) fn owned(&self,_type_id : TypeId) -> bool {
36        false
37    }
38
39    pub(in crate) fn owning(&self) -> Vec<TypeId> {
40        vec![]
41    }
42
43    pub(in crate) fn in_components( &self,
44                id : EntityId,
45                comp_a : &Box<dyn ComponentStorage>,
46                comp_b : &Box<dyn ComponentStorage>) -> bool {
47        comp_a.has(id) && comp_b.has(id)
48    }
49    pub(in crate) fn in_group(&self,
50                id : EntityId,
51                comp_a : &Box<dyn ComponentStorage>,
52                comp_b : &Box<dyn ComponentStorage>) -> bool {
53        if !self.in_components(id,comp_a,comp_b) {
54            return false;
55        }
56
57        self.sparse_set.exist(id)
58    }
59    pub(in crate) fn add(&mut self,
60           id : EntityId,
61           comp_a : &Box<dyn ComponentStorage>,
62           comp_b : &Box<dyn ComponentStorage>) {
63        if !self.in_components(id,&comp_a,&comp_b) {
64            return;
65        }
66        if self.in_group(id,&comp_a,&comp_b) {
67            return;
68        }
69
70        // get index in component storage
71        // This unwrap never fails because the in_components() ensures that it's already in components.
72        let index_a = comp_a.index(id).unwrap();
73        let index_b = comp_b.index(id).unwrap();
74
75        self.sparse_set.add(id,(index_a,index_b));
76    }
77
78    pub(in crate) fn remove(&mut self,
79              id : EntityId,
80              comp_a : &Box<dyn ComponentStorage>,
81              comp_b : &Box<dyn ComponentStorage>) {
82        if !self.in_group(id,&comp_a,&comp_b) {
83            return;
84        }
85
86        // Unwrap here
87        // This never fails because in_group ensures that it's already in group.
88        self.sparse_set.remove(id).unwrap();
89    }
90
91    pub(in crate) fn make(&mut self,
92            comp_a : &Box<dyn ComponentStorage>,
93            comp_b : &Box<dyn ComponentStorage>) {
94        self.sparse_set.clear();
95
96        let len_a = comp_a.count();
97        let len_b = comp_b.count();
98
99        if len_a < len_b {
100            for index_a in 0..len_a {
101                // Unwrap here never fails
102                // the for loop ensures this
103                let entity_id = comp_a.id(index_a).unwrap();
104                if let Some(index_b) = comp_b.index(entity_id) {
105                    self.sparse_set.add(entity_id,(index_a,index_b));
106                }
107            }
108        } else {
109            for index_b in 0..len_b {
110                // Unwrap here never fails
111                // the for loop ensures this
112                let entity_id = comp_b.id(index_b).unwrap();
113                if let Some(index_a) = comp_a.index(entity_id) {
114                    self.sparse_set.add(entity_id,(index_a,index_b));
115                }
116            }
117        }
118    }
119}
120
121#[derive(Clone, Copy)]
122pub struct NonOwning<A,B>{
123    _marker_a : PhantomData<A>,
124    _marker_b : PhantomData<B>
125}
126
127impl<A : Component,B : Component> NonOwning<A,B> {
128    pub(in crate) fn new() -> Self {
129        NonOwning {
130            _marker_a : PhantomData::default(),
131            _marker_b : PhantomData::default()
132        }
133    }
134}
135
136impl<A : Component,B : Component> Into<Group> for NonOwning<A,B> {
137    fn into(self) -> Group {
138        Group::NonOwning(NonOwningData {
139            sparse_set : SparseSet::new(),
140            type_a: TypeId::of::<A>(),
141            type_b: TypeId::of::<B>()
142        })
143    }
144}