diff options
| author | mat <github@matdoes.dev> | 2022-12-11 00:15:37 -0600 |
|---|---|---|
| committer | mat <github@matdoes.dev> | 2022-12-11 00:15:37 -0600 |
| commit | 37b9f10b3bcc74b48df2c6843a5286a7d41e2414 (patch) | |
| tree | 6a995f7ad3f3309e57c276e10dc7e655dae9c5bb /azalea-client/src/client.rs | |
| parent | 2d6737b247b74e964fd734d5ab4828a3193c296f (diff) | |
| download | azalea-drasl-37b9f10b3bcc74b48df2c6843a5286a7d41e2414.tar.xz | |
make entities have a reference to WeakWorlds instead
... and other exciting bug fixes
Diffstat (limited to 'azalea-client/src/client.rs')
| -rw-r--r-- | azalea-client/src/client.rs | 64 |
1 files changed, 22 insertions, 42 deletions
diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs index 3aad96c4..44c0f8cc 100644 --- a/azalea-client/src/client.rs +++ b/azalea-client/src/client.rs @@ -30,10 +30,10 @@ use azalea_protocol::{ }; use azalea_world::{ entity::{metadata, Entity, EntityData, EntityMetadata}, - WeakWorld, WeakWorldContainer, World, + PartialWorld, WeakWorld, WeakWorldContainer, }; use log::{debug, error, info, trace, warn}; -use parking_lot::{Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard}; +use parking_lot::{Mutex, RwLock}; use std::{ any, backtrace::Backtrace, @@ -92,7 +92,7 @@ pub struct Client { pub write_conn: Arc<tokio::sync::Mutex<WriteConnection<ServerboundGamePacket>>>, pub entity_id: Arc<RwLock<u32>>, /// The world that this client has access to. This supports shared worlds. - pub world: Arc<RwLock<World>>, + pub world: Arc<RwLock<PartialWorld>>, /// A container of world names to worlds. If we're not using a shared world /// (i.e. not a swarm), then this will only contain data about the world /// we're currently in. @@ -180,7 +180,7 @@ impl Client { write_conn, // default our id to 0, it'll be set later entity_id: Arc::new(RwLock::new(0)), - world: Arc::new(RwLock::new(World::default())), + world: Arc::new(RwLock::new(PartialWorld::default())), world_container: world_container .unwrap_or_else(|| Arc::new(RwLock::new(WeakWorldContainer::new()))), world_name: Arc::new(RwLock::new(None)), @@ -509,16 +509,18 @@ impl Client { .as_int() .expect("min_y tag is not an int"); + let world_name = p.dimension.clone(); + + *client.world_name.write() = Some(world_name.clone()); // add this world to the world_container (or don't if it's already there) - let weak_world = - client - .world_container - .write() - .insert(p.dimension.clone(), height, min_y); + let weak_world = client + .world_container + .write() + .insert(world_name, height, min_y); // set the loaded_world to an empty world // (when we add chunks or entities those will be in the world_container) let mut world_lock = client.world.write(); - *world_lock = World::new( + *world_lock = PartialWorld::new( client.client_information.read().view_distance.into(), weak_world, p.player_id, @@ -1011,7 +1013,7 @@ impl Client { // return if there's no chunk at the player's position { - let world_lock = client.world.read(); + let world_lock = client.world(); let player_entity_id = *client.entity_id.read(); let player_entity = world_lock.entity(player_entity_id); let Some(player_entity) = player_entity else { @@ -1037,46 +1039,24 @@ impl Client { // TODO: minecraft does ambient sounds here } - /// Get a [`WeakWorld`] from our world container. If it's a normal 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. + /// Get a reference to our (potentially shared) world. /// - /// # Panics - /// Panics if the client has not received the login packet yet. You can - /// check this with [`Client::logged_in`]. + /// This gets the [`WeakWorld`] from our world container. If it's a normal + /// 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<WeakWorld> { - let world_name = self.world_name.read(); - let world_name = world_name - .as_ref() - .expect("Client has not received login packet yet"); - if let Some(world) = self.world_container.read().get(world_name) { - world - } else { - unreachable!("The world name must be in the world container"); - } + self.world.read().shared.clone() } /// Returns the entity associated to the player. - pub fn entity_mut(&self) -> Entity<RwLockWriteGuard<World>> { - let entity_id = *self.entity_id.read(); - - let world = self.world.write(); - - let entity_data = world - .entity_storage - .get_by_id(entity_id) - .expect("Player entity should exist"); - let entity_ptr = unsafe { entity_data.as_ptr() }; - Entity::new(world, entity_id, entity_ptr) - } - /// Returns the entity associated to the player. - pub fn entity(&self) -> Entity<RwLockReadGuard<World>> { + pub fn entity(&self) -> Entity<Arc<WeakWorld>> { let entity_id = *self.entity_id.read(); - let world = self.world.read(); + let world = self.world(); let entity_data = world .entity_storage + .read() .get_by_id(entity_id) .expect("Player entity should be in the given world"); let entity_ptr = unsafe { entity_data.as_ptr() }; |
