Skip to content

Commit 2f68c66

Browse files
committed
feat: changed mutex in favor of RwLock and everything is now pretty much multithreadable -- will need tho some major refactoring
1 parent 3437a1f commit 2f68c66

File tree

10 files changed

+145
-147
lines changed

10 files changed

+145
-147
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,6 @@ features = ["png", "jpeg"]
2828
anyhow = "1.0"
2929
fs_extra = "1.2"
3030
glob = "0.3"
31+
32+
[build]
33+
rustflags = ["-Z", "threads=8"]

src/blocks/block.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ use bytemuck::{Pod, Zeroable};
33
use super::block_type::BlockType;
44
use crate::world::CHUNK_SIZE;
55
use glam::Vec3;
6-
use std::sync::MutexGuard;
6+
use std::sync::{Arc, MutexGuard, RwLock};
77

8+
#[derive(Debug)]
89
pub struct Block {
910
pub position: glam::Vec3,
1011
pub absolute_position: glam::Vec3,
@@ -38,10 +39,7 @@ pub enum FaceDirections {
3839
}
3940

4041
impl FaceDirections {
41-
pub fn create_face_data(
42-
&self,
43-
block: &MutexGuard<'_, Block>,
44-
) -> (Vec<BlockVertexData>, Vec<u32>) {
42+
pub fn create_face_data(&self, block: Arc<RwLock<Block>>) -> (Vec<BlockVertexData>, Vec<u32>) {
4543
let indices = self.get_indices();
4644

4745
let mut unique_indices: Vec<u32> = Vec::with_capacity(4);
@@ -66,15 +64,16 @@ impl FaceDirections {
6664
*indices_map = index_of as u32;
6765
}
6866

69-
let face_texcoords = block.block_type.get_texcoords(*self);
67+
let block_read = block.read().unwrap();
68+
let face_texcoords = block_read.block_type.get_texcoords(*self);
7069
let normals = self.get_normal_vector();
7170

7271
unique_indices.iter().enumerate().for_each(|(i, index)| {
7372
vertex_data.push(BlockVertexData {
7473
position: [
75-
CUBE_VERTEX[(*index as usize * 3 + 0) as usize] + block.position.x,
76-
CUBE_VERTEX[(*index as usize * 3 + 1) as usize] + block.position.y,
77-
CUBE_VERTEX[(*index as usize * 3 + 2) as usize] + block.position.z,
74+
CUBE_VERTEX[(*index as usize * 3 + 0) as usize] + block_read.position.x,
75+
CUBE_VERTEX[(*index as usize * 3 + 1) as usize] + block_read.position.y,
76+
CUBE_VERTEX[(*index as usize * 3 + 2) as usize] + block_read.position.z,
7877
],
7978
normal: normals.into(),
8079
tex_coords: face_texcoords[i],
@@ -86,7 +85,7 @@ impl FaceDirections {
8685

8786
pub fn create_face_data_abs(
8887
&self,
89-
block: &MutexGuard<'_, Block>, // To prevent deadlocks
88+
block: Arc<RwLock<Block>>,
9089
) -> (Vec<BlockVertexData>, Vec<u32>) {
9190
let indices = self.get_indices();
9291

@@ -112,15 +111,16 @@ impl FaceDirections {
112111
*indices_map = index_of as u32;
113112
}
114113

115-
let face_texcoords = block.block_type.get_texcoords(*self);
114+
let block_read = block.read().unwrap();
115+
let face_texcoords = block_read.block_type.get_texcoords(*self);
116116
let normals = self.get_normal_vector();
117117

118118
unique_indices.iter().enumerate().for_each(|(i, index)| {
119119
vertex_data.push(BlockVertexData {
120120
position: [
121-
CUBE_VERTEX[(*index as usize * 3 + 0) as usize] + block.absolute_position.x,
122-
CUBE_VERTEX[(*index as usize * 3 + 1) as usize] + block.absolute_position.y,
123-
CUBE_VERTEX[(*index as usize * 3 + 2) as usize] + block.absolute_position.z,
121+
CUBE_VERTEX[(*index as usize * 3 + 0) as usize] + block_read.absolute_position.x,
122+
CUBE_VERTEX[(*index as usize * 3 + 1) as usize] + block_read.absolute_position.y,
123+
CUBE_VERTEX[(*index as usize * 3 + 2) as usize] + block_read.absolute_position.z,
124124
],
125125
normal: normals.into(),
126126
tex_coords: face_texcoords[i],

src/chunk.rs

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::persistance::{Loadable, Saveable};
2+
use crate::world::WorldChunk;
23
use crate::{
34
blocks::{
45
block::{Block, BlockVertexData, FaceDirections},
@@ -10,12 +11,12 @@ use crate::{
1011
use glam::Vec3;
1112
use std::any::Any;
1213
use std::error::Error;
13-
use std::ptr::drop_in_place;
14-
use std::sync::{Arc, Mutex};
14+
use std::sync::{Arc, RwLock};
1515
use wgpu::util::DeviceExt;
1616

17-
pub type BlockVec = Vec<Vec<Option<Arc<Mutex<Block>>>>>;
17+
pub type BlockVec = Vec<Vec<Option<Arc<RwLock<Block>>>>>;
1818

19+
#[derive(Debug)]
1920
pub struct Chunk {
2021
pub x: i32,
2122
pub y: i32,
@@ -28,12 +29,12 @@ pub struct Chunk {
2829
pub chunk_position_buffer: wgpu::Buffer,
2930
pub chunk_index_buffer: Option<wgpu::Buffer>,
3031
pub chunk_vertex_buffer: Option<wgpu::Buffer>,
31-
pub outside_blocks: Vec<Arc<Mutex<Block>>>,
32+
pub outside_blocks: Vec<Arc<RwLock<Block>>>,
3233
}
3334

3435
impl Chunk {
35-
pub fn add_block(&mut self, block: Arc<Mutex<Block>>) {
36-
let block_borrow = block.lock().unwrap();
36+
pub fn add_block(&mut self, block: Arc<RwLock<Block>>) {
37+
let block_borrow = block.read().unwrap();
3738

3839
let y_blocks = self
3940
.blocks
@@ -71,7 +72,7 @@ impl Chunk {
7172
}
7273
return false;
7374
}
74-
pub fn get_block_at_relative(&self, position: &glam::Vec3) -> Option<Arc<Mutex<Block>>> {
75+
pub fn get_block_at_relative(&self, position: &glam::Vec3) -> Option<Arc<RwLock<Block>>> {
7576
if let Some(y_blocks) = self
7677
.blocks
7778
.get(((position.x * CHUNK_SIZE as f32) + position.z) as usize)
@@ -100,16 +101,16 @@ impl Chunk {
100101
false
101102
}
102103
}
103-
pub fn build_mesh(&mut self, other_chunks: Vec<Arc<Mutex<Chunk>>>) {
104+
pub fn build_mesh(&self, other_chunks: Vec<WorldChunk>) -> (u32, wgpu::Buffer, wgpu::Buffer) {
104105
let mut vertex: Vec<BlockVertexData> = vec![];
105106
let mut indices: Vec<u32> = vec![];
106107
for x in 0..CHUNK_SIZE {
107108
for z in 0..CHUNK_SIZE {
108-
let region = &self.blocks[(x * CHUNK_SIZE + z) as usize];
109+
let region = &self.blocks[((x * CHUNK_SIZE) + z) as usize];
109110
for y in 0..region.len() {
110111
let block = &region[y];
111-
if let Some(block) = block {
112-
let block = block.lock().unwrap();
112+
if let Some(block_ptr) = block {
113+
let block = block_ptr.read().unwrap();
113114
let position = block.position;
114115
let faces = FaceDirections::all();
115116

@@ -132,12 +133,15 @@ impl Chunk {
132133
);
133134

134135
let target_chunk = other_chunks.iter().find(|c| {
135-
let c = c.lock().unwrap();
136+
let c = c.read().unwrap();
136137
c.x == target_chunk_x && c.y == target_chunk_y
137138
});
139+
// If there's a chunk loaded in memory then check that, else it means we're on a edge and we can
140+
// Calculate the block's height when the chunk gets generated
141+
// TODO: Check for saved file chunk
138142
match target_chunk {
139143
Some(chunk) => {
140-
let chunk = chunk.lock().unwrap();
144+
let chunk = chunk.read().unwrap();
141145
if Chunk::exists_block_at(&chunk.blocks, &target_block) {
142146
is_visible = false;
143147
}
@@ -161,7 +165,8 @@ impl Chunk {
161165
}
162166

163167
if is_visible {
164-
let (mut vertex_data, index_data) = face.create_face_data(&block);
168+
let (mut vertex_data, index_data) =
169+
face.create_face_data(block_ptr.clone());
165170
vertex.append(&mut vertex_data);
166171
let indices_offset = vertex.len() as u32 - 4;
167172
indices.append(
@@ -189,9 +194,11 @@ impl Chunk {
189194
usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST,
190195
});
191196

192-
self.indices = indices.len() as u32;
193-
self.chunk_vertex_buffer = Some(chunk_vertex_buffer);
194-
self.chunk_index_buffer = Some(chunk_index_buffer);
197+
(
198+
indices.len() as u32,
199+
chunk_vertex_buffer,
200+
chunk_index_buffer,
201+
)
195202
}
196203
pub fn get_bind_group_layout() -> wgpu::BindGroupLayoutDescriptor<'static> {
197204
wgpu::BindGroupLayoutDescriptor {
@@ -246,7 +253,7 @@ impl Chunk {
246253
b => b,
247254
};
248255

249-
let block = Arc::new(Mutex::new(Block::new(
256+
let block = Arc::new(RwLock::new(Block::new(
250257
glam::vec3(x as f32, y as f32, z as f32),
251258
(chunk_x, chunk_y),
252259
block_type,
@@ -277,14 +284,14 @@ impl Chunk {
277284
.expect("TODO: Fix this case -h")
278285
.as_ref()
279286
.unwrap()
280-
.lock()
287+
.read()
281288
.unwrap()
282289
.absolute_position;
283290

284291
let tree_blocks = crate::structures::Tree::get_blocks(highest_block);
285292

286293
for block in tree_blocks.iter() {
287-
let block_brw = block.lock().unwrap();
294+
let block_brw = block.read().unwrap();
288295
let block_chunk = block_brw.get_chunk_coords();
289296
std::mem::drop(block_brw);
290297
if block_chunk == (self.x, self.y) {
@@ -303,8 +310,7 @@ impl Chunk {
303310
device: Arc<wgpu::Device>,
304311
queue: Arc<wgpu::Queue>,
305312
chunk_data_layout: Arc<wgpu::BindGroupLayout>,
306-
other_chunks: Vec<Arc<Mutex<Chunk>>>,
307-
) -> Self {
313+
) -> Chunk {
308314
let mut was_loaded = false;
309315
let blocks = if let Ok(blocks) = Self::load(Box::new((x, y))) {
310316
was_loaded = true;
@@ -327,6 +333,7 @@ impl Chunk {
327333
resource: chunk_position_buffer.as_entire_binding(),
328334
}],
329335
});
336+
330337
let mut chunk = Chunk {
331338
blocks,
332339
x,
@@ -345,8 +352,6 @@ impl Chunk {
345352
if !was_loaded {
346353
chunk.place_trees();
347354
}
348-
chunk.build_mesh(other_chunks);
349-
350355
return chunk;
351356
}
352357
}
@@ -361,7 +366,7 @@ impl Saveable<Chunk> for Chunk {
361366
for col in self.blocks.iter() {
362367
for block in col.iter() {
363368
if let Some(block_ptr) = block {
364-
let blockbrw = block_ptr.lock().unwrap();
369+
let blockbrw = block_ptr.read().unwrap();
365370
data += &format!(
366371
"{},{},{},{}\n",
367372
blockbrw.position.x,
@@ -404,7 +409,7 @@ impl Loadable<BlockVec> for Chunk {
404409
let x = coords.next().unwrap().parse::<i32>()?;
405410
let y = coords.next().unwrap().parse::<i32>()?;
406411

407-
let mut blocks: BlockVec = vec![];
412+
let mut blocks: BlockVec = vec![vec![]; (CHUNK_SIZE * CHUNK_SIZE) as usize];
408413
if *chunk_position == (x, y) {
409414
let file_contents = std::fs::read_to_string(format!("data/chunk{}_{}", x, y))?;
410415
for line in file_contents.lines() {
@@ -421,13 +426,6 @@ impl Loadable<BlockVec> for Chunk {
421426
block_type,
422427
);
423428

424-
if let None = blocks.get_mut(
425-
(block.position.x as u32 * CHUNK_SIZE + block.position.z as u32)
426-
as usize,
427-
) {
428-
// This works only because chunks rows are in order
429-
blocks.push(vec![]);
430-
}
431429
let y_blocks = blocks
432430
.get_mut(
433431
(block.position.x as u32 * CHUNK_SIZE + block.position.z as u32)
@@ -443,7 +441,7 @@ impl Loadable<BlockVec> for Chunk {
443441
y_blocks.push(None);
444442
}
445443
}
446-
y_blocks[y_position] = Some(Arc::new(Mutex::new(block)));
444+
y_blocks[y_position] = Some(Arc::new(RwLock::new(block)));
447445
}
448446
return Ok(blocks);
449447
}

src/collision.rs

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -136,34 +136,6 @@ impl CollisionBox {
136136
&& point.z >= self.min_z
137137
&& point.z <= self.max_z;
138138
}
139-
pub fn intersects_dir(&self, other: &CollisionBox) -> Option<(f32, f32, f32)> {
140-
if self.intersects(other) {
141-
let mut collision_dir = (0.0, 0.0, 0.0);
142-
143-
// if self.max_x >= other.min_x && self.min_x < other.min_x {
144-
// collision_dir.0 = self.max_x - other.min_x;
145-
// }
146-
// if self.min_x <= other.max_x && self.max_x > other.max_x {
147-
// collision_dir.0 = self.min_x - other.max_x;
148-
// }
149-
// if self.max_y >= other.min_y && self.min_y < other.min_y {
150-
// collision_dir.1 = 1.0;
151-
// }
152-
// if self.min_y <= other.max_y && self.max_y > other.max_y {
153-
// collision_dir.1 = -1.0;
154-
// }
155-
// if self.max_z >= other.min_z && self.min_z > other.min_z {
156-
// collision_dir.2 = self.max_z - other.min_z;
157-
// }
158-
// if self.min_z <= other.max_z && self.max_z > other.max_z {
159-
// collision_dir.2 = self.min_z - other.max_z;
160-
// }
161-
162-
return Some(collision_dir);
163-
} else {
164-
return None;
165-
}
166-
}
167139
pub fn intersects(&self, other: &CollisionBox) -> bool {
168140
return self.min_x <= other.max_x
169141
&& self.max_x >= other.min_x

src/player.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::any::Any;
22
use std::error::Error;
33
use std::f32::consts;
4-
use std::sync::{Arc, Mutex};
4+
use std::sync::{Arc, RwLock};
55
use std::time::{Duration, Instant};
66

77
use glam::{vec2, vec3, Mat2, Vec2, Vec3};
@@ -42,7 +42,7 @@ pub struct Player {
4242
pub is_jumping: bool,
4343
pub jump_action_start: Option<Instant>,
4444
pub is_ghost: bool,
45-
pub facing_block: Option<Arc<Mutex<Block>>>,
45+
pub facing_block: Option<Arc<RwLock<Block>>>,
4646
pub facing_face: Option<FaceDirections>,
4747
}
4848
impl Player {

0 commit comments

Comments
 (0)