1use std::fmt::{self, Display, Formatter};
2use std::hash::{Hash, Hasher};
3use std::io::{self, Cursor};
4use std::{
5 collections::{HashMap, HashSet},
6 fmt::Debug,
7};
8
9use azalea_block::fluid_state::FluidState;
10use azalea_block::BlockState;
11use azalea_buf::{AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError};
12use azalea_core::position::{BlockPos, ChunkPos};
13use azalea_core::registry_holder::RegistryHolder;
14use bevy_ecs::{component::Component, entity::Entity};
15use derive_more::{Deref, DerefMut};
16use nohash_hasher::IntMap;
17#[cfg(feature = "serde")]
18use serde::{Deserialize, Serialize};
19
20use crate::{ChunkStorage, PartialChunkStorage};
21
22pub struct PartialInstance {
31 pub chunks: PartialChunkStorage,
32 pub entity_infos: PartialEntityInfos,
35}
36
37impl PartialInstance {
38 pub fn new(chunk_radius: u32, owner_entity: Option<Entity>) -> Self {
39 PartialInstance {
40 chunks: PartialChunkStorage::new(chunk_radius),
41 entity_infos: PartialEntityInfos::new(owner_entity),
42 }
43 }
44}
45
46#[derive(Component, Copy, Clone, Debug, Default, PartialEq, Eq, Deref, DerefMut)]
63#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
64pub struct MinecraftEntityId(pub i32);
65
66impl Hash for MinecraftEntityId {
67 fn hash<H: Hasher>(&self, hasher: &mut H) {
68 hasher.write_i32(self.0);
69 }
70}
71impl nohash_hasher::IsEnabled for MinecraftEntityId {}
72
73impl AzaleaRead for MinecraftEntityId {
76 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
77 i32::azalea_read(buf).map(MinecraftEntityId)
78 }
79}
80impl AzaleaWrite for MinecraftEntityId {
81 fn azalea_write(&self, buf: &mut impl io::Write) -> Result<(), io::Error> {
82 i32::azalea_write(&self.0, buf)
83 }
84}
85impl AzaleaReadVar for MinecraftEntityId {
86 fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
87 i32::azalea_read_var(buf).map(MinecraftEntityId)
88 }
89}
90impl AzaleaWriteVar for MinecraftEntityId {
91 fn azalea_write_var(&self, buf: &mut impl io::Write) -> Result<(), io::Error> {
92 i32::azalea_write_var(&self.0, buf)
93 }
94}
95impl Display for MinecraftEntityId {
96 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
97 write!(f, "eid({})", self.0)
98 }
99}
100
101#[derive(Debug, Default)]
104pub struct PartialEntityInfos {
105 pub owner_entity: Option<Entity>,
111 pub updates_received: IntMap<MinecraftEntityId, u32>,
117}
118
119impl PartialEntityInfos {
120 pub fn new(owner_entity: Option<Entity>) -> Self {
121 Self {
122 owner_entity,
123 updates_received: IntMap::default(),
124 }
125 }
126}
127
128#[derive(Default, Debug)]
131pub struct Instance {
132 pub chunks: ChunkStorage,
133
134 pub entities_by_chunk: HashMap<ChunkPos, HashSet<Entity>>,
136
137 pub entity_by_id: IntMap<MinecraftEntityId, Entity>,
144
145 pub registries: RegistryHolder,
146}
147
148impl Instance {
149 pub fn get_block_state(&self, pos: &BlockPos) -> Option<BlockState> {
150 self.chunks.get_block_state(pos)
151 }
152
153 pub fn get_fluid_state(&self, pos: &BlockPos) -> Option<FluidState> {
154 self.chunks.get_block_state(pos).map(FluidState::from)
155 }
156
157 pub fn set_block_state(&self, pos: &BlockPos, state: BlockState) -> Option<BlockState> {
158 self.chunks.set_block_state(pos, state)
159 }
160}
161
162impl Debug for PartialInstance {
163 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
164 f.debug_struct("PartialInstance")
165 .field("chunks", &self.chunks)
166 .field("entity_infos", &self.entity_infos)
167 .finish()
168 }
169}
170
171impl Default for PartialInstance {
172 fn default() -> Self {
175 let chunk_storage = PartialChunkStorage::default();
176 let entity_storage = PartialEntityInfos::default();
177 Self {
178 chunks: chunk_storage,
179 entity_infos: entity_storage,
180 }
181 }
182}
183
184impl From<ChunkStorage> for Instance {
185 fn from(chunks: ChunkStorage) -> Self {
188 Self {
189 chunks,
190 entities_by_chunk: HashMap::new(),
191 entity_by_id: IntMap::default(),
192 registries: RegistryHolder::default(),
193 }
194 }
195}