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