Skip to content

Commit 3437a1f

Browse files
committed
feat: save state for player and chunks
1 parent 076ec71 commit 3437a1f

File tree

6 files changed

+89
-18
lines changed

6 files changed

+89
-18
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
.idea
33
.vscode
44
data.txt
5-
chunks
5+
chunks
6+
data

src/chunk.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::{
1010
use glam::Vec3;
1111
use std::any::Any;
1212
use std::error::Error;
13+
use std::ptr::drop_in_place;
1314
use std::sync::{Arc, Mutex};
1415
use wgpu::util::DeviceExt;
1516

@@ -304,7 +305,9 @@ impl Chunk {
304305
chunk_data_layout: Arc<wgpu::BindGroupLayout>,
305306
other_chunks: Vec<Arc<Mutex<Chunk>>>,
306307
) -> Self {
308+
let mut was_loaded = false;
307309
let blocks = if let Ok(blocks) = Self::load(Box::new((x, y))) {
310+
was_loaded = true;
308311
blocks
309312
} else {
310313
Self::create_blocks_data(x, y, noise_data.clone())
@@ -324,7 +327,6 @@ impl Chunk {
324327
resource: chunk_position_buffer.as_entire_binding(),
325328
}],
326329
});
327-
328330
let mut chunk = Chunk {
329331
blocks,
330332
x,
@@ -339,7 +341,10 @@ impl Chunk {
339341
indices: 0,
340342
outside_blocks: vec![],
341343
};
342-
chunk.place_trees();
344+
345+
if !was_loaded {
346+
chunk.place_trees();
347+
}
343348
chunk.build_mesh(other_chunks);
344349

345350
return chunk;
@@ -348,7 +353,7 @@ impl Chunk {
348353

349354
impl Saveable<Chunk> for Chunk {
350355
fn save(&self) -> Result<(), Box<dyn Error>> {
351-
if let Ok(_) = std::fs::create_dir("chunks") {
356+
if let Ok(_) = std::fs::create_dir("data") {
352357
println!("Created dir");
353358
}
354359
let mut data = String::new();
@@ -368,17 +373,25 @@ impl Saveable<Chunk> for Chunk {
368373
}
369374
}
370375

371-
let chunk_file_name = format!("chunks/chunk{}_{}", self.x, self.y);
376+
let chunk_file_name = format!("data/chunk{}_{}", self.x, self.y);
372377
std::fs::write(chunk_file_name.clone(), data.as_bytes())?;
378+
println!("WROTE FILE {:?}", chunk_file_name);
373379

374380
Ok(())
375381
}
376382
}
377383

384+
// Whenever a chunk gets dropped save it
385+
impl Drop for Chunk {
386+
fn drop(&mut self) {
387+
let _ = self.save();
388+
}
389+
}
390+
378391
impl Loadable<BlockVec> for Chunk {
379392
fn load(args: Box<dyn Any>) -> Result<BlockVec, Box<dyn Error>> {
380393
if let Ok(chunk_position) = args.downcast::<(i32, i32)>() {
381-
for entry in std::fs::read_dir("chunks")? {
394+
for entry in std::fs::read_dir("data")? {
382395
let file = entry?;
383396
let filename_chunk = file.file_name();
384397
let mut coords = filename_chunk
@@ -388,13 +401,12 @@ impl Loadable<BlockVec> for Chunk {
388401
.last()
389402
.expect("Invalid filename")
390403
.split("_");
391-
let x = coords.next().unwrap().parse::<i32>().unwrap();
392-
let y = coords.next().unwrap().parse::<i32>().unwrap();
404+
let x = coords.next().unwrap().parse::<i32>()?;
405+
let y = coords.next().unwrap().parse::<i32>()?;
393406

394407
let mut blocks: BlockVec = vec![];
395408
if *chunk_position == (x, y) {
396-
let file_contents =
397-
std::fs::read_to_string(format!("chunks/chunk{}_{}", x, y))?;
409+
let file_contents = std::fs::read_to_string(format!("data/chunk{}_{}", x, y))?;
398410
for line in file_contents.lines() {
399411
let mut i = line.split(",");
400412
let bx = i.next().unwrap().parse::<u32>()?;

src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
7676
state.resize(new_size);
7777
window.lock().unwrap().request_redraw();
7878
}
79-
// WindowEvent::RedrawRequested => {}
8079
WindowEvent::CloseRequested
8180
| WindowEvent::KeyboardInput {
8281
event:
@@ -86,7 +85,8 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
8685
},
8786
..
8887
} => {
89-
state.world.save_state();
88+
state.save_state();
89+
state.dispose();
9090
target.exit();
9191
}
9292

src/player.rs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
use std::any::Any;
2+
use std::error::Error;
3+
use std::f32::consts;
14
use std::sync::{Arc, Mutex};
25
use std::time::{Duration, Instant};
36

47
use glam::{vec2, vec3, Mat2, Vec2, Vec3};
58

69
use crate::blocks::block::{Block, FaceDirections};
710
use crate::collision::{CollisionPoint, RayResult};
11+
use crate::persistance::{Loadable, Saveable};
812
use crate::{
913
collision::CollisionBox,
1014
world::{World, CHUNK_SIZE},
@@ -105,7 +109,6 @@ impl Player {
105109
return match (block_collision, point) {
106110
(Some(block_collision), Some(point)) => {
107111
// TODO: This can be precomputed
108-
109112
let point_dir = ((block_collision.center() - point).normalize()) * -1.0;
110113

111114
let face_directions = FaceDirections::all();
@@ -225,6 +228,24 @@ pub struct Camera {
225228
}
226229

227230
impl Camera {
231+
pub fn new(surface_width: f32, surface_height: f32) -> Camera {
232+
let eye = if let Ok(eye) = Camera::load(Box::new(())) {
233+
eye
234+
} else {
235+
glam::vec3(-4.0, 50.0, 4.0)
236+
};
237+
Self {
238+
aspect_ratio: surface_width / surface_height,
239+
eye,
240+
yaw: consts::FRAC_PI_2,
241+
pitch: 0.0,
242+
243+
fovy: consts::FRAC_PI_4,
244+
znear: 0.1,
245+
zfar: 1000.,
246+
needs_update: false,
247+
}
248+
}
228249
pub fn build_view_matrix(&self) -> glam::Mat4 {
229250
glam::Mat4::look_at_lh(self.eye, self.eye + self.calc_target(), glam::Vec3::Y)
230251
}
@@ -250,3 +271,30 @@ impl Camera {
250271
self.needs_update = true;
251272
}
252273
}
274+
275+
impl Saveable<glam::Vec3> for Camera {
276+
fn save(&self) -> Result<(), Box<dyn Error>> {
277+
if let Ok(_) = std::fs::create_dir("data") {
278+
println!("Created dir");
279+
}
280+
let data = format!("{},{},{}", self.eye.x, self.eye.y, self.eye.z);
281+
282+
let player_file_name = "data/player";
283+
std::fs::write(player_file_name, data.as_bytes())?;
284+
println!("WROTE FILE {:?}", player_file_name);
285+
286+
Ok(())
287+
}
288+
}
289+
290+
impl Loadable<glam::Vec3> for Camera {
291+
fn load(_: Box<dyn Any>) -> Result<Vec3, Box<dyn Error>> {
292+
let data = String::from_utf8(std::fs::read("data/player")?)?;
293+
let mut data = data.split(",");
294+
let x = data.next().unwrap().parse::<f32>().unwrap();
295+
let y = data.next().unwrap().parse::<f32>().unwrap();
296+
let z = data.next().unwrap().parse::<f32>().unwrap();
297+
298+
return Ok(glam::vec3(x, y, z));
299+
}
300+
}

src/state.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use winit::{
2121
keyboard::{KeyCode, PhysicalKey},
2222
window::Window,
2323
};
24+
use crate::persistance::Saveable;
2425

2526
impl State {
2627
pub async fn new(window: Arc<Mutex<Window>>) -> Self {
@@ -120,6 +121,13 @@ impl State {
120121

121122
state
122123
}
124+
pub fn save_state(&mut self) {
125+
self.player.camera.save().expect("Failed to save camera state");
126+
self.world.save_state();
127+
}
128+
pub fn dispose(&mut self) {
129+
self.world.dispose();
130+
}
123131
pub fn handle_keypress(&mut self, event: KeyEvent, delta_time: f32) {
124132
let is_pressed: f32 = if event.state.is_pressed() { 1. } else { 0. };
125133

src/world.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub type NoiseData = Vec<f32>;
3333

3434
pub struct World {
3535
pub chunks: Vec<Arc<Mutex<Chunk>>>,
36-
pub thread_pool: ThreadPool,
36+
pub thread_pool: Option<ThreadPool>,
3737
pub seed: u32,
3838
pub noise_data: Arc<NoiseData>,
3939
pub chunk_data_layout: Arc<wgpu::BindGroupLayout>,
@@ -260,7 +260,7 @@ impl World {
260260
let queue = Arc::clone(&queue);
261261
let other_chunks = self.chunks.iter().map(|c| c.clone()).collect::<Vec<_>>();
262262

263-
self.thread_pool.execute(move || {
263+
self.thread_pool.as_ref().unwrap().execute(move || {
264264
let chunk = Chunk::new(
265265
new_chunk_pos.0,
266266
new_chunk_pos.1,
@@ -283,8 +283,10 @@ impl World {
283283

284284
player.current_chunk = current_chunk;
285285
}
286+
pub fn dispose(&mut self) {
287+
self.thread_pool = None;
288+
}
286289
pub fn save_state(&self) {
287-
// TODO: Player position
288290
for chunk in self.chunks.iter() {
289291
let chunkbrw = chunk.lock().unwrap();
290292
chunkbrw.save().unwrap();
@@ -301,7 +303,7 @@ impl World {
301303
let device = Arc::clone(&self.device);
302304
let queue = Arc::clone(&self.queue);
303305

304-
self.thread_pool.execute(move || {
306+
self.thread_pool.as_ref().unwrap().execute(move || {
305307
let chunk = Chunk::new(
306308
chunk_x,
307309
chunk_y,
@@ -373,7 +375,7 @@ impl World {
373375
device,
374376
queue,
375377
seed: 0,
376-
thread_pool,
378+
thread_pool: Some(thread_pool),
377379
}
378380
}
379381
}

0 commit comments

Comments
 (0)