@@ -24,7 +24,7 @@ pub const FREQUENCY: f32 = 1. / 128.;
24
24
pub const NOISE_CHUNK_PER_ROW : u32 = NOISE_SIZE / CHUNK_SIZE ;
25
25
pub const MAX_TREES_PER_CHUNK : u32 = 3 ;
26
26
27
- pub const CHUNKS_PER_ROW : u32 = 25 ;
27
+ pub const CHUNKS_PER_ROW : u32 = 60 ;
28
28
pub const CHUNKS_REGION : u32 = CHUNKS_PER_ROW * CHUNKS_PER_ROW ;
29
29
pub const WATER_HEIGHT_LEVEL : u8 = 5 ;
30
30
@@ -41,8 +41,12 @@ pub const UB: i32 = if CHUNKS_PER_ROW % 2 == 0 {
41
41
pub type NoiseData = Vec < f32 > ;
42
42
43
43
pub type WorldChunk = Arc < RwLock < Chunk > > ;
44
+ pub type ChunkMap = Arc < RwLock < HashMap < ( i32 , i32 ) , WorldChunk > > > ;
45
+
46
+ // TODO: It should be better to unsafely pass the hashmap between threads, since we never modify it except when we're done
47
+ // and it will be save since every chunk has its own lock.
44
48
pub struct World {
45
- pub chunks : HashMap < ( i32 , i32 ) , WorldChunk > ,
49
+ pub chunks : ChunkMap ,
46
50
pub thread_pool : Option < ThreadPool > ,
47
51
pub seed : u32 ,
48
52
pub noise_data : Arc < NoiseData > ,
@@ -52,23 +56,23 @@ pub struct World {
52
56
}
53
57
54
58
impl World {
55
- pub fn get_other_chunks ( & self , chunk_ptr : WorldChunk ) -> Vec < WorldChunk > {
56
- self . chunks
57
- . values ( )
58
- . filter_map ( |c| {
59
- return if !Arc :: ptr_eq ( & chunk_ptr, c) {
60
- Some ( c. clone ( ) )
61
- } else {
62
- None
63
- } ;
64
- } )
65
- . collect ( )
66
- }
59
+ // pub fn get_other_chunks(&self, chunk_ptr: WorldChunk) -> Vec<WorldChunk> {
60
+ // self.chunks
61
+ // .values()
62
+ // .filter_map(|c| {
63
+ // return if !Arc::ptr_eq(&chunk_ptr, c) {
64
+ // Some(c.clone())
65
+ // } else {
66
+ // None
67
+ // };
68
+ // })
69
+ // .collect()
70
+ // }
67
71
pub fn place_block ( & mut self , block : Arc < RwLock < Block > > ) {
68
72
let block_borrow = block. read ( ) . unwrap ( ) ;
69
73
let mut chunks_to_rerender = vec ! [ block_borrow. get_chunk_coords( ) ] ;
70
- let chunk = self
71
- . chunks
74
+ let chunk_map = self . chunks . read ( ) . unwrap ( ) ;
75
+ let chunk = chunk_map
72
76
. get ( & chunks_to_rerender[ 0 ] )
73
77
. expect ( "Cannot delete a block from unloaded chunk" ) ;
74
78
@@ -96,8 +100,8 @@ impl World {
96
100
pub fn remove_block ( & mut self , block : Arc < RwLock < Block > > ) {
97
101
let block_borrow = block. read ( ) . unwrap ( ) ;
98
102
let mut chunks_to_rerender = vec ! [ block_borrow. get_chunk_coords( ) ] ;
99
- let chunk = self
100
- . chunks
103
+ let chunk_map = self . chunks . read ( ) . unwrap ( ) ;
104
+ let chunk = chunk_map
101
105
. get ( & chunks_to_rerender[ 0 ] )
102
106
. expect ( "Cannot delete a block from unloaded chunk" ) ;
103
107
@@ -113,7 +117,8 @@ impl World {
113
117
pub fn get_blocks_absolute ( & self , position : & Vec3 ) -> Option < Arc < RwLock < Block > > > {
114
118
let ( chunk_x, chunk_y) = position. get_chunk_from_position_absolute ( ) ;
115
119
116
- let chunk = self . chunks . get ( & ( chunk_x, chunk_y) ) ?;
120
+ let chunk_map = self . chunks . read ( ) . unwrap ( ) ;
121
+ let chunk = chunk_map. get ( & ( chunk_x, chunk_y) ) ?;
117
122
let chunk = chunk. read ( ) . unwrap ( ) ;
118
123
119
124
let relative_position = position. relative_from_absolute ( ) ;
@@ -206,7 +211,7 @@ impl World {
206
211
. collect ( ) ;
207
212
208
213
let mut keys_to_remove = vec ! [ ] ;
209
- for key in self . chunks . keys ( ) {
214
+ for key in self . chunks . read ( ) . unwrap ( ) . keys ( ) {
210
215
// let chunk = chunk.read().unwrap();
211
216
if ( delta. 1 != 0 && key. 1 == chunk_y_remove)
212
217
|| ( delta. 0 != 0 && key. 0 == chunk_x_remove)
@@ -218,7 +223,12 @@ impl World {
218
223
// Save the unloaded chunks
219
224
let ( sender, receiver) = mpsc:: channel ( ) ;
220
225
for key in keys_to_remove. iter ( ) {
221
- let chunk = self . chunks . remove ( key) . expect ( "Something went wrong" ) ;
226
+ let chunk = self
227
+ . chunks
228
+ . write ( )
229
+ . unwrap ( )
230
+ . remove ( key)
231
+ . expect ( "Something went wrong" ) ;
222
232
let sender = sender. clone ( ) ;
223
233
self . thread_pool . as_ref ( ) . unwrap ( ) . execute ( move || {
224
234
let chunk = chunk. write ( ) . unwrap ( ) ;
@@ -260,6 +270,8 @@ impl World {
260
270
for _ in 0 ..chunks_added {
261
271
let chunk = receiver. recv ( ) . unwrap ( ) ;
262
272
self . chunks
273
+ . write ( )
274
+ . unwrap ( )
263
275
. insert ( ( chunk. x , chunk. y ) , Arc :: new ( RwLock :: new ( chunk) ) ) ;
264
276
}
265
277
self . handle_outside_blocks ( ) ;
@@ -272,7 +284,7 @@ impl World {
272
284
// Update visible chunks based on player position and direction
273
285
{
274
286
let ( sender, receiver) = mpsc:: channel ( ) ;
275
- for chunk in self . chunks . values ( ) {
287
+ for chunk in self . chunks . read ( ) . unwrap ( ) . values ( ) {
276
288
let chunk = Arc :: clone ( & chunk) ;
277
289
let sender = sender. clone ( ) ;
278
290
let player = Arc :: clone ( & player) ;
@@ -282,7 +294,7 @@ impl World {
282
294
sender. send ( ( ) ) . unwrap ( ) ;
283
295
} ) ;
284
296
}
285
- for _ in self . chunks . iter ( ) {
297
+ for _ in self . chunks . read ( ) . unwrap ( ) . iter ( ) {
286
298
receiver. recv ( ) . unwrap ( ) ;
287
299
}
288
300
}
@@ -292,7 +304,7 @@ impl World {
292
304
}
293
305
294
306
pub fn save_state ( & self ) {
295
- for chunk in self . chunks . values ( ) {
307
+ for chunk in self . chunks . read ( ) . unwrap ( ) . values ( ) {
296
308
let chunkbrw = chunk. read ( ) . unwrap ( ) ;
297
309
if chunkbrw. modified {
298
310
chunkbrw. save ( ) . expect ( "failed to save" ) ;
@@ -327,12 +339,14 @@ impl World {
327
339
for _ in 0 ..CHUNKS_PER_ROW * CHUNKS_PER_ROW {
328
340
let chunk = receiver. recv ( ) . expect ( "Some chunks are missing" ) ;
329
341
self . chunks
342
+ . write ( )
343
+ . unwrap ( )
330
344
. insert ( ( chunk. x , chunk. y ) , Arc :: new ( RwLock :: new ( chunk) ) ) ;
331
345
}
332
346
333
347
self . handle_outside_blocks ( ) ;
334
348
// this is kinda slow
335
- self . render_chunks ( self . chunks . keys ( ) . collect :: < Vec < _ > > ( ) ) ;
349
+ self . render_chunks ( self . chunks . read ( ) . unwrap ( ) . keys ( ) . collect :: < Vec < _ > > ( ) ) ;
336
350
}
337
351
// chunks: slice containing the chunk to re-render
338
352
fn render_chunks < I > ( & self , chunk_keys : Vec < I > )
@@ -342,15 +356,17 @@ impl World {
342
356
let ( sender, receiver) = mpsc:: channel ( ) ;
343
357
344
358
for key in chunk_keys. iter ( ) {
345
- if let Some ( chunk) = self . chunks . get ( key. borrow ( ) ) {
359
+ if let Some ( chunk) = self . chunks . read ( ) . unwrap ( ) . get ( key. borrow ( ) ) {
346
360
let sender = sender. clone ( ) ;
347
- let other = self . get_other_chunks ( chunk. clone ( ) ) ;
361
+ // This is extremely slow O(n^2)
362
+ // let other = self.get_other_chunks(chunk.clone());
348
363
let chunk = chunk. clone ( ) ;
364
+ let chunk_map = self . chunks . clone ( ) ;
349
365
350
366
self . thread_pool . as_ref ( ) . unwrap ( ) . execute ( move || {
351
367
let chunk_ptr = chunk. clone ( ) ;
352
368
let chunk = chunk. read ( ) . unwrap ( ) ;
353
- let res = chunk. build_mesh ( other ) ;
369
+ let res = chunk. build_mesh ( chunk_map ) ;
354
370
sender. send ( ( res, chunk_ptr) ) . unwrap ( ) ;
355
371
} ) ;
356
372
}
@@ -378,7 +394,7 @@ impl World {
378
394
}
379
395
fn handle_outside_blocks ( & mut self ) {
380
396
let mut blocks_to_add = vec ! [ ] ;
381
- for chunk in self . chunks . values ( ) {
397
+ for chunk in self . chunks . read ( ) . unwrap ( ) . values ( ) {
382
398
let mut chunkbrw = chunk. write ( ) . unwrap ( ) ;
383
399
blocks_to_add. append ( & mut chunkbrw. outside_blocks ) ;
384
400
}
@@ -387,7 +403,7 @@ impl World {
387
403
388
404
for block in blocks_to_add. iter ( ) {
389
405
let chunk_coords = block. read ( ) . unwrap ( ) . get_chunk_coords ( ) ;
390
- if let Some ( chunkptr) = self . chunks . get ( & chunk_coords) {
406
+ if let Some ( chunkptr) = self . chunks . read ( ) . unwrap ( ) . get ( & chunk_coords) {
391
407
let mut chunkbrw = chunkptr. write ( ) . unwrap ( ) ;
392
408
chunkbrw. add_block ( block. clone ( ) , false ) ;
393
409
if let None = chunks_to_rerender. iter ( ) . find ( |c| Arc :: ptr_eq ( c, chunkptr) ) {
@@ -409,7 +425,7 @@ impl World {
409
425
410
426
World {
411
427
chunk_data_layout,
412
- chunks : HashMap :: new ( ) ,
428
+ chunks : Arc :: new ( RwLock :: new ( HashMap :: new ( ) ) ) ,
413
429
noise_data,
414
430
device,
415
431
queue,
0 commit comments