diff options
Diffstat (limited to 'azalea-client')
| -rw-r--r-- | azalea-client/Cargo.toml | 9 | ||||
| -rwxr-xr-x | azalea-client/src/chat.rs | 24 | ||||
| -rw-r--r-- | azalea-client/src/client.rs | 102 | ||||
| -rw-r--r-- | azalea-client/src/disconnect.rs | 29 | ||||
| -rw-r--r-- | azalea-client/src/entity_query.rs | 12 | ||||
| -rw-r--r-- | azalea-client/src/events.rs | 12 | ||||
| -rw-r--r-- | azalea-client/src/lib.rs | 1 | ||||
| -rw-r--r-- | azalea-client/src/local_player.rs | 15 | ||||
| -rw-r--r-- | azalea-client/src/movement.rs | 37 | ||||
| -rw-r--r-- | azalea-client/src/packet_handling.rs | 66 | ||||
| -rwxr-xr-x | azalea-client/src/player.rs | 4 | ||||
| -rw-r--r-- | azalea-client/src/task_pool.rs | 26 |
12 files changed, 182 insertions, 155 deletions
diff --git a/azalea-client/Cargo.toml b/azalea-client/Cargo.toml index 6bb31069..f25aa290 100644 --- a/azalea-client/Cargo.toml +++ b/azalea-client/Cargo.toml @@ -16,14 +16,15 @@ azalea-block = { path = "../azalea-block", version = "0.6.0" } azalea-chat = { path = "../azalea-chat", version = "0.6.0" } azalea-core = { path = "../azalea-core", version = "0.6.0" } azalea-crypto = { path = "../azalea-crypto", version = "0.6.0" } -azalea-ecs = { path = "../azalea-ecs", version = "0.6.0" } azalea-physics = { path = "../azalea-physics", version = "0.6.0" } azalea-protocol = { path = "../azalea-protocol", version = "0.6.0" } azalea-registry = { path = "../azalea-registry", version = "0.6.0" } azalea-world = { path = "../azalea-world", version = "0.6.0" } -bevy_log = "0.9.1" -bevy_tasks = "0.9.1" -bevy_time = "0.9.1" +bevy_app = "0.10.0" +bevy_ecs = "0.10.0" +bevy_log = "0.10.0" +bevy_tasks = "0.10.0" +bevy_time = "0.10.0" derive_more = { version = "0.99.17", features = ["deref", "deref_mut"] } futures = "0.3.25" log = "0.4.17" diff --git a/azalea-client/src/chat.rs b/azalea-client/src/chat.rs index e127f0d7..0ae0250a 100755 --- a/azalea-client/src/chat.rs +++ b/azalea-client/src/chat.rs @@ -1,18 +1,18 @@ //! Implementations of chat-related features. use azalea_chat::FormattedText; -use azalea_ecs::{ - app::{App, Plugin}, - entity::Entity, - event::{EventReader, EventWriter}, - schedule::IntoSystemDescriptor, -}; use azalea_protocol::packets::game::{ clientbound_player_chat_packet::ClientboundPlayerChatPacket, clientbound_system_chat_packet::ClientboundSystemChatPacket, serverbound_chat_command_packet::ServerboundChatCommandPacket, serverbound_chat_packet::{LastSeenMessagesUpdate, ServerboundChatPacket}, }; +use bevy_app::{App, Plugin}; +use bevy_ecs::{ + entity::Entity, + event::{EventReader, EventWriter}, + schedule::{IntoSystemConfig, IntoSystemConfigs}, +}; use std::{ sync::Arc, time::{SystemTime, UNIX_EPOCH}, @@ -159,12 +159,12 @@ impl Plugin for ChatPlugin { app.add_event::<SendChatEvent>() .add_event::<SendChatKindEvent>() .add_event::<ChatReceivedEvent>() - .add_system(handle_send_chat_event.label("handle_send_chat_event")) - .add_system( - handle_send_chat_kind_event - .label("handle_send_chat_kind_event") - .after(handle_send_chat_event) - .after(handle_send_packet_event), + .add_systems( + ( + handle_send_chat_event, + handle_send_chat_kind_event.after(handle_send_packet_event), + ) + .chain(), ); } } diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs index 661858db..79501fd4 100644 --- a/azalea-client/src/client.rs +++ b/azalea-client/src/client.rs @@ -6,25 +6,16 @@ use crate::{ death_event, handle_send_packet_event, update_in_loaded_chunk, GameProfileComponent, LocalPlayer, PhysicsState, SendPacketEvent, }, - movement::{local_player_ai_step, send_position, sprint_listener, walk_listener}, + movement::PlayerMovePlugin, packet_handling::{self, PacketHandlerPlugin, PacketReceiver}, player::retroactively_add_game_profile_component, task_pool::TaskPoolPlugin, - Account, PlayerInfo, StartSprintEvent, StartWalkEvent, + Account, PlayerInfo, }; use azalea_auth::{game_profile::GameProfile, sessionserver::ClientSessionServerError}; use azalea_chat::FormattedText; -use azalea_ecs::{ - app::{App, Plugin, PluginGroup, PluginGroupBuilder}, - bundle::Bundle, - component::Component, - entity::Entity, - schedule::{IntoSystemDescriptor, ReportExecutionOrderAmbiguities, Schedule, Stage, SystemSet}, - AppTickExt, -}; -use azalea_ecs::{ecs::Ecs, TickPlugin}; -use azalea_physics::PhysicsPlugin; +use azalea_physics::{PhysicsPlugin, PhysicsSet}; use azalea_protocol::{ connect::{Connection, ConnectionError}, packets::{ @@ -46,13 +37,23 @@ use azalea_protocol::{ resolver, ServerAddress, }; use azalea_world::{ - entity::{EntityPlugin, Local, WorldName}, - PartialWorld, World, WorldContainer, + entity::{EntityPlugin, EntityUpdateSet, Local, WorldName}, + Instance, PartialWorld, WorldContainer, +}; +use bevy_app::{App, CoreSchedule, Plugin, PluginGroup, PluginGroupBuilder}; +use bevy_ecs::{ + bundle::Bundle, + component::Component, + entity::Entity, + schedule::IntoSystemConfig, + schedule::{LogLevel, ScheduleBuildSettings, ScheduleLabel}, + world::World, }; use bevy_log::LogPlugin; +use bevy_time::{prelude::FixedTime, TimePlugin}; use log::{debug, error}; use parking_lot::{Mutex, RwLock}; -use std::{collections::HashMap, fmt::Debug, io, net::SocketAddr, sync::Arc}; +use std::{collections::HashMap, fmt::Debug, io, net::SocketAddr, sync::Arc, time::Duration}; use thiserror::Error; use tokio::{sync::mpsc, time}; use uuid::Uuid; @@ -86,7 +87,7 @@ pub struct Client { /// The entity component system. You probably don't need to access this /// directly. Note that if you're using a shared world (i.e. a swarm), this /// will contain all entities in all worlds. - pub ecs: Arc<Mutex<Ecs>>, + pub ecs: Arc<Mutex<World>>, /// Use this to force the client to run the schedule outside of a tick. pub run_schedule_sender: mpsc::UnboundedSender<()>, @@ -120,7 +121,7 @@ impl Client { pub fn new( profile: GameProfile, entity: Entity, - ecs: Arc<Mutex<Ecs>>, + ecs: Arc<Mutex<World>>, run_schedule_sender: mpsc::UnboundedSender<()>, ) -> Self { Self { @@ -180,7 +181,7 @@ impl Client { /// Create a [`Client`] when you already have the ECS made with /// [`start_ecs`]. You'd usually want to use [`Self::join`] instead. pub async fn start_client( - ecs_lock: Arc<Mutex<Ecs>>, + ecs_lock: Arc<Mutex<World>>, account: &Account, address: &ServerAddress, resolved_address: &SocketAddr, @@ -226,7 +227,7 @@ impl Client { packet_writer_sender, // default to an empty world, it'll be set correctly later when we // get the login packet - Arc::new(RwLock::new(World::default())), + Arc::new(RwLock::new(Instance::default())), read_packets_task, write_packets_task, ); @@ -382,13 +383,13 @@ impl Client { }); } - pub fn local_player<'a>(&'a self, ecs: &'a mut Ecs) -> &'a LocalPlayer { + pub fn local_player<'a>(&'a self, ecs: &'a mut World) -> &'a LocalPlayer { self.query::<&LocalPlayer>(ecs) } pub fn local_player_mut<'a>( &'a self, - ecs: &'a mut Ecs, - ) -> azalea_ecs::ecs::Mut<'a, LocalPlayer> { + ecs: &'a mut World, + ) -> bevy_ecs::world::Mut<'a, LocalPlayer> { self.query::<&mut LocalPlayer>(ecs) } @@ -416,7 +417,7 @@ impl Client { /// client, then it'll be the same as the world the client has loaded. /// If the client using a shared world, then the shared world will be a /// superset of the client's world. - pub fn world(&self) -> Arc<RwLock<World>> { + pub fn world(&self) -> Arc<RwLock<Instance>> { let world_name = self.component::<WorldName>(); let ecs = self.ecs.lock(); let world_container = ecs.resource::<WorldContainer>(); @@ -493,33 +494,20 @@ pub struct JoinedClientBundle { pub struct AzaleaPlugin; impl Plugin for AzaleaPlugin { fn build(&self, app: &mut App) { - app.add_event::<StartWalkEvent>() - .add_event::<StartSprintEvent>(); - - app.add_tick_system_set( - SystemSet::new() - .with_system(send_position.after("ai_step")) - .with_system(update_in_loaded_chunk.before(send_position).after("travel")) - .with_system( - local_player_ai_step - .before(azalea_physics::ai_step) - .label("ai_step"), - ), + // Minecraft ticks happen every 50ms + app.insert_resource(FixedTime::new(Duration::from_millis(50))); + + app.add_system( + update_in_loaded_chunk + .after(PhysicsSet) + .after(handle_send_packet_event), ); // fire the Death event when the player dies. app.add_system(death_event); - // walk and sprint event listeners - app.add_system(walk_listener.label("walk_listener")) - .add_system( - sprint_listener - .label("sprint_listener") - .before("walk_listener"), - ); - // add GameProfileComponent when we get an AddPlayerEvent - app.add_system(retroactively_add_game_profile_component.after("update_indexes")); + app.add_system(retroactively_add_game_profile_component.after(EntityUpdateSet::Index)); app.add_event::<SendPacketEvent>() .add_system(handle_send_packet_event); @@ -544,7 +532,12 @@ pub fn init_ecs_app() -> App { let mut app = App::new(); - app.insert_resource(ReportExecutionOrderAmbiguities); + app.edit_schedule(CoreSchedule::Main, |schedule| { + schedule.set_build_settings(ScheduleBuildSettings { + ambiguity_detection: LogLevel::Warn, + ..Default::default() + }); + }); app.add_plugins(DefaultPlugins); app @@ -554,17 +547,19 @@ pub fn init_ecs_app() -> App { /// first. #[doc(hidden)] pub fn start_ecs( - app: App, + mut app: App, run_schedule_receiver: mpsc::UnboundedReceiver<()>, run_schedule_sender: mpsc::UnboundedSender<()>, -) -> Arc<Mutex<Ecs>> { +) -> Arc<Mutex<World>> { + app.setup(); + // all resources should have been added by now so we can take the ecs from the // app let ecs = Arc::new(Mutex::new(app.world)); tokio::spawn(run_schedule_loop( ecs.clone(), - app.schedule, + app.outer_schedule_label, run_schedule_receiver, )); tokio::spawn(tick_run_schedule_loop(run_schedule_sender)); @@ -573,14 +568,16 @@ pub fn start_ecs( } async fn run_schedule_loop( - ecs: Arc<Mutex<Ecs>>, - mut schedule: Schedule, + ecs: Arc<Mutex<World>>, + outer_schedule_label: Box<dyn ScheduleLabel>, mut run_schedule_receiver: mpsc::UnboundedReceiver<()>, ) { loop { // whenever we get an event from run_schedule_receiver, run the schedule run_schedule_receiver.recv().await; - schedule.run(&mut ecs.lock()); + let mut ecs = ecs.lock(); + ecs.run_schedule_ref(&*outer_schedule_label); + ecs.clear_trackers(); } } @@ -609,7 +606,7 @@ impl PluginGroup for DefaultPlugins { fn build(self) -> PluginGroupBuilder { PluginGroupBuilder::start::<Self>() .add(LogPlugin::default()) - .add(TickPlugin::default()) + .add(TimePlugin::default()) .add(PacketHandlerPlugin) .add(AzaleaPlugin) .add(EntityPlugin) @@ -618,5 +615,6 @@ impl PluginGroup for DefaultPlugins { .add(TaskPoolPlugin::default()) .add(ChatPlugin) .add(DisconnectPlugin) + .add(PlayerMovePlugin) } } diff --git a/azalea-client/src/disconnect.rs b/azalea-client/src/disconnect.rs index 9fd57e57..3b8d133e 100644 --- a/azalea-client/src/disconnect.rs +++ b/azalea-client/src/disconnect.rs @@ -1,30 +1,30 @@ //! Disconnect a client from the server. -use azalea_ecs::{ - app::{App, CoreStage, Plugin}, +use bevy_app::{App, CoreSet, Plugin}; +use bevy_ecs::{ component::Component, entity::Entity, event::{EventReader, EventWriter}, query::Changed, - schedule::IntoSystemDescriptor, + schedule::IntoSystemConfigs, system::{Commands, Query}, - AppTickExt, }; use derive_more::Deref; -use crate::{client::JoinedClientBundle, movement::send_position, LocalPlayer}; +use crate::{client::JoinedClientBundle, LocalPlayer}; pub struct DisconnectPlugin; impl Plugin for DisconnectPlugin { fn build(&self, app: &mut App) { - app.add_event::<DisconnectEvent>() - .add_system_to_stage(CoreStage::PostUpdate, handle_disconnect) - .add_tick_system( - update_read_packets_task_running_component - .before(disconnect_on_read_packets_ended) - .before(send_position), + app.add_event::<DisconnectEvent>().add_systems( + ( + update_read_packets_task_running_component, + disconnect_on_read_packets_ended, + remove_components_from_disconnected_players, ) - .add_tick_system(disconnect_on_read_packets_ended); + .in_base_set(CoreSet::PostUpdate) + .chain(), + ); } } @@ -35,7 +35,10 @@ pub struct DisconnectEvent { /// System that removes the [`JoinedClientBundle`] from the entity when it /// receives a [`DisconnectEvent`]. -pub fn handle_disconnect(mut commands: Commands, mut events: EventReader<DisconnectEvent>) { +pub fn remove_components_from_disconnected_players( + mut commands: Commands, + mut events: EventReader<DisconnectEvent>, +) { for DisconnectEvent { entity } in events.iter() { commands.entity(*entity).remove::<JoinedClientBundle>(); } diff --git a/azalea-client/src/entity_query.rs b/azalea-client/src/entity_query.rs index e39a7d2f..8fe94659 100644 --- a/azalea-client/src/entity_query.rs +++ b/azalea-client/src/entity_query.rs @@ -1,10 +1,10 @@ use std::sync::Arc; -use azalea_ecs::{ +use bevy_ecs::{ component::Component, - ecs::Ecs, entity::Entity, query::{ROQueryItem, ReadOnlyWorldQuery, WorldQuery}, + world::World, }; use parking_lot::Mutex; @@ -22,7 +22,7 @@ impl Client { /// .is_some(); /// # } /// ``` - pub fn query<'w, Q: WorldQuery>(&self, ecs: &'w mut Ecs) -> <Q as WorldQuery>::Item<'w> { + pub fn query<'w, Q: WorldQuery>(&self, ecs: &'w mut World) -> <Q as WorldQuery>::Item<'w> { ecs.query::<Q>() .get_mut(ecs, self.entity) .expect("Our client is missing a required component.") @@ -38,7 +38,7 @@ impl Client { /// Note that this will very likely change in the future. /// ``` /// use azalea_client::{Client, GameProfileComponent}; - /// use azalea_ecs::query::With; + /// use bevy_ecs::query::With; /// use azalea_world::entity::{Position, metadata::Player}; /// /// # fn example(mut bot: Client, sender_name: String) { @@ -74,7 +74,7 @@ impl Client { } pub trait EntityPredicate<Q: ReadOnlyWorldQuery, Filter: ReadOnlyWorldQuery> { - fn find(&self, ecs_lock: Arc<Mutex<Ecs>>) -> Option<Entity>; + fn find(&self, ecs_lock: Arc<Mutex<World>>) -> Option<Entity>; } impl<F, Q, Filter> EntityPredicate<(Q,), Filter> for F where @@ -82,7 +82,7 @@ where Q: ReadOnlyWorldQuery, Filter: ReadOnlyWorldQuery, { - fn find(&self, ecs_lock: Arc<Mutex<Ecs>>) -> Option<Entity> { + fn find(&self, ecs_lock: Arc<Mutex<World>>) -> Option<Entity> { let mut ecs = ecs_lock.lock(); let mut query = ecs.query_filtered::<(Entity, Q), Filter>(); let entity = query.iter(&ecs).find(|(_, q)| (self)(q)).map(|(e, _)| e); diff --git a/azalea-client/src/events.rs b/azalea-client/src/events.rs index 085f5368..c7ff20aa 100644 --- a/azalea-client/src/events.rs +++ b/azalea-client/src/events.rs @@ -3,18 +3,12 @@ use std::sync::Arc; -use azalea_ecs::{ - app::{App, Plugin}, - component::Component, - event::EventReader, - query::Added, - system::Query, - AppTickExt, -}; use azalea_protocol::packets::game::{ clientbound_player_combat_kill_packet::ClientboundPlayerCombatKillPacket, ClientboundGamePacket, }; use azalea_world::entity::MinecraftEntityId; +use bevy_app::{App, CoreSchedule, IntoSystemAppConfig, Plugin}; +use bevy_ecs::{component::Component, event::EventReader, query::Added, system::Query}; use derive_more::{Deref, DerefMut}; use tokio::sync::mpsc; @@ -115,7 +109,7 @@ impl Plugin for EventPlugin { .add_system(remove_player_listener) .add_system(death_listener) .add_system(keepalive_listener) - .add_tick_system(tick_listener); + .add_system(tick_listener.in_schedule(CoreSchedule::FixedUpdate)); } } diff --git a/azalea-client/src/lib.rs b/azalea-client/src/lib.rs index 8e119c0e..44a4db6b 100644 --- a/azalea-client/src/lib.rs +++ b/azalea-client/src/lib.rs @@ -26,7 +26,6 @@ mod player; pub mod task_pool; pub use account::Account; -pub use azalea_ecs as ecs; pub use client::{init_ecs_app, start_ecs, Client, ClientInformation, JoinError}; pub use events::Event; pub use local_player::{GameProfileComponent, LocalPlayer}; diff --git a/azalea-client/src/local_player.rs b/azalea-client/src/local_player.rs index d31f840f..be847e78 100644 --- a/azalea-client/src/local_player.rs +++ b/azalea-client/src/local_player.rs @@ -2,14 +2,13 @@ use std::{collections::HashMap, io, sync::Arc}; use azalea_auth::game_profile::GameProfile; use azalea_core::ChunkPos; -use azalea_ecs::component::Component; -use azalea_ecs::entity::Entity; -use azalea_ecs::event::EventReader; -use azalea_ecs::{query::Added, system::Query}; use azalea_protocol::packets::game::ServerboundGamePacket; use azalea_world::{ entity::{self, Dead}, - PartialWorld, World, + Instance, PartialWorld, +}; +use bevy_ecs::{ + component::Component, entity::Entity, event::EventReader, query::Added, system::Query, }; use derive_more::{Deref, DerefMut}; use parking_lot::RwLock; @@ -44,7 +43,7 @@ pub struct LocalPlayer { pub partial_world: Arc<RwLock<PartialWorld>>, /// The world is the combined [`PartialWorld`]s of all clients in the same /// world. (Only relevant if you're using a shared world, i.e. a swarm) - pub world: Arc<RwLock<World>>, + pub world: Arc<RwLock<Instance>>, /// A task that reads packets from the server. The client is disconnected /// when this task ends. @@ -88,7 +87,7 @@ impl LocalPlayer { pub fn new( entity: Entity, packet_writer: mpsc::UnboundedSender<ServerboundGamePacket>, - world: Arc<RwLock<World>>, + world: Arc<RwLock<Instance>>, read_packets_task: JoinHandle<()>, write_packets_task: JoinHandle<()>, ) -> Self { @@ -129,7 +128,7 @@ impl Drop for LocalPlayer { /// Update the [`LocalPlayerInLoadedChunk`] component for all [`LocalPlayer`]s. pub fn update_in_loaded_chunk( - mut commands: azalea_ecs::system::Commands, + mut commands: bevy_ecs::system::Commands, query: Query<(Entity, &LocalPlayer, &entity::Position)>, ) { for (entity, local_player, position) in &query { diff --git a/azalea-client/src/movement.rs b/azalea-client/src/movement.rs index f379501c..f6123c70 100644 --- a/azalea-client/src/movement.rs +++ b/azalea-client/src/movement.rs @@ -1,7 +1,8 @@ use crate::client::Client; -use crate::local_player::{LocalPlayer, LocalPlayerInLoadedChunk, PhysicsState}; -use azalea_ecs::entity::Entity; -use azalea_ecs::{event::EventReader, query::With, system::Query}; +use crate::local_player::{ + update_in_loaded_chunk, LocalPlayer, LocalPlayerInLoadedChunk, PhysicsState, +}; +use azalea_physics::{force_jump_listener, PhysicsSet}; use azalea_protocol::packets::game::serverbound_player_command_packet::ServerboundPlayerCommandPacket; use azalea_protocol::packets::game::{ serverbound_move_player_pos_packet::ServerboundMovePlayerPosPacket, @@ -13,6 +14,14 @@ use azalea_world::{ entity::{self, metadata::Sprinting, Attributes, Jumping, MinecraftEntityId}, MoveEntityError, }; +use bevy_app::{App, CoreSchedule, IntoSystemAppConfigs, Plugin}; +use bevy_ecs::{ + entity::Entity, + event::EventReader, + query::With, + schedule::{IntoSystemConfig, IntoSystemConfigs}, + system::Query, +}; use std::backtrace::Backtrace; use thiserror::Error; @@ -34,6 +43,28 @@ impl From<MoveEntityError> for MovePlayerError { } } +pub struct PlayerMovePlugin; + +impl Plugin for PlayerMovePlugin { + fn build(&self, app: &mut App) { + app.add_event::<StartWalkEvent>() + .add_event::<StartSprintEvent>() + .add_systems( + (sprint_listener, walk_listener) + .chain() + .before(force_jump_listener), + ) + .add_systems( + ( + local_player_ai_step.in_set(PhysicsSet), + send_position.after(update_in_loaded_chunk), + ) + .chain() + .in_schedule(CoreSchedule::FixedUpdate), + ); + } +} + impl Client { /// Set whether we're jumping. This acts as if you held space in /// vanilla. If you want to jump once, use the `jump` function. diff --git a/azalea-client/src/packet_handling.rs b/azalea-client/src/packet_handling.rs index 9f8c5f1a..76e6ee41 100644 --- a/azalea-client/src/packet_handling.rs +++ b/azalea-client/src/packet_handling.rs @@ -1,15 +1,6 @@ use std::{collections::HashSet, io::Cursor, sync::Arc}; use azalea_core::{ChunkPos, ResourceLocation, Vec3}; -use azalea_ecs::{ - app::{App, CoreStage, Plugin}, - component::Component, - ecs::Ecs, - entity::Entity, - event::{EventReader, EventWriter, Events}, - schedule::{StageLabel, SystemStage}, - system::{Commands, Query, ResMut, SystemState}, -}; use azalea_protocol::{ connect::{ReadConnection, WriteConnection}, packets::game::{ @@ -25,12 +16,21 @@ use azalea_protocol::{ use azalea_world::{ entity::{ metadata::{apply_metadata, Health, PlayerMetadataBundle}, - set_rotation, Dead, EntityBundle, EntityKind, LastSentPosition, MinecraftEntityId, Physics, - PlayerBundle, Position, WorldName, + set_rotation, Dead, EntityBundle, EntityKind, EntityUpdateSet, LastSentPosition, + MinecraftEntityId, Physics, PlayerBundle, Position, WorldName, }, entity::{LoadedBy, RelativeEntityUpdate}, PartialWorld, WorldContainer, }; +use bevy_app::{App, CoreSet, Plugin}; +use bevy_ecs::{ + component::Component, + entity::Entity, + event::{EventReader, EventWriter, Events}, + schedule::IntoSystemConfig, + system::{Commands, Query, ResMut, SystemState}, + world::World, +}; use log::{debug, error, trace, warn}; use parking_lot::Mutex; use tokio::sync::mpsc; @@ -46,7 +46,7 @@ use crate::{ /// ``` /// # use azalea_client::packet_handling::PacketEvent; /// # use azalea_protocol::packets::game::ClientboundGamePacket; -/// # use azalea_ecs::event::EventReader; +/// # use bevy_ecs::event::EventReader; /// /// fn handle_packets(mut events: EventReader<PacketEvent>) { /// for PacketEvent { @@ -72,25 +72,22 @@ pub struct PacketEvent { pub struct PacketHandlerPlugin; -#[derive(StageLabel)] -pub struct SendPacketEventsStage; - impl Plugin for PacketHandlerPlugin { fn build(&self, app: &mut App) { - app.add_stage_before( - CoreStage::PreUpdate, - SendPacketEventsStage, - SystemStage::parallel(), - ) - .add_system_to_stage(SendPacketEventsStage, send_packet_events) - .add_system_to_stage(CoreStage::PreUpdate, process_packet_events) - .init_resource::<Events<PacketEvent>>() - .add_event::<AddPlayerEvent>() - .add_event::<RemovePlayerEvent>() - .add_event::<UpdatePlayerEvent>() - .add_event::<ChatReceivedEvent>() - .add_event::<DeathEvent>() - .add_event::<KeepAliveEvent>(); + app.add_system(send_packet_events.in_base_set(CoreSet::First)) + .add_system( + process_packet_events + .in_base_set(CoreSet::PreUpdate) + // we want to index and deindex right after + .before(EntityUpdateSet::Deindex), + ) + .init_resource::<Events<PacketEvent>>() + .add_event::<AddPlayerEvent>() + .add_event::<RemovePlayerEvent>() + .add_event::<UpdatePlayerEvent>() + .add_event::<ChatReceivedEvent>() + .add_event::<DeathEvent>() + .add_event::<KeepAliveEvent>(); } } @@ -168,7 +165,7 @@ pub fn send_packet_events( } } -fn process_packet_events(ecs: &mut Ecs) { +fn process_packet_events(ecs: &mut World) { let mut events_owned = Vec::new(); let mut system_state: SystemState<EventReader<PacketEvent>> = SystemState::new(ecs); let mut events = system_state.get_mut(ecs); @@ -715,8 +712,7 @@ fn process_packet_events(ecs: &mut Ecs) { if let Some(entity) = entity { let new_position = p.position; - commands.add(RelativeEntityUpdate { - entity, + commands.entity(entity).add(RelativeEntityUpdate { partial_world: local_player.partial_world.clone(), update: Box::new(move |entity| { let mut position = entity.get_mut::<Position>().unwrap(); @@ -747,8 +743,7 @@ fn process_packet_events(ecs: &mut Ecs) { if let Some(entity) = entity { let delta = p.delta.clone(); - commands.add(RelativeEntityUpdate { - entity, + commands.entity(entity).add(RelativeEntityUpdate { partial_world: local_player.partial_world.clone(), update: Box::new(move |entity_mut| { let mut position = entity_mut.get_mut::<Position>().unwrap(); @@ -776,8 +771,7 @@ fn process_packet_events(ecs: &mut Ecs) { if let Some(entity) = entity { let delta = p.delta.clone(); - commands.add(RelativeEntityUpdate { - entity, + commands.entity(entity).add(RelativeEntityUpdate { partial_world: local_player.partial_world.clone(), update: Box::new(move |entity_mut| { let mut position = entity_mut.get_mut::<Position>().unwrap(); diff --git a/azalea-client/src/player.rs b/azalea-client/src/player.rs index 3680e2d0..c2c8a94e 100755 --- a/azalea-client/src/player.rs +++ b/azalea-client/src/player.rs @@ -1,11 +1,11 @@ use azalea_auth::game_profile::GameProfile; use azalea_chat::FormattedText; use azalea_core::GameType; -use azalea_ecs::{ +use azalea_world::entity::EntityInfos; +use bevy_ecs::{ event::EventReader, system::{Commands, Res}, }; -use azalea_world::entity::EntityInfos; use uuid::Uuid; use crate::{packet_handling::AddPlayerEvent, GameProfileComponent}; diff --git a/azalea-client/src/task_pool.rs b/azalea-client/src/task_pool.rs index 59f70487..8df554f0 100644 --- a/azalea-client/src/task_pool.rs +++ b/azalea-client/src/task_pool.rs @@ -1,11 +1,16 @@ //! Borrowed from `bevy_core`. -use azalea_ecs::{ - app::{App, Plugin}, - schedule::IntoSystemDescriptor, - system::Resource, +use std::marker::PhantomData; + +use bevy_app::{App, CoreSet, Plugin}; +use bevy_ecs::{ + schedule::IntoSystemConfig, + system::{NonSend, Resource}, +}; +use bevy_tasks::{ + tick_global_task_pools_on_main_thread, AsyncComputeTaskPool, ComputeTaskPool, IoTaskPool, + TaskPoolBuilder, }; -use bevy_tasks::{AsyncComputeTaskPool, ComputeTaskPool, IoTaskPool, TaskPoolBuilder}; /// Setup of default task pools: `AsyncComputeTaskPool`, `ComputeTaskPool`, /// `IoTaskPool`. @@ -22,13 +27,16 @@ impl Plugin for TaskPoolPlugin { self.task_pool_options.create_default_pools(); #[cfg(not(target_arch = "wasm32"))] - app.add_system_to_stage( - azalea_ecs::app::CoreStage::Last, - bevy_tasks::tick_global_task_pools_on_main_thread.at_end(), - ); + app.add_system(tick_global_task_pools.in_base_set(CoreSet::Last)); } } +pub struct NonSendMarker(PhantomData<*mut ()>); +#[cfg(not(target_arch = "wasm32"))] +fn tick_global_task_pools(_main_thread_marker: Option<NonSend<NonSendMarker>>) { + tick_global_task_pools_on_main_thread(); +} + /// Helper for configuring and creating the default task pools. For end-users /// who want full control, set up [`TaskPoolPlugin`](TaskPoolPlugin) #[derive(Clone, Resource)] |
