1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 14:26:04 +00:00

yet another W for linear searches

This commit is contained in:
mat 2023-10-02 19:57:13 -05:00
parent 7b10e5cd7e
commit 985327241d
4 changed files with 34 additions and 13 deletions

View file

@ -228,11 +228,17 @@ impl Add<ChunkPos> for ChunkPos {
}
}
}
impl From<ChunkPos> for u64 {
#[inline]
fn from(pos: ChunkPos) -> Self {
((pos.x as u64) << 32) | (pos.z as u64)
}
}
impl Hash for ChunkPos {
#[inline]
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
// optimized hash that only calls hash once
let combined = (self.x as u64) << 32 | (self.z as u64);
combined.hash(state);
u64::from(*self).hash(state);
}
}
/// nohash_hasher lets us have IntMap<ChunkPos, _> which is significantly faster
@ -316,6 +322,15 @@ impl From<BlockPos> for ChunkSectionPos {
}
}
}
impl From<&BlockPos> for ChunkSectionPos {
fn from(pos: &BlockPos) -> Self {
ChunkSectionPos {
x: pos.x.div_floor(16),
y: pos.y.div_floor(16),
z: pos.z.div_floor(16),
}
}
}
impl From<ChunkSectionPos> for ChunkPos {
fn from(pos: ChunkSectionPos) -> Self {

View file

@ -397,7 +397,7 @@ impl McBufWritable for Section {
}
impl Section {
fn get(&self, pos: ChunkSectionBlockPos) -> BlockState {
pub fn get(&self, pos: ChunkSectionBlockPos) -> BlockState {
// TODO: use the unsafe method and do the check earlier
let state = self
.states
@ -406,7 +406,7 @@ impl Section {
BlockState::try_from(state).unwrap_or(BlockState::AIR)
}
fn get_and_set(&mut self, pos: ChunkSectionBlockPos, state: BlockState) -> BlockState {
pub fn get_and_set(&mut self, pos: ChunkSectionBlockPos, state: BlockState) -> BlockState {
let previous_state =
self.states
.get_and_set(pos.x as usize, pos.y as usize, pos.z as usize, state.id);
@ -414,7 +414,7 @@ impl Section {
BlockState::try_from(previous_state).unwrap_or(BlockState::AIR)
}
fn set(&mut self, pos: ChunkSectionBlockPos, state: BlockState) {
pub fn set(&mut self, pos: ChunkSectionBlockPos, state: BlockState) {
self.states
.set(pos.x as usize, pos.y as usize, pos.z as usize, state.id);
}

View file

@ -283,7 +283,7 @@ fn path_found_listener(
"Entity tried to pathfind but the entity isn't in a valid world",
);
let world = &world_lock.read().chunks;
let ctx = PathfinderCtx::new(&world);
let ctx = PathfinderCtx::new(world);
let successors_fn: moves::SuccessorsFn = event.successors_fn;
let successors = |pos: BlockPos| successors_fn(&ctx, pos);
@ -446,7 +446,7 @@ fn tick_execute_path(
{
// obstruction check (the path we're executing isn't possible anymore)
let world = &world_lock.read().chunks;
let ctx = PathfinderCtx::new(&world);
let ctx = PathfinderCtx::new(world);
let successors = |pos: BlockPos| successors_fn(&ctx, pos);
if let Some(last_reached_node) = pathfinder.last_reached_node {

View file

@ -9,10 +9,9 @@ use super::astar;
use azalea_block::BlockState;
use azalea_client::{StartSprintEvent, StartWalkEvent};
use azalea_core::position::{BlockPos, ChunkBlockPos, ChunkPos, Vec3};
use azalea_physics::collision::{self, BlockWithShape};
use azalea_physics::collision::BlockWithShape;
use azalea_world::ChunkStorage;
use bevy_ecs::{entity::Entity, event::EventWriter};
use nohash_hasher::IntMap;
type Edge = astar::Edge<BlockPos, MoveData>;
@ -36,7 +35,7 @@ impl Debug for MoveData {
pub struct PathfinderCtx<'a> {
world: &'a ChunkStorage,
cached_chunks: RefCell<IntMap<ChunkPos, Vec<azalea_world::Section>>>,
cached_chunks: RefCell<Vec<(ChunkPos, Vec<azalea_world::Section>)>>,
}
impl<'a> PathfinderCtx<'a> {
@ -51,7 +50,13 @@ impl<'a> PathfinderCtx<'a> {
let chunk_pos = ChunkPos::from(pos);
let mut cached_chunks = self.cached_chunks.borrow_mut();
if let Some(sections) = cached_chunks.get(&chunk_pos) {
if let Some(sections) = cached_chunks.iter().find_map(|(pos, sections)| {
if *pos == chunk_pos {
Some(sections)
} else {
None
}
}) {
return azalea_world::chunk_storage::get_block_state_from_sections(
sections,
&ChunkBlockPos::from(pos),
@ -62,11 +67,12 @@ impl<'a> PathfinderCtx<'a> {
let chunk = self.world.get(&chunk_pos)?;
let chunk = chunk.read();
cached_chunks.insert(chunk_pos, chunk.sections.clone());
cached_chunks.push((chunk_pos, chunk.sections.clone()));
let chunk_block_pos = ChunkBlockPos::from(pos);
azalea_world::chunk_storage::get_block_state_from_sections(
&chunk.sections,
&ChunkBlockPos::from(pos),
&chunk_block_pos,
self.world.min_y,
)
}