Skip to content

Commit

Permalink
feat: add empty Block loader (#751)
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewgazelka authored Dec 18, 2024
1 parent 1f249f6 commit b633b29
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 85 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

131 changes: 65 additions & 66 deletions crates/hyperion/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,75 +7,74 @@ harness = false
name = "atomic"

[dependencies]
anyhow = {workspace = true}
base64 = {workspace = true}
bitfield-struct = {workspace = true}
bitvec = {workspace = true}
bumpalo = {workspace = true}
bytemuck = {workspace = true}
byteorder = {workspace = true}
bytes = {workspace = true}
anyhow = { workspace = true }
base64 = { workspace = true }
bitfield-struct = { workspace = true }
bitvec = { workspace = true }
bumpalo = { workspace = true }
bytemuck = { workspace = true }
byteorder = { workspace = true }
bytes = { workspace = true }
colored = "2.2.0"
derive_more = {workspace = true}
enumset = {workspace = true}
fastrand = {workspace = true}
flate2 = {workspace = true, features = ["zlib-ng"]}
flecs_ecs = {workspace = true }
geometry = {workspace = true}
glam = {workspace = true, features = ["serde"]}
heapless = {workspace = true}
heed = {workspace = true}
humantime = {workspace = true}
hyperion-crafting = {workspace = true}
hyperion-event-macros = {workspace = true}
hyperion-inventory = {workspace = true}
hyperion-nerd-font = {workspace = true}
hyperion-palette = {workspace = true}
hyperion-proto = {workspace = true}
hyperion-text = {workspace = true}
hyperion-utils = {workspace = true}
indexmap = {workspace = true}
itertools = {workspace = true}
kanal = {workspace = true}
libc = {workspace = true}
libdeflater = {workspace = true}
memmap2 = {workspace = true}
more-asserts = {workspace = true}
ndarray = {workspace = true}
no_denormals = {workspace = true}
once_cell = {workspace = true}
ouroboros = {workspace = true}
papaya = {workspace = true}
parking_lot = {workspace = true}
rayon = {workspace = true}
reqwest = {workspace = true}
rkyv = {workspace = true}
roaring = {workspace = true, features = ["simd"]}
rustc-hash = {workspace = true}
serde = {workspace = true, features = ["derive"]}
serde_json = {workspace = true}
sha2 = {workspace = true}
simd-utils = {workspace = true}
system-order = {workspace = true}
thiserror = {workspace = true}
tokio = {workspace = true, features = ["full", "tracing"]}
toml = {workspace = true}
tracing = {workspace = true}
tracing-tracy = {workspace = true}
uuid = {workspace = true}
valence_anvil = {workspace = true}
valence_generated = {workspace = true}
valence_ident = {workspace = true}
valence_nbt = {workspace = true}
valence_protocol = {workspace = true}
valence_registry = {workspace = true}
valence_server = {workspace = true}
valence_text = {workspace = true}
derive_more = { workspace = true }
enumset = { workspace = true }
fastrand = { workspace = true }
flate2 = { workspace = true, features = ["zlib-ng"] }
flecs_ecs = { workspace = true }
geometry = { workspace = true }
glam = { workspace = true, features = ["serde"] }
heapless = { workspace = true }
heed = { workspace = true }
humantime = { workspace = true }
hyperion-crafting = { workspace = true }
hyperion-event-macros = { workspace = true }
hyperion-inventory = { workspace = true }
hyperion-nerd-font = { workspace = true }
hyperion-palette = { workspace = true }
hyperion-proto = { workspace = true }
hyperion-text = { workspace = true }
hyperion-utils = { workspace = true }
indexmap = { workspace = true }
itertools = { workspace = true }
kanal = { workspace = true }
libc = { workspace = true }
libdeflater = { workspace = true }
memmap2 = { workspace = true }
more-asserts = { workspace = true }
ndarray = { workspace = true }
no_denormals = { workspace = true }
once_cell = { workspace = true }
ouroboros = { workspace = true }
papaya = { workspace = true }
parking_lot = { workspace = true }
rayon = { workspace = true }
reqwest = { workspace = true }
rkyv = { workspace = true }
roaring = { workspace = true, features = ["simd"] }
rustc-hash = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
sha2 = { workspace = true }
simd-utils = { workspace = true }
system-order = { workspace = true }
thiserror = { workspace = true }
tokio = { workspace = true, features = ["full", "tracing"] }
toml = { workspace = true }
tracing = { workspace = true }
tracing-tracy = { workspace = true }
uuid = { workspace = true }
valence_anvil = { workspace = true }
valence_generated = { workspace = true }
valence_ident = { workspace = true }
valence_nbt = { workspace = true }
valence_protocol = { workspace = true }
valence_registry = { workspace = true }
valence_server = { workspace = true }
valence_text = { workspace = true }

[dev-dependencies]
divan = {workspace = true}
fastrand = {workspace = true}
hyperion-genmap = {workspace = true}
divan = { workspace = true }
fastrand = { workspace = true }

[lints]
workspace = true
Expand Down
4 changes: 3 additions & 1 deletion crates/hyperion/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,10 @@ impl HyperionCore {
world.component::<Events>();
world.component::<Comms>();
world.component::<EgressComm>();
world.component::<Blocks>();

world.component::<AsyncRuntime>();
world.component::<Blocks>();

world.component::<Tasks>();

system!("run_tasks", world, &mut Tasks($))
Expand Down Expand Up @@ -373,6 +374,7 @@ impl HyperionCore {
});

world.set(IgnMap::default());
world.set(Blocks::empty(world));

Ok(())
}
Expand Down
26 changes: 21 additions & 5 deletions crates/hyperion/src/simulation/blocks/loader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::{borrow::Cow, cell::RefCell, io::Write, sync::Arc};

