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:
parent
7b10e5cd7e
commit
985327241d
4 changed files with 34 additions and 13 deletions
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue