Skip to content
This repository has been archived by the owner on Jul 1, 2024. It is now read-only.

Commit

Permalink
init skylight when laoding chunk
Browse files Browse the repository at this point in the history
  • Loading branch information
DimitriTimoz committed Dec 25, 2023
1 parent bfd88f7 commit 309e9e8
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 24 deletions.
3 changes: 1 addition & 2 deletions minecraft-server/src/world/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ impl LightManager {
}
}

#[instrument(skip(world_map))]
pub async fn update_light(world_map: &'static WorldMap, block_position: BlockPosition, block: BlockWithState) {
let mut light_manager = Self::new(world_map);

Expand Down Expand Up @@ -261,8 +262,6 @@ impl LightManager {
}
}



async fn set_light_level(&mut self, position: LightPosition, level: u8) {
unimplemented!();
}
Expand Down
41 changes: 22 additions & 19 deletions minecraft-server/src/world/map.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::{collections::HashMap, cmp::Ordering};
use minecraft_protocol::{components::chunk::PalettedData, ids::blocks::Block};
use tokio::sync::{RwLock, OwnedRwLockWriteGuard};
use crate::prelude::*;
use crate::{prelude::*, world::light::LightManager};

pub struct WorldMap {
/// The map is divided in shards.
Expand Down Expand Up @@ -453,19 +453,21 @@ impl WorldMap {
}


pub async fn set_block(&self, position: BlockPosition, block: BlockWithState) {
async fn inner_get_block(s: &WorldMap, position: BlockPosition, block: BlockWithState) -> Option<()> {
pub async fn set_block(&'static self, position: BlockPosition, block: BlockWithState) {
async fn inner_set_block(s: &'static WorldMap, position: BlockPosition, block: BlockWithState) -> Option<()> {
let chunk_position = position.chunk();
let position_in_chunk_column = position.in_chunk_column();
let chunk_column_position = chunk_position.chunk_column();
let shard = chunk_column_position.shard(s.shard_count);

let mut shard = s.shards[shard].write().await;
let chunk_column = shard.get_mut(&chunk_column_position)?;
chunk_column.set_block(position_in_chunk_column, block);
chunk_column.set_block(position_in_chunk_column.clone(), block);
Some(())
}
inner_get_block(self, position, block).await;

inner_set_block(self, position.clone(), block.clone()).await;
LightManager::update_light(self, position, block).await;
}

#[cfg_attr(feature = "trace", instrument(skip_all))]
Expand Down Expand Up @@ -495,13 +497,14 @@ impl WorldMap {
}

#[cfg_attr(feature = "trace", instrument(skip(self)))]
pub async fn load(&self, position: ChunkColumnPosition) {
pub async fn load(&'static self, position: ChunkColumnPosition) {
let chunk = ChunkColumn::flat(); // TODO: load from disk
let shard = position.shard(self.shard_count);

trace!("Loading chunk column at {:?}", position);
let mut shard = self.shards[shard].write().await;
shard.entry(position).or_insert_with(|| chunk);
shard.entry(position.clone()).or_insert_with(|| chunk);
LightManager::init_chunk_column_light(self, position).await;
}


Expand Down Expand Up @@ -645,24 +648,24 @@ mod tests {

#[tokio::test]
async fn test_world_map() {
let map = WorldMap::new(1);
let world = Box::leak(Box::new(World::new(broadcast_channel(100).1)));
for cx in -3..=3 {
for cz in -3..=3 {
map.load(ChunkColumnPosition { cx, cz }).await;
world.map.load(ChunkColumnPosition { cx, cz }).await;
}
}

// Test single block
map.set_block(BlockPosition { x: -40, y: -40, z: -40 }, BlockWithState::RedstoneBlock).await;
let block = map.get_block(BlockPosition { x: -40, y: -40, z: -40 }).await;
world.map.set_block(BlockPosition { x: -40, y: -40, z: -40 }, BlockWithState::RedstoneBlock).await;
let block = world.map.get_block(BlockPosition { x: -40, y: -40, z: -40 }).await;
assert_eq!(block.block_state_id().unwrap(), BlockWithState::RedstoneBlock.block_state_id().unwrap());

// Set blocks
let mut id = 1;
for x in (-40..40).step_by(9) {
for y in (-40..200).step_by(15) {
for z in (-40..40).step_by(9) {
map.set_block(BlockPosition { x, y, z }, BlockWithState::from_state_id(id).unwrap()).await;
world.map.set_block(BlockPosition { x, y, z }, BlockWithState::from_state_id(id).unwrap()).await;
id += 1;
}
}
Expand All @@ -673,7 +676,7 @@ mod tests {
for x in (-40..40).step_by(9) {
for y in (-40..200).step_by(15) {
for z in (-40..40).step_by(9) {
let got = map.get_block(BlockPosition { x, y, z }).await.block_state_id().unwrap();
let got = world.map.get_block(BlockPosition { x, y, z }).await.block_state_id().unwrap();
assert_eq!(id, got);
id += 1;
}
Expand Down Expand Up @@ -735,8 +738,8 @@ mod tests {

#[tokio::test]
async fn test_try_move() {
let map = WorldMap::new(1);
map.load(ChunkColumnPosition { cx: 0, cz: 0 }).await;
let world = Box::leak(Box::new(World::new(broadcast_channel(100).1)));
world.map.load(ChunkColumnPosition { cx: 0, cz: 0 }).await;
let bounding_box = CollisionShape {
x1: 0.0,
y1: 0.0,
Expand All @@ -749,19 +752,19 @@ mod tests {
// Position on ground and try to go through it
let positionned_box = bounding_box.clone() + &Translation { x: 0.0, y: -3.0*16.0, z: 0.0 };
let movement = Translation { x: 0.0, y: -10.0, z: 0.0 };
let movement = map.try_move(&positionned_box, &movement).await;
let movement = world.map.try_move(&positionned_box, &movement).await;
assert_eq!(movement, Translation { x: 0.0, y: 0.0, z: 0.0 }); // It doesn't get through

// Place it a little above ground
let positionned_box = bounding_box.clone() + &Translation { x: 0.0, y: -3.0*16.0 + 1.0, z: 0.0 };
let movement = Translation { x: 0.0, y: -10.0, z: 0.0 };
let movement = map.try_move(&positionned_box, &movement).await;
let movement = world.map.try_move(&positionned_box, &movement).await;
assert_eq!(movement, Translation { x: 0.0, y: -1.0, z: 0.0 }); // It falls down but doesn't get through

// Place it above but not on round coordinates
let positionned_box = bounding_box.clone() + &Translation { x: 0.0, y: -3.0*16.0 + 1.1, z: 0.2 };
let movement = Translation { x: 2.0, y: -10.0, z: 0.0 };
let movement = map.try_move(&positionned_box, &movement).await;
let movement = world.map.try_move(&positionned_box, &movement).await;
assert_eq!(movement, Translation { x: 0.2200000000000003, y: -1.1000000000000014, z: 0.0 }); // It falls down but doesn't get through
}
}
6 changes: 3 additions & 3 deletions minecraft-server/src/world/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl World {
Some(self.map.get_block(position).await)
}

pub async fn set_block(&self, position: BlockPosition, block: BlockWithState) {
pub async fn set_block(&'static self, position: BlockPosition, block: BlockWithState) {
self.map.set_block(position.clone(), block.clone()).await;
self.notify(&position.chunk_column(), WorldChange::Block(position, block)).await;
}
Expand All @@ -59,7 +59,7 @@ impl World {
self.change_senders.write().await.remove(&uuid);
}

pub async fn ensure_loaded_chunks(&self, uuid: UUID, loaded_chunks: HashSet<ChunkColumnPosition>) {
pub async fn ensure_loaded_chunks(&'static self, uuid: UUID, loaded_chunks: HashSet<ChunkColumnPosition>) {
let mut loading_manager = self.loading_manager.write().await;
let loaded_chunks_before = loading_manager.get_loaded_chunks();
loading_manager.update_loaded_chunks(uuid, loaded_chunks);
Expand Down Expand Up @@ -171,7 +171,7 @@ mod tests {

#[tokio::test]
async fn test_world_notifications() {
let world = World::new(broadcast_channel(100).1);
let world = Box::leak(Box::new(World::new(broadcast_channel(100).1)));

let mut receiver1 = world.add_loader(1).await;
let mut receiver2 = world.add_loader(2).await;
Expand Down

0 comments on commit 309e9e8

Please sign in to comment.