use anyhow::{Context, bail};
use bytes::BytesMut;
use derive_more::Constructor;
use glam::{I16Vec2, IVec2};
use hyperion_nerd_font::NERD_ROCKET;
use itertools::Itertools;
Expand Down Expand Up @@ -58,6 +59,7 @@ struct ChunkLoader {
runtime: AsyncRuntime,
}

#[derive(Constructor)]
pub struct ChunkLoaderHandle {
tx_load_chunk_requests: tokio::sync::mpsc::UnboundedSender<Message>,
}
Expand All @@ -70,7 +72,7 @@ impl ChunkLoaderHandle {
}
}

pub fn launch_manager(shared: Arc<WorldShared>, runtime: &AsyncRuntime) -> ChunkLoaderHandle {
pub fn launch_loader(shared: Arc<WorldShared>, runtime: &AsyncRuntime) -> ChunkLoaderHandle {
let (tx_load_chunk_requests, rx_load_chunk_requests) = tokio::sync::mpsc::unbounded_channel();

runtime.spawn({
Expand All @@ -92,6 +94,20 @@ pub fn launch_manager(shared: Arc<WorldShared>, runtime: &AsyncRuntime) -> Chunk
}
}

pub fn launch_empty_loader(runtime: &AsyncRuntime) -> ChunkLoaderHandle {
let (tx_loaded_chunks, mut rx_loaded_chunks) =
tokio::sync::mpsc::unbounded_channel::<Message>();

runtime.spawn(async move {
while let Some(msg) = rx_loaded_chunks.recv().await {
let column = empty_column(msg.position);
msg.tx.send(column).unwrap();
}
});

ChunkLoaderHandle::new(tx_loaded_chunks)
}

impl ChunkLoader {
async fn run(mut self) {
while let Some(message) = self.rx_load_chunk_requests.recv().await {
Expand Down Expand Up @@ -125,12 +141,12 @@ impl ChunkLoader {
version of Minecraft.\n\nExpected height: {CHUNK_HEIGHT_SPAN}, got \
{chunk_height}"
);
empty_chunk(position)
empty_column(position)
}
}
Err(err) => {
warn!("failed to load chunk {position:?}: {err}");
empty_chunk(position)
empty_column(position)
}
};

Expand All @@ -149,7 +165,7 @@ impl ChunkLoader {
}
}

fn empty_chunk(position: I16Vec2) -> Column {
fn empty_column(position: I16Vec2) -> Column {
// height: 24
let unloaded = ColumnData::new_with(CHUNK_HEIGHT_SPAN, Section::empty_sky);
let position = position.as_ivec2();
Expand All @@ -176,7 +192,7 @@ async fn load_chunk(position: I16Vec2, shared: &WorldShared) -> anyhow::Result<C
let Ok(region) = shared.regions.get_region_from_chunk(x, y).await else {
// most likely the file representing the region does not exist so we will just return en empty chunk
warn!("region file for {position} does not exist; returning empty chunk");
return Ok(empty_chunk(position));
return Ok(empty_column(position));
};

let raw_chunk = {
Expand Down
42 changes: 31 additions & 11 deletions crates/hyperion/src/simulation/blocks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use flecs_ecs::{
use geometry::ray::Ray;
use glam::{I16Vec2, IVec2, IVec3, Vec3};
use indexmap::IndexMap;
use loader::{ChunkLoaderHandle, launch_manager};
use loader::{ChunkLoaderHandle, launch_loader};
use rayon::iter::ParallelIterator;
use roaring::RoaringBitmap;
use rustc_hash::FxBuildHasher;
Expand All @@ -25,7 +25,10 @@ use valence_server::layer::chunk::Chunk;
use crate::{
CHUNK_HEIGHT_SPAN,
runtime::AsyncRuntime,
simulation::{blocks::loader::parse::section::Section, util::generate_biome_registry},
simulation::{
blocks::loader::{launch_empty_loader, parse::section::Section},
util::generate_biome_registry,
},
};

pub mod chunk;
Expand Down Expand Up @@ -76,6 +79,20 @@ pub struct Blocks {
pub to_confirm: Vec<EntityAndSequence>,
}

impl From<ChunkLoaderHandle> for Blocks {
fn from(loader_handle: ChunkLoaderHandle) -> Self {
let (tx_loaded_chunks, rx_loaded_chunks) = tokio::sync::mpsc::unbounded_channel();
Self {
chunk_cache: IndexMap::default(),
should_update: RoaringBitmap::default(),
loader_handle,
tx_loaded_chunks,
rx_loaded_chunks,
to_confirm: vec![],
}
}
}

impl Blocks {
pub fn new(world: &World, path: &Path) -> anyhow::Result<Self> {
world.get::<&AsyncRuntime>(|runtime| {
Expand All @@ -85,16 +102,19 @@ impl Blocks {
let shared = WorldShared::new(&biome_registry, runtime, path)?;
let shared = Arc::new(shared);

let (tx_loaded_chunks, rx_loaded_chunks) = tokio::sync::mpsc::unbounded_channel();
let loader_handle = launch_loader(shared, runtime);

Ok(Self {
chunk_cache: IndexMap::default(),
should_update: RoaringBitmap::default(),
loader_handle: launch_manager(shared, runtime),
tx_loaded_chunks,
rx_loaded_chunks,
to_confirm: vec![],
})
let result = Self::from(loader_handle);

Ok(result)
})
}

#[must_use]
pub fn empty(world: &World) -> Self {
world.get::<&AsyncRuntime>(|runtime| {
let loader_handle = launch_empty_loader(runtime);
Self::from(loader_handle)
})
}

Expand Down
1 change: 0 additions & 1 deletion crates/hyperion/tests/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ struct TestModule;

impl Module for TestModule {
fn module(world: &World) {
world.import::<hyperion_genmap::GenMapModule>();
world.import::<hyperion::HyperionCore>();
}
}
Expand Down

0 comments on commit b633b29

Please sign in to comment.