@@ -9,6 +9,14 @@ pub use resource::*;
9
9
pub use sparse_set:: * ;
10
10
pub use table:: * ;
11
11
12
+ use crate :: {
13
+ archetype:: Archetypes ,
14
+ component:: { ComponentId , ComponentTicks , Components , StorageType , TickCells } ,
15
+ entity:: { Entity , EntityLocation } ,
16
+ } ;
17
+ use bevy_ptr:: Ptr ;
18
+ use std:: any:: TypeId ;
19
+
12
20
/// The raw data stores of a [World](crate::world::World)
13
21
#[ derive( Default ) ]
14
22
pub struct Storages {
@@ -17,3 +25,182 @@ pub struct Storages {
17
25
pub resources : Resources < true > ,
18
26
pub non_send_resources : Resources < false > ,
19
27
}
28
+
29
+ impl Storages {
30
+ /// Get a raw pointer to a particular [`Component`] and its [`ComponentTicks`] identified by their [`TypeId`]
31
+ ///
32
+ /// # Safety
33
+ /// - `entity_location` must be within bounds of the given archetype and `entity` must exist inside
34
+ /// - `component_id` must be valid
35
+ /// - `storage_type` must accurately reflect where the components for `component_id` are stored.
36
+ /// - `Archetypes` and `Components` must come from the world this of this `Storages`
37
+ /// - the caller must ensure that no aliasing rules are violated
38
+ #[ inline]
39
+ pub unsafe fn get_component_and_ticks_with_type (
40
+ & self ,
41
+ archetypes : & Archetypes ,
42
+ components : & Components ,
43
+ type_id : TypeId ,
44
+ storage_type : StorageType ,
45
+ entity : Entity ,
46
+ location : EntityLocation ,
47
+ ) -> Option < ( Ptr < ' _ > , TickCells < ' _ > ) > {
48
+ let component_id = components. get_id ( type_id) ?;
49
+ self . get_component_and_ticks ( archetypes, component_id, storage_type, entity, location)
50
+ }
51
+
52
+ /// Get a raw pointer to a particular [`Component`] and its [`ComponentTicks`]
53
+ ///
54
+ /// # Safety
55
+ /// - `entity_location` must be within bounds of the given archetype and `entity` must exist inside
56
+ /// - `component_id` must be valid
57
+ /// - `storage_type` must accurately reflect where the components for `component_id` are stored.
58
+ /// - `Archetypes` and `Components` must come from the world this of this `Storages`
59
+ /// - the caller must ensure that no aliasing rules are violated
60
+ #[ inline]
61
+ pub unsafe fn get_component_and_ticks (
62
+ & self ,
63
+ archetypes : & Archetypes ,
64
+ component_id : ComponentId ,
65
+ storage_type : StorageType ,
66
+ entity : Entity ,
67
+ location : EntityLocation ,
68
+ ) -> Option < ( Ptr < ' _ > , TickCells < ' _ > ) > {
69
+ match storage_type {
70
+ StorageType :: Table => {
71
+ let ( components, table_row) =
72
+ fetch_table ( archetypes, self , location, component_id) ?;
73
+
74
+ // SAFETY: archetypes only store valid table_rows and the stored component type is T
75
+ Some ( (
76
+ components. get_data_unchecked ( table_row) ,
77
+ TickCells {
78
+ added : components. get_added_ticks_unchecked ( table_row) ,
79
+ changed : components. get_changed_ticks_unchecked ( table_row) ,
80
+ } ,
81
+ ) )
82
+ }
83
+ StorageType :: SparseSet => fetch_sparse_set ( self , component_id) ?. get_with_ticks ( entity) ,
84
+ }
85
+ }
86
+
87
+ /// Get a raw pointer to a particular [`Component`] on a particular [`Entity`], identified by the component's [`Type`]
88
+ ///
89
+ /// # Safety
90
+ /// - `entity_location` must be within bounds of the given archetype and `entity` must exist inside
91
+ /// the archetype
92
+ /// - `Archetypes` and `Components` must come from the world this of this `Storages`
93
+ /// - the caller must ensure that no aliasing rules are violated
94
+ #[ inline]
95
+ pub unsafe fn get_component_with_type (
96
+ & self ,
97
+ archetypes : & Archetypes ,
98
+ components : & Components ,
99
+ type_id : TypeId ,
100
+ storage_type : StorageType ,
101
+ entity : Entity ,
102
+ location : EntityLocation ,
103
+ ) -> Option < Ptr < ' _ > > {
104
+ let component_id = components. get_id ( type_id) ?;
105
+ self . get_component ( archetypes, component_id, storage_type, entity, location)
106
+ }
107
+
108
+ /// Get a raw pointer to a particular [`Component`] on a particular [`Entity`] in the provided [`World`].
109
+ ///
110
+ /// # Safety
111
+ /// - `entity_location` must be within bounds of the given archetype and `entity` must exist inside
112
+ /// the archetype
113
+ /// - `component_id`
114
+ /// - `storage_type` must accurately reflect where the components for `component_id` are stored.
115
+ /// - `Archetypes` and `Components` must come from the world this of this `Storages`
116
+ /// - the caller must ensure that no aliasing rules are violated
117
+ #[ inline]
118
+ pub unsafe fn get_component (
119
+ & self ,
120
+ archetypes : & Archetypes ,
121
+ component_id : ComponentId ,
122
+ storage_type : StorageType ,
123
+ entity : Entity ,
124
+ location : EntityLocation ,
125
+ ) -> Option < Ptr < ' _ > > {
126
+ // SAFETY: component_id exists and is therefore valid
127
+ match storage_type {
128
+ StorageType :: Table => {
129
+ let ( components, table_row) =
130
+ fetch_table ( archetypes, self , location, component_id) ?;
131
+ // SAFETY: archetypes only store valid table_rows and the stored component type is T
132
+ Some ( components. get_data_unchecked ( table_row) )
133
+ }
134
+ StorageType :: SparseSet => fetch_sparse_set ( self , component_id) ?. get ( entity) ,
135
+ }
136
+ }
137
+
138
+ /// Get a raw pointer to the [`ComponentTicks`] on a particular [`Entity`], identified by the component's [`TypeId`]
139
+ ///
140
+ /// # Safety
141
+ /// - `entity_location` must be within bounds of the given archetype and `entity` must exist inside
142
+ /// the archetype
143
+ /// - `Archetypes` and `Components` must come from the world this of this `Storages`
144
+ /// - the caller must ensure that no aliasing rules are violated
145
+ #[ inline]
146
+ pub unsafe fn get_ticks_with_type (
147
+ & self ,
148
+ archetypes : & Archetypes ,
149
+ components : & Components ,
150
+ type_id : TypeId ,
151
+ storage_type : StorageType ,
152
+ entity : Entity ,
153
+ location : EntityLocation ,
154
+ ) -> Option < ComponentTicks > {
155
+ let component_id = components. get_id ( type_id) ?;
156
+ self . get_ticks ( archetypes, component_id, storage_type, entity, location)
157
+ }
158
+
159
+ /// Get a raw pointer to the [`ComponentTicks`] on a particular [`Entity`]
160
+ ///
161
+ /// # Safety
162
+ /// - `entity_location` must be within bounds of the given archetype and `entity` must exist inside
163
+ /// the archetype
164
+ /// - `component_id` must be valid
165
+ /// - `storage_type` must accurately reflect where the components for `component_id` are stored.
166
+ /// - `Archetypes` and `Components` must come from the world this of this `Storages`
167
+ /// - the caller must ensure that no aliasing rules are violated
168
+ #[ inline]
169
+ pub unsafe fn get_ticks (
170
+ & self ,
171
+ archetypes : & Archetypes ,
172
+ component_id : ComponentId ,
173
+ storage_type : StorageType ,
174
+ entity : Entity ,
175
+ location : EntityLocation ,
176
+ ) -> Option < ComponentTicks > {
177
+ match storage_type {
178
+ StorageType :: Table => {
179
+ let ( components, table_row) =
180
+ fetch_table ( archetypes, self , location, component_id) ?;
181
+ // SAFETY: archetypes only store valid table_rows and the stored component type is T
182
+ Some ( components. get_ticks_unchecked ( table_row) )
183
+ }
184
+ StorageType :: SparseSet => fetch_sparse_set ( self , component_id) ?. get_ticks ( entity) ,
185
+ }
186
+ }
187
+ }
188
+
189
+ #[ inline]
190
+ unsafe fn fetch_table < ' s > (
191
+ archetypes : & Archetypes ,
192
+ storages : & ' s Storages ,
193
+ location : EntityLocation ,
194
+ component_id : ComponentId ,
195
+ ) -> Option < ( & ' s Column , TableRow ) > {
196
+ let archetype = & archetypes[ location. archetype_id ] ;
197
+ let table = & storages. tables [ archetype. table_id ( ) ] ;
198
+ let components = table. get_column ( component_id) ?;
199
+ let table_row = archetype. entity_table_row ( location. archetype_row ) ;
200
+ Some ( ( components, table_row) )
201
+ }
202
+
203
+ #[ inline]
204
+ fn fetch_sparse_set ( storages : & Storages , component_id : ComponentId ) -> Option < & ComponentSparseSet > {
205
+ storages. sparse_sets . get ( component_id)
206
+ }
0 commit comments