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

fix world being locked while pathfinding

This commit is contained in:
mat 2023-10-03 22:08:18 -05:00
parent 9c6459a73b
commit bffa28e706
4 changed files with 31 additions and 24 deletions

View file

@ -1,4 +1,4 @@
use std::{hint::black_box, time::Duration};
use std::{hint::black_box, sync::Arc, time::Duration};
use azalea::{
pathfinder::{
@ -12,6 +12,7 @@ use azalea::{
use azalea_core::position::{ChunkBlockPos, ChunkPos};
use azalea_world::{Chunk, ChunkStorage, PartialChunkStorage};
use criterion::{criterion_group, criterion_main, Criterion};
use parking_lot::RwLock;
use rand::Rng;
fn generate_bedrock_world(
@ -78,7 +79,7 @@ fn bench_pathfinder(c: &mut Criterion) {
b.iter(|| {
let (world, start, end) = generate_bedrock_world(&mut partial_chunks, 4);
let ctx = PathfinderCtx::new(&world);
let ctx = PathfinderCtx::new(Arc::new(RwLock::new(world.into())));
let goal = BlockPosGoal(end);
let successors = |pos: BlockPos| successors_fn(&ctx, pos);

View file

@ -178,8 +178,7 @@ fn goto_listener(
let task = thread_pool.spawn(async move {
debug!("start: {start:?}");
let world = &world_lock.read().chunks;
let ctx = PathfinderCtx::new(world);
let ctx = PathfinderCtx::new(world_lock);
let successors = |pos: BlockPos| successors_fn(&ctx, pos);
let mut attempt_number = 0;
@ -282,8 +281,7 @@ fn path_found_listener(
let world_lock = instance_container.get(instance_name).expect(
"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_lock);
let successors_fn: moves::SuccessorsFn = event.successors_fn;
let successors = |pos: BlockPos| successors_fn(&ctx, pos);
@ -445,8 +443,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_lock);
let successors = |pos: BlockPos| successors_fn(&ctx, pos);
if let Some(last_reached_node) = pathfinder.last_reached_node {
@ -728,7 +725,7 @@ mod tests {
BlockPos::new(0, 67, 3),
],
);
for _ in 0..40 {
for _ in 0..60 {
simulation.tick();
}
assert_eq!(

View file

@ -211,7 +211,6 @@ fn execute_descend_move(
);
if BlockPos::from(position) != target || horizontal_distance_from_target > 0.25 {
// if we're only falling one block then it's fine to try to overshoot
if horizontal_distance_from_start < 1.25 {
// this basically just exists to avoid doing spins while we're falling
look_at_events.send(LookAtEvent {
@ -232,6 +231,11 @@ fn execute_descend_move(
direction: WalkDirection::Forward,
});
}
} else {
walk_events.send(StartWalkEvent {
entity,
direction: WalkDirection::None,
});
}
}

View file

@ -1,7 +1,7 @@
pub mod basic;
pub mod parkour;
use std::{cell::RefCell, fmt::Debug};
use std::{cell::RefCell, fmt::Debug, sync::Arc};
use crate::{JumpEvent, LookAtEvent};
@ -10,8 +10,9 @@ use azalea_block::BlockState;
use azalea_client::{StartSprintEvent, StartWalkEvent};
use azalea_core::position::{BlockPos, ChunkBlockPos, ChunkPos, Vec3};
use azalea_physics::collision::BlockWithShape;
use azalea_world::ChunkStorage;
use azalea_world::Instance;
use bevy_ecs::{entity::Entity, event::EventWriter};
use parking_lot::RwLock;
type Edge = astar::Edge<BlockPos, MoveData>;
@ -33,15 +34,18 @@ impl Debug for MoveData {
}
}
pub struct PathfinderCtx<'a> {
world: &'a ChunkStorage,
pub struct PathfinderCtx {
min_y: i32,
world_lock: Arc<RwLock<Instance>>,
cached_chunks: RefCell<Vec<(ChunkPos, Vec<azalea_world::Section>)>>,
}
impl<'a> PathfinderCtx<'a> {
pub fn new(world: &'a ChunkStorage) -> Self {
impl PathfinderCtx {
pub fn new(world_lock: Arc<RwLock<Instance>>) -> Self {
let min_y = world_lock.read().chunks.min_y;
Self {
world,
min_y,
world_lock,
cached_chunks: Default::default(),
}
}
@ -61,11 +65,12 @@ impl<'a> PathfinderCtx<'a> {
return azalea_world::chunk_storage::get_block_state_from_sections(
sections,
&chunk_block_pos,
self.world.min_y,
self.min_y,
);
}
let chunk = self.world.get(&chunk_pos)?;
let world = self.world_lock.read();
let chunk = world.chunks.get(&chunk_pos)?;
let chunk = chunk.read();
cached_chunks.push((chunk_pos, chunk.sections.clone()));
@ -73,7 +78,7 @@ impl<'a> PathfinderCtx<'a> {
azalea_world::chunk_storage::get_block_state_from_sections(
&chunk.sections,
&chunk_block_pos,
self.world.min_y,
self.min_y,
)
}
@ -136,7 +141,7 @@ impl<'a> PathfinderCtx<'a> {
distance += 1;
current_pos = current_pos.down(1);
if current_pos.y < self.world.min_y {
if current_pos.y < self.min_y {
return u32::MAX;
}
}
@ -209,7 +214,7 @@ mod tests {
.chunks
.set_block_state(&BlockPos::new(0, 1, 0), BlockState::AIR, &world);
let ctx = PathfinderCtx::new(&world);
let ctx = PathfinderCtx::new(Arc::new(RwLock::new(world.into())));
assert!(!ctx.is_block_passable(&BlockPos::new(0, 0, 0)));
assert!(ctx.is_block_passable(&BlockPos::new(0, 1, 0),));
}
@ -230,7 +235,7 @@ mod tests {
.chunks
.set_block_state(&BlockPos::new(0, 1, 0), BlockState::AIR, &world);
let ctx = PathfinderCtx::new(&world);
let ctx = PathfinderCtx::new(Arc::new(RwLock::new(world.into())));
assert!(ctx.is_block_solid(&BlockPos::new(0, 0, 0)));
assert!(!ctx.is_block_solid(&BlockPos::new(0, 1, 0)));
}
@ -257,7 +262,7 @@ mod tests {
.chunks
.set_block_state(&BlockPos::new(0, 3, 0), BlockState::AIR, &world);
let ctx = PathfinderCtx::new(&world);
let ctx = PathfinderCtx::new(Arc::new(RwLock::new(world.into())));
assert!(ctx.is_standable(&BlockPos::new(0, 1, 0)));
assert!(!ctx.is_standable(&BlockPos::new(0, 0, 0)));
assert!(!ctx.is_standable(&BlockPos::new(0, 2, 0)));