aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--azalea-client/src/client.rs24
-rw-r--r--azalea/src/swarm/mod.rs6
2 files changed, 19 insertions, 11 deletions
diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs
index c6530e75..6937348d 100644
--- a/azalea-client/src/client.rs
+++ b/azalea-client/src/client.rs
@@ -1,7 +1,7 @@
use std::{
collections::HashMap,
fmt::Debug,
- io,
+ io, mem,
net::SocketAddr,
sync::Arc,
thread,
@@ -130,7 +130,8 @@ impl<'a> StartClientOpts<'a> {
let mut app = App::new();
app.add_plugins(DefaultPlugins);
- let ecs_lock = start_ecs_runner(app);
+ let (ecs_lock, start_running_systems) = start_ecs_runner(app);
+ start_running_systems();
Self {
ecs_lock,
@@ -663,12 +664,14 @@ impl Plugin for AzaleaPlugin {
}
}
-/// Start running the ECS loop!
+/// Create the ECS world, and return a function that begins running systems.
+/// This exists to allow you to make last-millisecond updates to the world
+/// before any systems start running.
///
/// You can create your app with `App::new()`, but don't forget to add
/// [`DefaultPlugins`].
#[doc(hidden)]
-pub fn start_ecs_runner(mut app: App) -> Arc<Mutex<World>> {
+pub fn start_ecs_runner(mut app: App) -> (Arc<Mutex<World>>, impl FnOnce()) {
// this block is based on Bevy's default runner:
// https://github.com/bevyengine/bevy/blob/390877cdae7a17095a75c8f9f1b4241fe5047e83/crates/bevy_app/src/schedule_runner.rs#L77-L85
if app.plugins_state() != PluginsState::Cleaned {
@@ -686,14 +689,15 @@ pub fn start_ecs_runner(mut app: App) -> Arc<Mutex<World>> {
// all resources should have been added by now so we can take the ecs from the
// app
- let ecs = Arc::new(Mutex::new(std::mem::take(app.world_mut())));
+ let ecs = Arc::new(Mutex::new(mem::take(app.world_mut())));
- tokio::spawn(run_schedule_loop(
- ecs.clone(),
- *app.main().update_schedule.as_ref().unwrap(),
- ));
+ let ecs_clone = ecs.clone();
+ let outer_schedule_label = *app.main().update_schedule.as_ref().unwrap();
+ let start_running_systems = move || {
+ tokio::spawn(run_schedule_loop(ecs_clone, outer_schedule_label));
+ };
- ecs
+ (ecs, start_running_systems)
}
async fn run_schedule_loop(ecs: Arc<Mutex<World>>, outer_schedule_label: InternedScheduleLabel) {
diff --git a/azalea/src/swarm/mod.rs b/azalea/src/swarm/mod.rs
index 6ecf4d32..9be5d7ea 100644
--- a/azalea/src/swarm/mod.rs
+++ b/azalea/src/swarm/mod.rs
@@ -396,7 +396,7 @@ where
let main_schedule_label = self.app.main().update_schedule.unwrap();
- let ecs_lock = start_ecs_runner(self.app);
+ let (ecs_lock, start_running_systems) = start_ecs_runner(self.app);
let swarm = Swarm {
ecs_lock: ecs_lock.clone(),
@@ -420,6 +420,10 @@ where
ecs.clear_trackers();
}
+ // only do this after we inserted the Swarm and state resources to avoid errors
+ // where Res<Swarm> is inaccessible
+ start_running_systems();
+
// SwarmBuilder (self) isn't Send so we have to take all the things we need out
// of it
let swarm_clone = swarm.clone();