@@ -6,9 +6,8 @@ use internal_types::FastHashMap;
6
6
use std:: fmt:: Debug ;
7
7
use std:: hash:: Hash ;
8
8
use std:: marker:: PhantomData ;
9
- use std:: mem;
10
- use std:: ops;
11
- use std:: u64;
9
+ use std:: { mem, ops, u64} ;
10
+ use util:: VecHelper ;
12
11
13
12
/*
14
13
@@ -60,7 +59,9 @@ pub struct UpdateList<S> {
60
59
/// The current epoch of the scene builder.
61
60
epoch : Epoch ,
62
61
/// The additions and removals to apply.
63
- updates : Vec < Update < S > > ,
62
+ updates : Vec < Update > ,
63
+ /// Actual new data to insert.
64
+ data : Vec < S > ,
64
65
}
65
66
66
67
#[ cfg_attr( feature = "capture" , derive( Serialize ) ) ]
@@ -89,17 +90,17 @@ impl <T> Handle<T> where T: Copy {
89
90
90
91
#[ cfg_attr( feature = "capture" , derive( Serialize ) ) ]
91
92
#[ cfg_attr( feature = "replay" , derive( Deserialize ) ) ]
92
- pub enum UpdateKind < S > {
93
- Insert ( S ) ,
93
+ pub enum UpdateKind {
94
+ Insert ,
94
95
Remove ,
95
96
UpdateEpoch ,
96
97
}
97
98
98
99
#[ cfg_attr( feature = "capture" , derive( Serialize ) ) ]
99
100
#[ cfg_attr( feature = "replay" , derive( Deserialize ) ) ]
100
- pub struct Update < S > {
101
+ pub struct Update {
101
102
index : usize ,
102
- kind : UpdateKind < S > ,
103
+ kind : UpdateKind ,
103
104
}
104
105
105
106
/// The data item is stored with an epoch, for validating
@@ -137,18 +138,14 @@ impl<S, T, M> DataStore<S, T, M> where S: Debug, T: From<S>, M: Debug {
137
138
& mut self ,
138
139
update_list : UpdateList < S > ,
139
140
) {
141
+ let mut data_iter = update_list. data . into_iter ( ) ;
140
142
for update in update_list. updates {
141
143
match update. kind {
142
- UpdateKind :: Insert ( data ) => {
143
- let item = Item {
144
- data : T :: from ( data ) ,
144
+ UpdateKind :: Insert => {
145
+ self . items . entry ( update . index ) . set ( Item {
146
+ data : T :: from ( data_iter . next ( ) . unwrap ( ) ) ,
145
147
epoch : update_list. epoch ,
146
- } ;
147
- if self . items . len ( ) == update. index {
148
- self . items . push ( item)
149
- } else {
150
- self . items [ update. index ] = item;
151
- }
148
+ } ) ;
152
149
}
153
150
UpdateKind :: Remove => {
154
151
self . items [ update. index ] . epoch = Epoch :: INVALID ;
@@ -158,6 +155,7 @@ impl<S, T, M> DataStore<S, T, M> where S: Debug, T: From<S>, M: Debug {
158
155
}
159
156
}
160
157
}
158
+ debug_assert ! ( data_iter. next( ) . is_none( ) ) ;
161
159
}
162
160
}
163
161
@@ -194,7 +192,9 @@ pub struct Interner<S : Eq + Hash + Clone + Debug, D, M> {
194
192
/// List of free slots in the data store for re-use.
195
193
free_list : Vec < usize > ,
196
194
/// Pending list of updates that need to be applied.
197
- updates : Vec < Update < S > > ,
195
+ updates : Vec < Update > ,
196
+ /// Pending new data to insert.
197
+ update_data : Vec < S > ,
198
198
/// The current epoch for the interner.
199
199
current_epoch : Epoch ,
200
200
/// Incrementing counter for identifying stable values.
@@ -211,6 +211,7 @@ impl<S, D, M> Interner<S, D, M> where S: Eq + Hash + Clone + Debug, M: Copy + De
211
211
map : FastHashMap :: default ( ) ,
212
212
free_list : Vec :: new ( ) ,
213
213
updates : Vec :: new ( ) ,
214
+ update_data : Vec :: new ( ) ,
214
215
current_epoch : Epoch ( 1 ) ,
215
216
next_uid : 0 ,
216
217
local_data : Vec :: new ( ) ,
@@ -259,8 +260,9 @@ impl<S, D, M> Interner<S, D, M> where S: Eq + Hash + Clone + Debug, M: Copy + De
259
260
// Add a pending update to insert the new data.
260
261
self . updates . push ( Update {
261
262
index,
262
- kind : UpdateKind :: Insert ( data . clone ( ) ) ,
263
+ kind : UpdateKind :: Insert ,
263
264
} ) ;
265
+ self . update_data . alloc ( ) . init ( data. clone ( ) ) ;
264
266
265
267
// Generate a handle for access via the data store.
266
268
let handle = Handle {
@@ -280,15 +282,10 @@ impl<S, D, M> Interner<S, D, M> where S: Eq + Hash + Clone + Debug, M: Copy + De
280
282
281
283
// Create the local data for this item that is
282
284
// being interned.
283
- let local_item = Item {
285
+ self . local_data . entry ( index ) . set ( Item {
284
286
epoch : self . current_epoch ,
285
287
data : f ( ) ,
286
- } ;
287
- if self . local_data . len ( ) == index {
288
- self . local_data . push ( local_item) ;
289
- } else {
290
- self . local_data [ index] = local_item;
291
- }
288
+ } ) ;
292
289
293
290
handle
294
291
}
@@ -298,6 +295,8 @@ impl<S, D, M> Interner<S, D, M> where S: Eq + Hash + Clone + Debug, M: Copy + De
298
295
/// a GC step that removes old entries.
299
296
pub fn end_frame_and_get_pending_updates ( & mut self ) -> UpdateList < S > {
300
297
let mut updates = mem:: replace ( & mut self . updates , Vec :: new ( ) ) ;
298
+ let data = mem:: replace ( & mut self . update_data , Vec :: new ( ) ) ;
299
+
301
300
let free_list = & mut self . free_list ;
302
301
let current_epoch = self . current_epoch . 0 ;
303
302
@@ -327,6 +326,7 @@ impl<S, D, M> Interner<S, D, M> where S: Eq + Hash + Clone + Debug, M: Copy + De
327
326
328
327
let updates = UpdateList {
329
328
updates,
329
+ data,
330
330
epoch : self . current_epoch ,
331
331
} ;
332
332
0 commit comments