Skip to content

Commit

Permalink
feat: implement block updates and item registry
Browse files Browse the repository at this point in the history
  • Loading branch information
Liyze09 committed Oct 2, 2024
1 parent bd63fa5 commit c545096
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 25 deletions.
7 changes: 4 additions & 3 deletions crates/kernel/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub mod oak_log;
pub mod stone;

use crate::registry::protocol_id::{get_block_states, get_protocol_id};
use crate::world::block_update::BlockUpdateType;
use crate::world::block_update::{BlockUpdate, BlockUpdateType};
use crate::world::dimension::Dimension;
use dashmap::DashMap;
use downcast_rs::{impl_downcast, DowncastSync};
Expand All @@ -24,9 +24,10 @@ pub trait Block: Send + Sync + DowncastSync {
&self,
_update_type: BlockUpdateType,
_pos: (i32, i32, i32),
_dimension: &mut Dimension,
_dimension: Arc<Dimension>,
_state: u32,
) {
) -> Vec<BlockUpdate> {
Vec::with_capacity(0)
}
fn get_builder(&self) -> &BlockBuilder;
fn get_block_id(&self) -> u32 {
Expand Down
19 changes: 19 additions & 0 deletions crates/kernel/src/item.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
use crate::block::BLOCK_ITEM_BY_ID;
use crate::registry::protocol_id::get_protocol_id;
use dashmap::DashMap;
use downcast_rs::{impl_downcast, DowncastSync};
use once_cell::sync::Lazy;

pub(crate) static ITEMS_BY_ID: Lazy<DashMap<u32, Box<dyn Item>>> = Lazy::new(DashMap::new);
pub(crate) static ITEMS_BY_NAME: Lazy<DashMap<String, u32>> = Lazy::new(DashMap::new);
pub fn register_item(id: &str, item: Box<dyn Item + 'static>) {
let protocol_id = item.get_item_id();
ITEMS_BY_NAME.insert(id.to_string(), protocol_id);
ITEMS_BY_ID.insert(protocol_id, item);
}
pub fn register_block_item(id: &str, item: Box<dyn Item + 'static>, block: u32) {
let protocol_id = item.get_item_id();
BLOCK_ITEM_BY_ID.insert(block, protocol_id);
ITEMS_BY_NAME.insert(id.to_string(), protocol_id);
ITEMS_BY_ID.insert(protocol_id, item);
}
pub trait Item: Send + Sync + DowncastSync {
fn get_builder(&self) -> &ItemBuilder;
fn get_item_id(&self) -> u32 {
self.get_builder().protocol_id
}
}
impl_downcast!(sync Item);

Expand Down
117 changes: 98 additions & 19 deletions crates/kernel/src/world.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use crate::block::BLOCKS_BY_ID;
use crate::entity::entity_manager::EntityManager;
use crate::registry::dimension_type::DIMENSION_TYPES;
use crate::registry::DIMENSION_TYPES_INDEX;
use crate::world::block_update::BlockUpdateType::{NeighbourChange, PostPlacement};
use crate::world::block_update::{BlockUpdate, BlockUpdateType};
use crate::world::dimension::Dimension;
use dashmap::DashSet;
use parking_lot::Mutex;
use rayon::prelude::*;
use std::sync::Arc;
use std::thread;

pub mod block_update;
pub mod chunk;
Expand Down Expand Up @@ -70,33 +72,109 @@ impl World {
}
pub fn tick(&mut self) {
self.swap_queues();
let queue = self.get_internal_queue();
let new: Mutex<Vec<BlockUpdate>> = Mutex::new(Vec::new());
loop {
let mut new: Vec<BlockUpdate> = Vec::new();
let queue = self.get_internal_queue();
let blocks_in_use: DashSet<(i32, i32, i32)> = DashSet::new();
queue.par_iter_mut().for_each(|update| {
match update.update_type {
BlockUpdateType::NeighbourChange => {
// TODO
queue
.par_iter_mut()
.for_each(|update| match update.update_type {
NeighbourChange => {
let positions = [
(update.pos.0, update.pos.1, update.pos.2 - 1),
(update.pos.0, update.pos.1, update.pos.2 + 1),
(update.pos.0 + 1, update.pos.1, update.pos.2),
(update.pos.0 - 1, update.pos.1, update.pos.2),
(update.pos.0, update.pos.1 - 1, update.pos.2),
(update.pos.0, update.pos.1 + 1, update.pos.2),
];
let mut new = new.lock();
for pos in positions.iter() {
while blocks_in_use.contains(pos) {
rayon::yield_now();
}
blocks_in_use.insert(*pos);
new.append(
&mut BLOCKS_BY_ID
.get(&update.state)
.unwrap()
.value()
.when_block_update(
NeighbourChange,
update.pos,
update.dimension.clone(),
update.state,
),
);
blocks_in_use.remove(pos);
}
}
BlockUpdateType::PostPlacement => {
// TODO
PostPlacement => {
let positions = [
(update.pos.0, update.pos.1, update.pos.2 - 1),
(update.pos.0, update.pos.1, update.pos.2 + 1),
(update.pos.0, update.pos.1 - 1, update.pos.2),
(update.pos.0, update.pos.1 + 1, update.pos.2),
(update.pos.0 + 1, update.pos.1, update.pos.2),
(update.pos.0 - 1, update.pos.1, update.pos.2),
];
let mut new = new.lock();
for pos in positions.iter() {
while blocks_in_use.contains(pos) {
rayon::yield_now();
}
blocks_in_use.insert(*pos);
new.append(
&mut BLOCKS_BY_ID
.get(&update.state)
.unwrap()
.value()
.when_block_update(
PostPlacement,
update.pos,
update.dimension.clone(),
update.state,
),
);
blocks_in_use.remove(pos);
}
}
BlockUpdateType::Change(new) => {
BlockUpdateType::Change(new_state) => {
while blocks_in_use.contains(&update.pos) {
thread::yield_now()
rayon::yield_now();
}
blocks_in_use.insert(update.pos);
update
.dimension
.set_block(update.pos.0, update.pos.1, update.pos.2, new);
update.dimension.set_block(
update.pos.0,
update.pos.1,
update.pos.2,
new_state,
);
let mut new = new.lock();
new.append(
&mut BLOCKS_BY_ID
.get(&new_state)
.unwrap()
.value()
.when_block_update(
update.update_type,
update.pos,
update.dimension.clone(),
update.state,
),
);
blocks_in_use.remove(&update.pos);
new.push(BlockUpdate::new(
update.pos.0,
update.pos.1,
update.pos.2,
update.dimension.clone(),
new_state,
PostPlacement,
))
}
BlockUpdateType::NeighbourChangeDouble => {
// TODO
}
}
});
});
let mut new = new.lock();
if new.is_empty() {
break;
} else {
Expand All @@ -107,6 +185,7 @@ impl World {
}
self.swap_queues();
}

pub fn find_dimension(&self, name: &str) -> Option<Arc<Dimension>> {
Some(
self.dimensions
Expand Down
7 changes: 4 additions & 3 deletions crates/kernel/src/world/block_update.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
use crate::world::dimension::Dimension;
use std::sync::Arc;

#[derive(Eq, PartialEq, Copy, Clone)]
pub enum BlockUpdateType {
NeighbourChange,
NeighbourChangeDouble,
PostPlacement,
Change(u32),
}

pub struct BlockUpdate {
pub pos: (i32, i32, i32),
pub dimension: &'static mut Dimension,
pub dimension: Arc<Dimension>,
pub state: u32,
pub(crate) update_type: BlockUpdateType,
}
Expand All @@ -18,7 +19,7 @@ impl BlockUpdate {
x: i32,
y: i32,
z: i32,
dimension: &'static mut Dimension,
dimension: Arc<Dimension>,
state: u32,
update_type: BlockUpdateType,
) -> BlockUpdate {
Expand Down

0 comments on commit c545096

Please sign in to comment.