aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2023-10-03 22:08:18 -0500
committermat <git@matdoes.dev>2023-10-03 22:08:18 -0500
commitbffa28e7069669198906566058aaa668922c54bc (patch)
tree8297aa7544c4f8d9e3a723580cf6d9ebec9b3b8b
parent9c6459a73b232cd73857815677b63ea02cdce13a (diff)
downloadazalea-drasl-bffa28e7069669198906566058aaa668922c54bc.tar.xz
fix world being locked while pathfinding
-rw-r--r--azalea/benches/pathfinder.rs5
-rw-r--r--azalea/src/pathfinder/mod.rs11
-rw-r--r--azalea/src/pathfinder/moves/basic.rs6
-rw-r--r--azalea/src/pathfinder/moves/mod.rs33
4 files changed, 31 insertions, 24 deletions
diff --git a/azalea/benches/pathfinder.rs b/azalea/benches/pathfinder.rs
index e7c52d57..eaeaa9fb 100644
--- a/azalea/benches/pathfinder.rs
+++ b/azalea/benches/pathfinder.rs
@@ -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);
diff --git a/azalea/src/pathfinder/mod.rs b/azalea/src/pathfinder/mod.rs
index 99bc7787..c71d0b42 100644
--- a/azalea/src/pathfinder/mod.rs
+++ b/azalea/src/pathfinder/mod.rs
@@ -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!(
diff --git a/azalea/src/pathfinder/moves/basic.rs b/azalea/src/pathfinder/moves/basic.rs
index 26a77f4e..412f463e 100644
--- a/azalea/src/pathfinder/moves/basic.rs
+++ b/azalea/src/pathfinder/moves/basic.rs
@@ -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,
+ });
}
}
diff --git a/azalea/src/pathfinder/moves/mod.rs b/azalea/src/pathfinder/moves/mod.rs
index 39e5374f..1a626c1c 100644
--- a/azalea/src/pathfinder/moves/mod.rs
+++ b/azalea/src/pathfinder/moves/mod.rs
@@ -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)));