1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 14:26:04 +00:00

replace EntityMut and EntityRef with just Entity

This commit is contained in:
Ubuntu 2022-10-28 20:00:04 +00:00
parent f7c8d57b68
commit 6bc47c01d8
9 changed files with 69 additions and 149 deletions

View file

@ -27,11 +27,11 @@ use azalea_protocol::{
resolver, ServerAddress,
};
use azalea_world::{
entity::{EntityData, EntityMut, EntityRef},
entity::{Entity, EntityData},
Dimension,
};
use log::{debug, error, warn};
use parking_lot::{Mutex, MutexGuard, RwLock};
use parking_lot::{Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};
use std::{
fmt::Debug,
io::{self, Cursor},
@ -84,7 +84,7 @@ pub struct Client {
pub read_conn: Arc<tokio::sync::Mutex<ReadConnection<ClientboundGamePacket>>>,
pub write_conn: Arc<tokio::sync::Mutex<WriteConnection<ServerboundGamePacket>>>,
pub player: Arc<Mutex<Player>>,
pub dimension: Arc<Mutex<Dimension>>,
pub dimension: Arc<RwLock<Dimension>>,
pub physics_state: Arc<Mutex<PhysicsState>>,
pub client_information: Arc<RwLock<ClientInformation>>,
tasks: Arc<Mutex<Vec<JoinHandle<()>>>>,
@ -248,7 +248,7 @@ impl Client {
read_conn,
write_conn,
player: Arc::new(Mutex::new(Player::default())),
dimension: Arc::new(Mutex::new(Dimension::default())),
dimension: Arc::new(RwLock::new(Dimension::default())),
physics_state: Arc::new(Mutex::new(PhysicsState::default())),
tasks: Arc::new(Mutex::new(Vec::new())),
client_information: Arc::new(RwLock::new(ClientInformation::default())),
@ -390,7 +390,7 @@ impl Client {
.as_int()
.expect("min_y tag is not an int");
let mut dimension_lock = client.dimension.lock();
let mut dimension_lock = client.dimension.write();
// the 16 here is our render distance
// i'll make this an actual setting later
*dimension_lock = Dimension::new(16, height, min_y);
@ -465,7 +465,7 @@ impl Client {
player_lock.entity_id
};
let mut dimension_lock = client.dimension.lock();
let mut dimension_lock = client.dimension.write();
let mut player_entity = dimension_lock
.entity_mut(player_entity_id)
@ -553,7 +553,7 @@ impl Client {
debug!("Got chunk cache center packet {:?}", p);
client
.dimension
.lock()
.write()
.update_view_center(&ChunkPos::new(p.x, p.z));
}
ClientboundGamePacket::LevelChunkWithLight(p) => {
@ -563,7 +563,7 @@ impl Client {
// debug("chunk {:?}")
client
.dimension
.lock()
.write()
.replace_with_packet_data(&pos, &mut Cursor::new(&p.chunk_data.data))
.unwrap();
}
@ -573,7 +573,7 @@ impl Client {
ClientboundGamePacket::AddEntity(p) => {
debug!("Got add entity packet {:?}", p);
let entity = EntityData::from(p);
client.dimension.lock().add_entity(p.id, entity);
client.dimension.write().add_entity(p.id, entity);
}
ClientboundGamePacket::SetEntityData(_p) => {
// debug!("Got set entity data packet {:?}", p);
@ -590,7 +590,7 @@ impl Client {
ClientboundGamePacket::AddPlayer(p) => {
debug!("Got add player packet {:?}", p);
let entity = EntityData::from(p);
client.dimension.lock().add_entity(p.id, entity);
client.dimension.write().add_entity(p.id, entity);
}
ClientboundGamePacket::InitializeBorder(p) => {
debug!("Got initialize border packet {:?}", p);
@ -611,7 +611,7 @@ impl Client {
debug!("Got set experience packet {:?}", p);
}
ClientboundGamePacket::TeleportEntity(p) => {
let mut dimension_lock = client.dimension.lock();
let mut dimension_lock = client.dimension.write();
dimension_lock
.set_entity_pos(
@ -631,14 +631,14 @@ impl Client {
// debug!("Got rotate head packet {:?}", p);
}
ClientboundGamePacket::MoveEntityPos(p) => {
let mut dimension_lock = client.dimension.lock();
let mut dimension_lock = client.dimension.write();
dimension_lock
.move_entity_with_delta(p.entity_id, &p.delta)
.map_err(|e| HandleError::Other(e.into()))?;
}
ClientboundGamePacket::MoveEntityPosRot(p) => {
let mut dimension_lock = client.dimension.lock();
let mut dimension_lock = client.dimension.write();
dimension_lock
.move_entity_with_delta(p.entity_id, &p.delta)
@ -673,7 +673,7 @@ impl Client {
}
ClientboundGamePacket::BlockUpdate(p) => {
debug!("Got block update packet {:?}", p);
let mut dimension = client.dimension.lock();
let mut dimension = client.dimension.write();
dimension.set_block_state(&p.pos, p.block_state);
}
ClientboundGamePacket::Animate(p) => {
@ -681,7 +681,7 @@ impl Client {
}
ClientboundGamePacket::SectionBlocksUpdate(p) => {
debug!("Got section blocks update packet {:?}", p);
let mut dimension = client.dimension.lock();
let mut dimension = client.dimension.write();
for state in &p.states {
dimension.set_block_state(&(p.section_pos + state.pos.clone()), state.state);
}
@ -778,7 +778,7 @@ impl Client {
async fn game_tick(client: &mut Client, tx: &UnboundedSender<Event>) {
// return if there's no chunk at the player's position
{
let dimension_lock = client.dimension.lock();
let dimension_lock = client.dimension.write();
let player_lock = client.player.lock();
let player_entity = player_lock.entity(&dimension_lock);
let player_entity = if let Some(player_entity) = player_entity {
@ -805,41 +805,41 @@ impl Client {
}
/// Returns the entity associated to the player.
pub fn entity_mut(&self) -> EntityMut<MutexGuard<Dimension>> {
pub fn entity_mut(&self) -> Entity<RwLockWriteGuard<Dimension>> {
let entity_id = {
let player_lock = self.player.lock();
player_lock.entity_id
};
let mut dimension = self.dimension.lock();
let mut dimension = self.dimension.write();
let entity_data = dimension
.entity_storage
.get_mut_by_id(entity_id)
.expect("Player entity should exist");
let entity_ptr = unsafe { entity_data.as_ptr() };
EntityMut::new(dimension, entity_id, entity_ptr)
Entity::new(dimension, entity_id, entity_ptr)
}
/// Returns the entity associated to the player.
pub fn entity(&self) -> EntityRef<MutexGuard<Dimension>> {
pub fn entity(&self) -> Entity<RwLockReadGuard<Dimension>> {
let entity_id = {
let player_lock = self.player.lock();
player_lock.entity_id
};
let dimension = self.dimension.lock();
let dimension = self.dimension.read();
let entity_data = dimension
.entity_storage
.get_by_id(entity_id)
.expect("Player entity should be in the given dimension");
let entity_ptr = unsafe { entity_data.as_const_ptr() };
EntityRef::new(dimension, entity_id, entity_ptr)
Entity::new(dimension, entity_id, entity_ptr)
}
/// Returns whether we have a received the login packet yet.
pub fn logged_in(&self) -> bool {
let dimension = self.dimension.lock();
let dimension = self.dimension.read();
let player = self.player.lock();
player.entity(&dimension).is_some()
}

View file

@ -33,7 +33,7 @@ impl Client {
let packet = {
let player_lock = self.player.lock();
let mut physics_state = self.physics_state.lock();
let mut dimension_lock = self.dimension.lock();
let mut dimension_lock = self.dimension.write();
let mut player_entity = player_lock
.entity_mut(&mut dimension_lock)
@ -130,7 +130,7 @@ impl Client {
// Set our current position to the provided Vec3, potentially clipping through blocks.
pub async fn set_pos(&mut self, new_pos: Vec3) -> Result<(), MovePlayerError> {
let player_lock = self.player.lock();
let mut dimension_lock = self.dimension.lock();
let mut dimension_lock = self.dimension.write();
dimension_lock.set_entity_pos(player_lock.entity_id, new_pos)?;
@ -138,7 +138,7 @@ impl Client {
}
pub async fn move_entity(&mut self, movement: &Vec3) -> Result<(), MovePlayerError> {
let mut dimension_lock = self.dimension.lock();
let mut dimension_lock = self.dimension.write();
let player = self.player.lock();
let mut entity = player
@ -160,8 +160,8 @@ impl Client {
pub fn ai_step(&mut self) {
self.tick_controls(None);
let mut dimension_lock = self.dimension.write();
let player_lock = self.player.lock();
let mut dimension_lock = self.dimension.lock();
let mut player_entity = player_lock
.entity_mut(&mut dimension_lock)
.expect("Player must exist");

View file

@ -1,4 +1,4 @@
use azalea_world::entity::{EntityMut, EntityRef};
use azalea_world::entity::Entity;
use azalea_world::Dimension;
use uuid::Uuid;
@ -18,12 +18,12 @@ pub struct Player {
impl Player {
/// Get a reference to the entity of the player in the world.
pub fn entity<'d>(&'d self, dimension: &'d Dimension) -> Option<EntityRef> {
pub fn entity<'d>(&'d self, dimension: &'d Dimension) -> Option<Entity<&Dimension>> {
dimension.entity(self.entity_id)
}
/// Get a mutable reference to the entity of the player in the world.
pub fn entity_mut<'d>(&'d self, dimension: &'d mut Dimension) -> Option<EntityMut> {
pub fn entity_mut<'d>(&'d self, dimension: &'d mut Dimension) -> Option<Entity> {
dimension.entity_mut(self.entity_id)
}

View file

@ -47,7 +47,7 @@ impl Trait for azalea_client::Client {
&moves::EastMove,
&moves::WestMove,
];
let dimension = self.dimension.lock();
let dimension = self.dimension.read();
for possible_move in possible_moves.iter() {
if possible_move.can_execute(&dimension, &node.pos) {
edges.push(Edge {

View file

@ -5,7 +5,7 @@ mod mergers;
mod shape;
use azalea_core::{Axis, Vec3, AABB, EPSILON};
use azalea_world::entity::{EntityData, EntityMut};
use azalea_world::entity::{Entity, EntityData};
use azalea_world::{Dimension, MoveEntityError};
pub use blocks::BlockWithShape;
use dimension_collisions::CollisionGetter;
@ -81,7 +81,7 @@ impl HasCollision for Dimension {
}
}
impl MovableEntity for EntityMut<'_> {
impl MovableEntity for Entity<'_> {
/// Move an entity by a given delta, checking for collisions.
fn move_colliding(
&mut self,

View file

@ -4,7 +4,7 @@ pub mod collision;
use azalea_block::{Block, BlockState};
use azalea_core::{BlockPos, Vec3};
use azalea_world::entity::{EntityData, EntityMut};
use azalea_world::entity::{Entity, EntityData};
use collision::{MovableEntity, MoverType};
pub trait HasPhysics {
@ -14,7 +14,7 @@ pub trait HasPhysics {
fn jump_from_ground(&mut self);
}
impl HasPhysics for EntityMut<'_> {
impl HasPhysics for Entity<'_> {
/// Move the entity with the given acceleration while handling friction,
/// gravity, collisions, and some other stuff.
fn travel(&mut self, acceleration: &Vec3) {
@ -139,7 +139,7 @@ fn get_block_pos_below_that_affects_movement(entity: &EntityData) -> BlockPos {
}
fn handle_relative_friction_and_calculate_movement(
entity: &mut EntityMut,
entity: &mut Entity,
acceleration: &Vec3,
block_friction: f32,
) -> Vec3 {
@ -173,7 +173,7 @@ fn get_speed(entity: &EntityData, friction: f32) -> f32 {
/// Returns the what the entity's jump should be multiplied by based on the
/// block they're standing on.
fn block_jump_factor(entity: &EntityMut) -> f32 {
fn block_jump_factor(entity: &Entity) -> f32 {
let block_at_pos = entity.dimension.get_block_state(&entity.pos().into());
let block_below = entity
.dimension
@ -201,11 +201,11 @@ fn block_jump_factor(entity: &EntityMut) -> f32 {
// public double getJumpBoostPower() {
// return this.hasEffect(MobEffects.JUMP) ? (double)(0.1F * (float)(this.getEffect(MobEffects.JUMP).getAmplifier() + 1)) : 0.0D;
// }
fn jump_power(entity: &EntityMut) -> f32 {
fn jump_power(entity: &Entity) -> f32 {
0.42 * block_jump_factor(entity)
}
fn jump_boost_power(_entity: &EntityMut) -> f64 {
fn jump_boost_power(_entity: &Entity) -> f64 {
// TODO: potion effects
// if let Some(effects) = entity.effects() {
// if let Some(jump_effect) = effects.get(&Effect::Jump) {

View file

@ -11,11 +11,9 @@ use std::ops::{Deref, DerefMut};
use std::ptr::NonNull;
use uuid::Uuid;
/// A reference to an entity in a dimension.
#[derive(Debug)]
pub struct EntityRef<'d, D = &'d Dimension>
where
D: Deref<Target = Dimension>,
{
pub struct Entity<'d, D = &'d mut Dimension> {
/// The dimension this entity is in.
pub dimension: D,
/// The incrementing numerical id of the entity.
@ -24,7 +22,7 @@ where
_marker: PhantomData<&'d ()>,
}
impl<'d, D: Deref<Target = Dimension>> EntityRef<'d, D> {
impl<'d, D: Deref<Target = Dimension>> Entity<'d, D> {
pub fn new(dimension: D, id: u32, data: NonNull<EntityData>) -> Self {
// TODO: have this be based on the entity type
Self {
@ -36,82 +34,7 @@ impl<'d, D: Deref<Target = Dimension>> EntityRef<'d, D> {
}
}
impl<'d, D: Deref<Target = Dimension>> EntityRef<'d, D> {
#[inline]
pub fn pos(&self) -> &Vec3 {
&self.pos
}
pub fn make_bounding_box(&self) -> AABB {
self.dimensions.make_bounding_box(self.pos())
}
/// Get the position of the block below the entity, but a little lower.
pub fn on_pos_legacy(&self) -> BlockPos {
self.on_pos(0.2)
}
// int x = Mth.floor(this.position.x);
// int y = Mth.floor(this.position.y - (double)var1);
// int z = Mth.floor(this.position.z);
// BlockPos var5 = new BlockPos(x, y, z);
// if (this.level.getBlockState(var5).isAir()) {
// BlockPos var6 = var5.below();
// BlockState var7 = this.level.getBlockState(var6);
// if (var7.is(BlockTags.FENCES) || var7.is(BlockTags.WALLS) || var7.getBlock() instanceof FenceGateBlock) {
// return var6;
// }
// }
// return var5;
pub fn on_pos(&self, offset: f32) -> BlockPos {
let x = self.pos().x.floor() as i32;
let y = (self.pos().y - offset as f64).floor() as i32;
let z = self.pos().z.floor() as i32;
let pos = BlockPos { x, y, z };
// TODO: check if block below is a fence, wall, or fence gate
let block_pos = pos.down(1);
let block_state = self.dimension.get_block_state(&block_pos);
if block_state == Some(BlockState::Air) {
let block_pos_below = block_pos.down(1);
let block_state_below = self.dimension.get_block_state(&block_pos_below);
if let Some(_block_state_below) = block_state_below {
// if block_state_below.is_fence()
// || block_state_below.is_wall()
// || block_state_below.is_fence_gate()
// {
// return block_pos_below;
// }
}
}
pos
}
}
#[derive(Debug)]
pub struct EntityMut<'d, D = &'d mut Dimension>
where
D: DerefMut<Target = Dimension>,
{
/// The dimension this entity is in.
pub dimension: D,
/// The incrementing numerical id of the entity.
pub id: u32,
pub data: NonNull<EntityData>,
_marker: PhantomData<&'d ()>,
}
impl<'d, D: DerefMut<Target = Dimension>> EntityMut<'d, D> {
pub fn new(dimension: D, id: u32, data: NonNull<EntityData>) -> Self {
Self {
dimension,
id,
data,
_marker: PhantomData,
}
}
impl<'d, D: DerefMut<Target = Dimension>> Entity<'d, D> {
/// Sets the position of the entity. This doesn't update the cache in
/// azalea-world, and should only be used within azalea-world!
///
@ -155,7 +78,7 @@ impl<'d, D: DerefMut<Target = Dimension>> EntityMut<'d, D> {
}
}
impl<'d, D: DerefMut<Target = Dimension>> EntityMut<'d, D> {
impl<'d, D: Deref<Target = Dimension>> Entity<'d, D> {
#[inline]
pub fn pos(&self) -> &Vec3 {
&self.pos
@ -208,32 +131,29 @@ impl<'d, D: DerefMut<Target = Dimension>> EntityMut<'d, D> {
}
}
impl<'d, D: DerefMut<Target = Dimension>> From<EntityMut<'d, D>> for EntityRef<'d, D> {
fn from(entity: EntityMut<'d, D>) -> EntityRef<'d, D> {
EntityRef {
dimension: entity.dimension,
id: entity.id,
data: entity.data,
_marker: PhantomData,
}
}
}
// impl<
// 'd,
// D: DerefMut<Target = Dimension> + Deref<Target = Dimension>,
// D2: Deref<Target = Dimension>,
// > From<Entity<'d, D>> for Entity<'d, D2>
// {
// fn from(entity: Entity<'d, D>) -> Entity<'d, D> {
// Entity {
// dimension: entity.dimension,
// id: entity.id,
// data: entity.data,
// _marker: PhantomData,
// }
// }
// }
impl<D: DerefMut<Target = Dimension>> Deref for EntityMut<'_, D> {
type Target = EntityData;
fn deref(&self) -> &Self::Target {
unsafe { self.data.as_ref() }
}
}
impl<D: DerefMut<Target = Dimension>> DerefMut for EntityMut<'_, D> {
impl<D: DerefMut<Target = Dimension>> DerefMut for Entity<'_, D> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { self.data.as_mut() }
}
}
impl<D: Deref<Target = Dimension>> Deref for EntityRef<'_, D> {
impl<D: Deref<Target = Dimension>> Deref for Entity<'_, D> {
type Target = EntityData;
fn deref(&self) -> &Self::Target {
@ -335,8 +255,8 @@ mod tests {
let mut dim = Dimension::default();
let uuid = Uuid::from_u128(100);
dim.add_entity(0, EntityData::new(uuid, Vec3::default()));
let entity: EntityMut = dim.entity_mut(0).unwrap();
let entity_ref = EntityRef::from(entity);
let entity: Entity = dim.entity_mut(0).unwrap();
let entity_ref = Entity::from(entity);
assert_eq!(entity_ref.uuid, uuid);
}
}

View file

@ -11,7 +11,7 @@ use azalea_buf::BufReadError;
use azalea_core::{BlockPos, ChunkPos, PositionDelta8, Vec3};
pub use bit_storage::BitStorage;
pub use chunk_storage::{Chunk, ChunkStorage};
use entity::{EntityData, EntityMut, EntityRef};
use entity::{Entity, EntityData};
pub use entity_storage::EntityStorage;
use std::{
io::Cursor,
@ -126,16 +126,16 @@ impl Dimension {
self.entity_storage.get_mut_by_id(id)
}
pub fn entity(&self, id: u32) -> Option<EntityRef> {
pub fn entity(&self, id: u32) -> Option<Entity<&Dimension>> {
let entity_data = self.entity_storage.get_by_id(id)?;
let entity_ptr = unsafe { entity_data.as_const_ptr() };
Some(EntityRef::new(self, id, entity_ptr))
Some(Entity::new(self, id, entity_ptr))
}
pub fn entity_mut(&mut self, id: u32) -> Option<EntityMut> {
pub fn entity_mut(&mut self, id: u32) -> Option<Entity<'_, &mut Dimension>> {
let entity_data = self.entity_storage.get_mut_by_id(id)?;
let entity_ptr = unsafe { entity_data.as_ptr() };
Some(EntityMut::new(self, id, entity_ptr))
Some(Entity::new(self, id, entity_ptr))
}
pub fn entity_by_uuid(&self, uuid: &Uuid) -> Option<&EntityData> {

View file

@ -23,7 +23,7 @@ impl BotTrait for azalea_client::Client {
/// Queue a jump for the next tick.
fn jump(&self) {
let player_lock = self.player.lock();
let mut dimension_lock = self.dimension.lock();
let mut dimension_lock = self.dimension.write();
let mut player_entity = player_lock
.entity_mut(&mut dimension_lock)