mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 06:16:04 +00:00
fix world being locked while pathfinding
This commit is contained in:
parent
9c6459a73b
commit
bffa28e706
4 changed files with 31 additions and 24 deletions
|
@ -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);
|
||||
|
|
|
@ -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!(
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)));
|
||||
|
|
Loading…
Add table
Reference in a new issue