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:
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::{
|
use azalea::{
|
||||||
pathfinder::{
|
pathfinder::{
|
||||||
|
@ -12,6 +12,7 @@ use azalea::{
|
||||||
use azalea_core::position::{ChunkBlockPos, ChunkPos};
|
use azalea_core::position::{ChunkBlockPos, ChunkPos};
|
||||||
use azalea_world::{Chunk, ChunkStorage, PartialChunkStorage};
|
use azalea_world::{Chunk, ChunkStorage, PartialChunkStorage};
|
||||||
use criterion::{criterion_group, criterion_main, Criterion};
|
use criterion::{criterion_group, criterion_main, Criterion};
|
||||||
|
use parking_lot::RwLock;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
fn generate_bedrock_world(
|
fn generate_bedrock_world(
|
||||||
|
@ -78,7 +79,7 @@ fn bench_pathfinder(c: &mut Criterion) {
|
||||||
|
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let (world, start, end) = generate_bedrock_world(&mut partial_chunks, 4);
|
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 goal = BlockPosGoal(end);
|
||||||
|
|
||||||
let successors = |pos: BlockPos| successors_fn(&ctx, pos);
|
let successors = |pos: BlockPos| successors_fn(&ctx, pos);
|
||||||
|
|
|
@ -178,8 +178,7 @@ fn goto_listener(
|
||||||
let task = thread_pool.spawn(async move {
|
let task = thread_pool.spawn(async move {
|
||||||
debug!("start: {start:?}");
|
debug!("start: {start:?}");
|
||||||
|
|
||||||
let world = &world_lock.read().chunks;
|
let ctx = PathfinderCtx::new(world_lock);
|
||||||
let ctx = PathfinderCtx::new(world);
|
|
||||||
let successors = |pos: BlockPos| successors_fn(&ctx, pos);
|
let successors = |pos: BlockPos| successors_fn(&ctx, pos);
|
||||||
|
|
||||||
let mut attempt_number = 0;
|
let mut attempt_number = 0;
|
||||||
|
@ -282,8 +281,7 @@ fn path_found_listener(
|
||||||
let world_lock = instance_container.get(instance_name).expect(
|
let world_lock = instance_container.get(instance_name).expect(
|
||||||
"Entity tried to pathfind but the entity isn't in a valid world",
|
"Entity tried to pathfind but the entity isn't in a valid world",
|
||||||
);
|
);
|
||||||
let world = &world_lock.read().chunks;
|
let ctx = PathfinderCtx::new(world_lock);
|
||||||
let ctx = PathfinderCtx::new(world);
|
|
||||||
let successors_fn: moves::SuccessorsFn = event.successors_fn;
|
let successors_fn: moves::SuccessorsFn = event.successors_fn;
|
||||||
let successors = |pos: BlockPos| successors_fn(&ctx, pos);
|
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)
|
// obstruction check (the path we're executing isn't possible anymore)
|
||||||
let world = &world_lock.read().chunks;
|
let ctx = PathfinderCtx::new(world_lock);
|
||||||
let ctx = PathfinderCtx::new(world);
|
|
||||||
let successors = |pos: BlockPos| successors_fn(&ctx, pos);
|
let successors = |pos: BlockPos| successors_fn(&ctx, pos);
|
||||||
|
|
||||||
if let Some(last_reached_node) = pathfinder.last_reached_node {
|
if let Some(last_reached_node) = pathfinder.last_reached_node {
|
||||||
|
@ -728,7 +725,7 @@ mod tests {
|
||||||
BlockPos::new(0, 67, 3),
|
BlockPos::new(0, 67, 3),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
for _ in 0..40 {
|
for _ in 0..60 {
|
||||||
simulation.tick();
|
simulation.tick();
|
||||||
}
|
}
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
@ -211,7 +211,6 @@ fn execute_descend_move(
|
||||||
);
|
);
|
||||||
|
|
||||||
if BlockPos::from(position) != target || horizontal_distance_from_target > 0.25 {
|
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 {
|
if horizontal_distance_from_start < 1.25 {
|
||||||
// this basically just exists to avoid doing spins while we're falling
|
// this basically just exists to avoid doing spins while we're falling
|
||||||
look_at_events.send(LookAtEvent {
|
look_at_events.send(LookAtEvent {
|
||||||
|
@ -232,6 +231,11 @@ fn execute_descend_move(
|
||||||
direction: WalkDirection::Forward,
|
direction: WalkDirection::Forward,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
walk_events.send(StartWalkEvent {
|
||||||
|
entity,
|
||||||
|
direction: WalkDirection::None,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
pub mod basic;
|
pub mod basic;
|
||||||
pub mod parkour;
|
pub mod parkour;
|
||||||
|
|
||||||
use std::{cell::RefCell, fmt::Debug};
|
use std::{cell::RefCell, fmt::Debug, sync::Arc};
|
||||||
|
|
||||||
use crate::{JumpEvent, LookAtEvent};
|
use crate::{JumpEvent, LookAtEvent};
|
||||||
|
|
||||||
|
@ -10,8 +10,9 @@ use azalea_block::BlockState;
|
||||||
use azalea_client::{StartSprintEvent, StartWalkEvent};
|
use azalea_client::{StartSprintEvent, StartWalkEvent};
|
||||||
use azalea_core::position::{BlockPos, ChunkBlockPos, ChunkPos, Vec3};
|
use azalea_core::position::{BlockPos, ChunkBlockPos, ChunkPos, Vec3};
|
||||||
use azalea_physics::collision::BlockWithShape;
|
use azalea_physics::collision::BlockWithShape;
|
||||||
use azalea_world::ChunkStorage;
|
use azalea_world::Instance;
|
||||||
use bevy_ecs::{entity::Entity, event::EventWriter};
|
use bevy_ecs::{entity::Entity, event::EventWriter};
|
||||||
|
use parking_lot::RwLock;
|
||||||
|
|
||||||
type Edge = astar::Edge<BlockPos, MoveData>;
|
type Edge = astar::Edge<BlockPos, MoveData>;
|
||||||
|
|
||||||
|
@ -33,15 +34,18 @@ impl Debug for MoveData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PathfinderCtx<'a> {
|
pub struct PathfinderCtx {
|
||||||
world: &'a ChunkStorage,
|
min_y: i32,
|
||||||
|
world_lock: Arc<RwLock<Instance>>,
|
||||||
cached_chunks: RefCell<Vec<(ChunkPos, Vec<azalea_world::Section>)>>,
|
cached_chunks: RefCell<Vec<(ChunkPos, Vec<azalea_world::Section>)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PathfinderCtx<'a> {
|
impl PathfinderCtx {
|
||||||
pub fn new(world: &'a ChunkStorage) -> Self {
|
pub fn new(world_lock: Arc<RwLock<Instance>>) -> Self {
|
||||||
|
let min_y = world_lock.read().chunks.min_y;
|
||||||
Self {
|
Self {
|
||||||
world,
|
min_y,
|
||||||
|
world_lock,
|
||||||
cached_chunks: Default::default(),
|
cached_chunks: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,11 +65,12 @@ impl<'a> PathfinderCtx<'a> {
|
||||||
return azalea_world::chunk_storage::get_block_state_from_sections(
|
return azalea_world::chunk_storage::get_block_state_from_sections(
|
||||||
sections,
|
sections,
|
||||||
&chunk_block_pos,
|
&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();
|
let chunk = chunk.read();
|
||||||
|
|
||||||
cached_chunks.push((chunk_pos, chunk.sections.clone()));
|
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(
|
azalea_world::chunk_storage::get_block_state_from_sections(
|
||||||
&chunk.sections,
|
&chunk.sections,
|
||||||
&chunk_block_pos,
|
&chunk_block_pos,
|
||||||
self.world.min_y,
|
self.min_y,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +141,7 @@ impl<'a> PathfinderCtx<'a> {
|
||||||
distance += 1;
|
distance += 1;
|
||||||
current_pos = current_pos.down(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;
|
return u32::MAX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,7 +214,7 @@ mod tests {
|
||||||
.chunks
|
.chunks
|
||||||
.set_block_state(&BlockPos::new(0, 1, 0), BlockState::AIR, &world);
|
.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, 0, 0)));
|
||||||
assert!(ctx.is_block_passable(&BlockPos::new(0, 1, 0),));
|
assert!(ctx.is_block_passable(&BlockPos::new(0, 1, 0),));
|
||||||
}
|
}
|
||||||
|
@ -230,7 +235,7 @@ mod tests {
|
||||||
.chunks
|
.chunks
|
||||||
.set_block_state(&BlockPos::new(0, 1, 0), BlockState::AIR, &world);
|
.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, 0, 0)));
|
||||||
assert!(!ctx.is_block_solid(&BlockPos::new(0, 1, 0)));
|
assert!(!ctx.is_block_solid(&BlockPos::new(0, 1, 0)));
|
||||||
}
|
}
|
||||||
|
@ -257,7 +262,7 @@ mod tests {
|
||||||
.chunks
|
.chunks
|
||||||
.set_block_state(&BlockPos::new(0, 3, 0), BlockState::AIR, &world);
|
.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, 1, 0)));
|
||||||
assert!(!ctx.is_standable(&BlockPos::new(0, 0, 0)));
|
assert!(!ctx.is_standable(&BlockPos::new(0, 0, 0)));
|
||||||
assert!(!ctx.is_standable(&BlockPos::new(0, 2, 0)));
|
assert!(!ctx.is_standable(&BlockPos::new(0, 2, 0)));
|
||||||
|
|
Loading…
Add table
Reference in a new issue