mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Move sync code into common submodule
This commit is contained in:
parent
609e0f23bf
commit
71cce03f29
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -3194,16 +3194,6 @@ dependencies = [
|
||||
"specs 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sphynx"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"specs 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sum_type 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
@ -3598,7 +3588,7 @@ dependencies = [
|
||||
"serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"specs 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"specs-idvs 0.1.0 (git+https://gitlab.com/veloren/specs-idvs.git)",
|
||||
"sphynx 0.1.0",
|
||||
"sum_type 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vek 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -14,8 +14,8 @@ use common::{
|
||||
ServerError, ServerInfo, ServerMsg, MAX_BYTES_CHAT_MSG,
|
||||
},
|
||||
net::PostBox,
|
||||
sphynx::WorldSyncExt,
|
||||
state::{State, Uid},
|
||||
state::State,
|
||||
sync::{Uid, WorldSyncExt},
|
||||
terrain::{block::Block, TerrainChunk, TerrainChunkSize},
|
||||
vol::RectVolSize,
|
||||
ChatType,
|
||||
|
@ -5,8 +5,6 @@ authors = ["Joshua Barretto <joshua.s.barretto@gmail.com>", "Maciej Ćwięka <mc
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
#sphynx = { git = "https://gitlab.com/veloren/sphynx.git", features = ["serde1"], rev = "ac4adf54d181339a789907acd27f61fe81daa455" }
|
||||
sphynx = { path = "../../sphynx", features = ["serde1"] }
|
||||
specs-idvs = { git = "https://gitlab.com/veloren/specs-idvs.git" }
|
||||
|
||||
specs = { version = "0.14.2", features = ["serde", "nightly"] }
|
||||
@ -31,6 +29,7 @@ parking_lot = "0.9.0"
|
||||
crossbeam = "=0.7.2"
|
||||
notify = "5.0.0-pre.1"
|
||||
indexmap = "1.3.0"
|
||||
sum_type = "0.2.0"
|
||||
# TODO: remove when upgrading to specs 0.15
|
||||
hibitset = "0.5.3"
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::sync::Uid;
|
||||
use specs::{Component, FlaggedStorage};
|
||||
use specs_idvs::IDVStorage;
|
||||
use sphynx::Uid;
|
||||
use std::time::Duration;
|
||||
use vek::*;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::state::Uid;
|
||||
use crate::sync::Uid;
|
||||
use specs::{Component, FlaggedStorage, NullStorage};
|
||||
use specs_idvs::IDVStorage;
|
||||
use vek::*;
|
||||
|
@ -1,5 +1,4 @@
|
||||
use crate::comp;
|
||||
use crate::state::Uid;
|
||||
use crate::{comp, sync::Uid};
|
||||
use specs::{Component, FlaggedStorage};
|
||||
use specs_idvs::IDVStorage;
|
||||
use std::time::Duration;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{comp, state::Uid};
|
||||
use crate::{comp, sync::Uid};
|
||||
use specs::{Component, FlaggedStorage};
|
||||
use specs_idvs::IDVStorage;
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
use crate::comp;
|
||||
use crate::{comp, sync::Uid};
|
||||
use comp::item::Tool;
|
||||
use parking_lot::Mutex;
|
||||
use serde::Deserialize;
|
||||
use specs::Entity as EcsEntity;
|
||||
use sphynx::Uid;
|
||||
use std::{collections::VecDeque, ops::DerefMut};
|
||||
use vek::*;
|
||||
|
||||
|
@ -7,9 +7,6 @@ extern crate serde_derive;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
// Re-export sphynx
|
||||
pub use sphynx;
|
||||
|
||||
pub mod assets;
|
||||
pub mod astar;
|
||||
pub mod clock;
|
||||
@ -23,6 +20,7 @@ pub mod pathfinding;
|
||||
pub mod ray;
|
||||
pub mod region;
|
||||
pub mod state;
|
||||
pub mod sync;
|
||||
pub mod sys;
|
||||
pub mod terrain;
|
||||
pub mod util;
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{comp, state};
|
||||
use crate::{comp, state, sync};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use sphynx::sum_type;
|
||||
use std::marker::PhantomData;
|
||||
use sum_type::sum_type;
|
||||
|
||||
// Automatically derive From<T> for EcsResPacket
|
||||
// for each variant EcsResPacket::T(T).
|
||||
@ -12,11 +12,11 @@ sum_type! {
|
||||
TimeOfDay(state::TimeOfDay),
|
||||
}
|
||||
}
|
||||
impl sphynx::ResPacket for EcsResPacket {
|
||||
impl sync::ResPacket for EcsResPacket {
|
||||
fn apply(self, world: &specs::World) {
|
||||
match self {
|
||||
EcsResPacket::Time(time) => sphynx::handle_res_update(time, world),
|
||||
EcsResPacket::TimeOfDay(time_of_day) => sphynx::handle_res_update(time_of_day, world),
|
||||
EcsResPacket::Time(time) => sync::handle_res_update(time, world),
|
||||
EcsResPacket::TimeOfDay(time_of_day) => sync::handle_res_update(time_of_day, world),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -66,72 +66,68 @@ sum_type! {
|
||||
Sticky(PhantomData<comp::Sticky>),
|
||||
}
|
||||
}
|
||||
impl sphynx::CompPacket for EcsCompPacket {
|
||||
impl sync::CompPacket for EcsCompPacket {
|
||||
type Phantom = EcsCompPhantom;
|
||||
fn apply_insert(self, entity: specs::Entity, world: &specs::World) {
|
||||
match self {
|
||||
EcsCompPacket::Pos(comp) => sphynx::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Vel(comp) => sphynx::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Ori(comp) => sphynx::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Body(comp) => sphynx::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Player(comp) => sphynx::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::CanBuild(comp) => sphynx::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Stats(comp) => sphynx::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::LightEmitter(comp) => sphynx::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Item(comp) => sphynx::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Scale(comp) => sphynx::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::MountState(comp) => sphynx::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Mounting(comp) => sphynx::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Mass(comp) => sphynx::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Projectile(comp) => sphynx::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Gravity(comp) => sphynx::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Sticky(comp) => sphynx::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Pos(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Vel(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Ori(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Body(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Player(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::CanBuild(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Stats(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::LightEmitter(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Item(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Scale(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::MountState(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Mounting(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Mass(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Projectile(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Gravity(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Sticky(comp) => sync::handle_insert(comp, entity, world),
|
||||
}
|
||||
}
|
||||
fn apply_modify(self, entity: specs::Entity, world: &specs::World) {
|
||||
match self {
|
||||
EcsCompPacket::Pos(comp) => sphynx::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Vel(comp) => sphynx::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Ori(comp) => sphynx::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Body(comp) => sphynx::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Player(comp) => sphynx::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::CanBuild(comp) => sphynx::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Stats(comp) => sphynx::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::LightEmitter(comp) => sphynx::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Item(comp) => sphynx::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Scale(comp) => sphynx::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::MountState(comp) => sphynx::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Mounting(comp) => sphynx::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Mass(comp) => sphynx::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Projectile(comp) => sphynx::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Gravity(comp) => sphynx::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Sticky(comp) => sphynx::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Pos(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Vel(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Ori(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Body(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Player(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::CanBuild(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Stats(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::LightEmitter(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Item(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Scale(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::MountState(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Mounting(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Mass(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Projectile(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Gravity(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Sticky(comp) => sync::handle_modify(comp, entity, world),
|
||||
}
|
||||
}
|
||||
fn apply_remove(phantom: Self::Phantom, entity: specs::Entity, world: &specs::World) {
|
||||
match phantom {
|
||||
EcsCompPhantom::Pos(_) => sphynx::handle_remove::<comp::Pos>(entity, world),
|
||||
EcsCompPhantom::Vel(_) => sphynx::handle_remove::<comp::Vel>(entity, world),
|
||||
EcsCompPhantom::Ori(_) => sphynx::handle_remove::<comp::Ori>(entity, world),
|
||||
EcsCompPhantom::Body(_) => sphynx::handle_remove::<comp::Body>(entity, world),
|
||||
EcsCompPhantom::Player(_) => sphynx::handle_remove::<comp::Player>(entity, world),
|
||||
EcsCompPhantom::CanBuild(_) => sphynx::handle_remove::<comp::CanBuild>(entity, world),
|
||||
EcsCompPhantom::Stats(_) => sphynx::handle_remove::<comp::Stats>(entity, world),
|
||||
EcsCompPhantom::Pos(_) => sync::handle_remove::<comp::Pos>(entity, world),
|
||||
EcsCompPhantom::Vel(_) => sync::handle_remove::<comp::Vel>(entity, world),
|
||||
EcsCompPhantom::Ori(_) => sync::handle_remove::<comp::Ori>(entity, world),
|
||||
EcsCompPhantom::Body(_) => sync::handle_remove::<comp::Body>(entity, world),
|
||||
EcsCompPhantom::Player(_) => sync::handle_remove::<comp::Player>(entity, world),
|
||||
EcsCompPhantom::CanBuild(_) => sync::handle_remove::<comp::CanBuild>(entity, world),
|
||||
EcsCompPhantom::Stats(_) => sync::handle_remove::<comp::Stats>(entity, world),
|
||||
EcsCompPhantom::LightEmitter(_) => {
|
||||
sphynx::handle_remove::<comp::LightEmitter>(entity, world)
|
||||
sync::handle_remove::<comp::LightEmitter>(entity, world)
|
||||
}
|
||||
EcsCompPhantom::Item(_) => sphynx::handle_remove::<comp::Item>(entity, world),
|
||||
EcsCompPhantom::Scale(_) => sphynx::handle_remove::<comp::Scale>(entity, world),
|
||||
EcsCompPhantom::MountState(_) => {
|
||||
sphynx::handle_remove::<comp::MountState>(entity, world)
|
||||
}
|
||||
EcsCompPhantom::Mounting(_) => sphynx::handle_remove::<comp::Mounting>(entity, world),
|
||||
EcsCompPhantom::Mass(_) => sphynx::handle_remove::<comp::Mass>(entity, world),
|
||||
EcsCompPhantom::Projectile(_) => {
|
||||
sphynx::handle_remove::<comp::Projectile>(entity, world)
|
||||
}
|
||||
EcsCompPhantom::Gravity(_) => sphynx::handle_remove::<comp::Gravity>(entity, world),
|
||||
EcsCompPhantom::Sticky(_) => sphynx::handle_remove::<comp::Sticky>(entity, world),
|
||||
EcsCompPhantom::Item(_) => sync::handle_remove::<comp::Item>(entity, world),
|
||||
EcsCompPhantom::Scale(_) => sync::handle_remove::<comp::Scale>(entity, world),
|
||||
EcsCompPhantom::MountState(_) => sync::handle_remove::<comp::MountState>(entity, world),
|
||||
EcsCompPhantom::Mounting(_) => sync::handle_remove::<comp::Mounting>(entity, world),
|
||||
EcsCompPhantom::Mass(_) => sync::handle_remove::<comp::Mass>(entity, world),
|
||||
EcsCompPhantom::Projectile(_) => sync::handle_remove::<comp::Projectile>(entity, world),
|
||||
EcsCompPhantom::Gravity(_) => sync::handle_remove::<comp::Gravity>(entity, world),
|
||||
EcsCompPhantom::Sticky(_) => sync::handle_remove::<comp::Sticky>(entity, world),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use super::{ClientState, EcsCompPacket, EcsResPacket};
|
||||
use crate::{
|
||||
comp,
|
||||
comp, sync,
|
||||
terrain::{Block, TerrainChunk},
|
||||
ChatType,
|
||||
};
|
||||
@ -26,7 +26,7 @@ pub struct ServerInfo {
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum ServerMsg {
|
||||
InitialSync {
|
||||
ecs_state: sphynx::StatePackage<EcsCompPacket, EcsResPacket>,
|
||||
ecs_state: sync::StatePackage<EcsCompPacket, EcsResPacket>,
|
||||
entity_uid: u64,
|
||||
server_info: ServerInfo,
|
||||
// world_map: Vec2<usize>, /*, Vec<u32>)*/
|
||||
@ -40,9 +40,9 @@ pub enum ServerMsg {
|
||||
message: String,
|
||||
},
|
||||
SetPlayerEntity(u64),
|
||||
EcsSync(sphynx::SyncPackage<EcsCompPacket>),
|
||||
EcsResSync(sphynx::ResSyncPackage<EcsResPacket>),
|
||||
CreateEntity(sphynx::EntityPackage<EcsCompPacket>),
|
||||
EcsSync(sync::SyncPackage<EcsCompPacket>),
|
||||
EcsResSync(sync::ResSyncPackage<EcsResPacket>),
|
||||
CreateEntity(sync::EntityPackage<EcsCompPacket>),
|
||||
DeleteEntity(u64),
|
||||
EntityPos {
|
||||
entity: u64,
|
||||
|
@ -1,10 +1,8 @@
|
||||
// Reexports
|
||||
pub use sphynx::Uid;
|
||||
|
||||
use crate::{
|
||||
comp,
|
||||
event::{EventBus, LocalEvent, ServerEvent, SfxEventItem},
|
||||
region::RegionMap,
|
||||
sync::WorldSyncExt,
|
||||
sys,
|
||||
terrain::{Block, TerrainChunk, TerrainGrid},
|
||||
vol::WriteVol,
|
||||
@ -17,7 +15,6 @@ use specs::{
|
||||
storage::{MaskedStorage as EcsMaskedStorage, Storage as EcsStorage},
|
||||
Component, DispatcherBuilder, Entity as EcsEntity,
|
||||
};
|
||||
use sphynx::WorldSyncExt;
|
||||
use std::{sync::Arc, time::Duration};
|
||||
use vek::*;
|
||||
|
||||
@ -103,20 +100,6 @@ impl Default for State {
|
||||
}
|
||||
|
||||
impl State {
|
||||
// Create a new `State` from an ECS state package.
|
||||
/*pub fn from_state_package(
|
||||
state_package: sphynx::StatePackage<EcsCompPacket, EcsResPacket>,
|
||||
) -> Self {
|
||||
Self {
|
||||
ecs: sphynx::World::from_state_package(
|
||||
specs::World::new(),
|
||||
Self::setup_sphynx_world,
|
||||
state_package,
|
||||
),
|
||||
thread_pool: Arc::new(ThreadPoolBuilder::new().build().unwrap()),
|
||||
}
|
||||
}*/
|
||||
|
||||
/// Creates ecs world and registers all the common components and resources
|
||||
// TODO: Split up registering into server and client (e.g. move EventBus<ServerEvent> to the server)
|
||||
fn setup_ecs_world() -> specs::World {
|
||||
|
14
common/src/sync/mod.rs
Normal file
14
common/src/sync/mod.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// Note: Currently only one-way sync is supported until a usecase for two-way sync arises
|
||||
mod packet;
|
||||
mod sync_ext;
|
||||
mod track;
|
||||
mod uid;
|
||||
|
||||
// Reexports
|
||||
pub use packet::{
|
||||
handle_insert, handle_modify, handle_remove, handle_res_update, CompPacket, EntityPackage,
|
||||
ResPacket, ResSyncPackage, StatePackage, SyncPackage,
|
||||
};
|
||||
pub use sync_ext::WorldSyncExt;
|
||||
pub use track::{Tracker, UpdateTracker};
|
||||
pub use uid::{Uid, UidAllocator};
|
167
common/src/sync/packet.rs
Normal file
167
common/src/sync/packet.rs
Normal file
@ -0,0 +1,167 @@
|
||||
use super::{
|
||||
track::{Tracker, UpdateTracker},
|
||||
uid::Uid,
|
||||
};
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
use specs::{shred::Resource, Component, Entity, Join, ReadStorage, World};
|
||||
use std::{
|
||||
convert::{TryFrom, TryInto},
|
||||
fmt::Debug,
|
||||
marker::PhantomData,
|
||||
};
|
||||
|
||||
pub trait CompPacket: Clone + Debug + Send + 'static {
|
||||
type Phantom: Clone + Debug + Serialize + DeserializeOwned;
|
||||
|
||||
fn apply_insert(self, entity: Entity, world: &World);
|
||||
fn apply_modify(self, entity: Entity, world: &World);
|
||||
fn apply_remove(phantom: Self::Phantom, entity: Entity, world: &World);
|
||||
}
|
||||
|
||||
pub trait ResPacket: Clone + Debug + Send + 'static {
|
||||
fn apply(self, world: &World);
|
||||
}
|
||||
|
||||
/// Useful for implementing CompPacket trait
|
||||
pub fn handle_insert<C: Component>(comp: C, entity: Entity, world: &World) {
|
||||
let _ = world.write_storage::<C>().insert(entity, comp);
|
||||
}
|
||||
/// Useful for implementing CompPacket trait
|
||||
pub fn handle_modify<C: Component>(comp: C, entity: Entity, world: &World) {
|
||||
let _ = world
|
||||
.write_storage::<C>()
|
||||
.get_mut(entity)
|
||||
.map(|c| *c = comp);
|
||||
}
|
||||
/// Useful for implementing CompPacket trait
|
||||
pub fn handle_remove<C: Component>(entity: Entity, world: &World) {
|
||||
let _ = world.write_storage::<C>().remove(entity);
|
||||
}
|
||||
/// Useful for implementing ResPacket trait
|
||||
pub fn handle_res_update<R: Resource>(res: R, world: &World) {
|
||||
*world.write_resource::<R>() = res;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum CompUpdateKind<P: CompPacket> {
|
||||
Inserted(P),
|
||||
Modified(P),
|
||||
Removed(P::Phantom),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct EntityPackage<P: CompPacket>(pub u64, pub Vec<P>);
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct StatePackage<P: CompPacket, R: ResPacket> {
|
||||
pub entities: Vec<EntityPackage<P>>,
|
||||
pub resources: Vec<R>,
|
||||
}
|
||||
|
||||
impl<P: CompPacket, R: ResPacket> Default for StatePackage<P, R> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
entities: Vec::new(),
|
||||
resources: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: CompPacket, R: ResPacket> StatePackage<P, R> {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
pub fn with_entities<C: Component + Clone + Send + Sync>(
|
||||
mut self,
|
||||
mut entities: Vec<EntityPackage<P>>,
|
||||
) -> Self {
|
||||
self.entities.append(&mut entities);
|
||||
self
|
||||
}
|
||||
pub fn with_entity(mut self, entry: EntityPackage<P>) -> Self {
|
||||
self.entities.push(entry);
|
||||
self
|
||||
}
|
||||
pub fn with_res<C: Resource + Clone + Send + Sync>(mut self, res: &C) -> Self
|
||||
where
|
||||
R: From<C>,
|
||||
{
|
||||
self.resources.push(R::from(res.clone()));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct SyncPackage<P: CompPacket> {
|
||||
pub comp_updates: Vec<(u64, CompUpdateKind<P>)>,
|
||||
pub created_entities: Vec<u64>,
|
||||
pub deleted_entities: Vec<u64>,
|
||||
}
|
||||
impl<P: CompPacket> SyncPackage<P> {
|
||||
pub fn new<'a>(
|
||||
uids: &ReadStorage<'a, Uid>,
|
||||
uid_tracker: &UpdateTracker<Uid>,
|
||||
filter: impl Join + Copy,
|
||||
) -> Self {
|
||||
// Add created and deleted entities
|
||||
let created_entities = (uids, filter, uid_tracker.inserted())
|
||||
.join()
|
||||
.map(|(uid, _, _)| (*uid).into())
|
||||
.collect();
|
||||
// TODO: handle modified uid?
|
||||
//created_entities.append(&mut (uids, filter, uid_tracker.inserted()).join().map(|(uid, _, _)| uid).collect());
|
||||
let deleted_entities = (uids, filter, uid_tracker.removed())
|
||||
.join()
|
||||
.map(|(uid, _, _)| (*uid).into())
|
||||
.collect();
|
||||
|
||||
Self {
|
||||
comp_updates: Vec::new(),
|
||||
created_entities,
|
||||
deleted_entities,
|
||||
}
|
||||
}
|
||||
pub fn with_component<'a, C: Component + Clone + Send + Sync>(
|
||||
mut self,
|
||||
uids: &ReadStorage<'a, Uid>,
|
||||
uid_tracker: &UpdateTracker<Uid>,
|
||||
tracker: &impl Tracker<C, P>,
|
||||
storage: &ReadStorage<'a, C>,
|
||||
filter: impl Join + Copy,
|
||||
) -> Self
|
||||
where
|
||||
P: From<C>,
|
||||
C: TryFrom<P>,
|
||||
P::Phantom: From<PhantomData<C>>,
|
||||
P::Phantom: TryInto<PhantomData<C>>,
|
||||
C::Storage: specs::storage::Tracked,
|
||||
{
|
||||
tracker.get_updates_for(
|
||||
uids,
|
||||
storage,
|
||||
// Don't include updates for deleted entities
|
||||
(filter, &!uid_tracker.removed()),
|
||||
&mut self.comp_updates,
|
||||
);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct ResSyncPackage<R: ResPacket> {
|
||||
pub resources: Vec<R>,
|
||||
}
|
||||
impl<R: ResPacket> ResSyncPackage<R> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
resources: Vec::new(),
|
||||
}
|
||||
}
|
||||
pub fn with_res<C: Resource + Clone + Send + Sync>(mut self, res: &C) -> Self
|
||||
where
|
||||
R: From<C>,
|
||||
{
|
||||
self.resources.push(R::from(res.clone()));
|
||||
self
|
||||
}
|
||||
}
|
178
common/src/sync/sync_ext.rs
Normal file
178
common/src/sync/sync_ext.rs
Normal file
@ -0,0 +1,178 @@
|
||||
use super::{
|
||||
packet::{
|
||||
CompPacket, CompUpdateKind, EntityPackage, ResPacket, ResSyncPackage, StatePackage,
|
||||
SyncPackage,
|
||||
},
|
||||
track::UpdateTracker,
|
||||
uid::{Uid, UidAllocator},
|
||||
};
|
||||
use specs::{
|
||||
saveload::{MarkedBuilder, MarkerAllocator},
|
||||
world::Builder,
|
||||
};
|
||||
|
||||
pub trait WorldSyncExt {
|
||||
fn register_sync_marker(&mut self);
|
||||
fn register_synced<C: specs::Component + Clone + Send + Sync>(&mut self)
|
||||
where
|
||||
C::Storage: Default + specs::storage::Tracked;
|
||||
fn register_tracker<C: specs::Component + Clone + Send + Sync>(&mut self)
|
||||
where
|
||||
C::Storage: Default + specs::storage::Tracked;
|
||||
fn create_entity_synced(&mut self) -> specs::EntityBuilder;
|
||||
fn uid_from_entity(&self, entity: specs::Entity) -> Option<Uid>;
|
||||
fn entity_from_uid(&self, uid: u64) -> Option<specs::Entity>;
|
||||
fn apply_entity_package<P: CompPacket>(&mut self, entity_package: EntityPackage<P>);
|
||||
fn apply_state_package<P: CompPacket, R: ResPacket>(
|
||||
&mut self,
|
||||
state_package: StatePackage<P, R>,
|
||||
);
|
||||
fn apply_sync_package<P: CompPacket>(&mut self, package: SyncPackage<P>);
|
||||
fn apply_res_sync_package<R: ResPacket>(&mut self, package: ResSyncPackage<R>);
|
||||
}
|
||||
|
||||
impl WorldSyncExt for specs::World {
|
||||
fn register_sync_marker(&mut self) {
|
||||
self.register_synced::<Uid>();
|
||||
|
||||
self.add_resource(UidAllocator::new());
|
||||
}
|
||||
fn register_synced<C: specs::Component + Clone + Send + Sync>(&mut self)
|
||||
where
|
||||
// P: From<C>,
|
||||
// C: TryFrom<P, Error = InvalidType>,
|
||||
// P::Phantom: From<PhantomData<C>>,
|
||||
// P::Phantom: TryInto<PhantomData<C>>,
|
||||
C::Storage: Default + specs::storage::Tracked,
|
||||
{
|
||||
self.register::<C>();
|
||||
self.register_tracker::<C>();
|
||||
}
|
||||
fn register_tracker<C: specs::Component + Clone + Send + Sync>(&mut self)
|
||||
where
|
||||
// P: From<C>,
|
||||
// C: TryFrom<P, Error = InvalidType>,
|
||||
// P::Phantom: From<PhantomData<C>>,
|
||||
// P::Phantom: TryInto<PhantomData<C>>,
|
||||
C::Storage: Default + specs::storage::Tracked,
|
||||
{
|
||||
let tracker = UpdateTracker::<C>::new(self);
|
||||
self.add_resource(tracker);
|
||||
}
|
||||
|
||||
/*fn insert_synced<C: specs::shred::Resource + Clone + Send + Sync>(&mut self, res: C)
|
||||
//where
|
||||
// R: From<C>,
|
||||
// C: TryFrom<R>,
|
||||
{
|
||||
self.add_resource::<C>(res);
|
||||
|
||||
self.res_trackers.insert(ResUpdateTracker::<C>::new());
|
||||
}*/
|
||||
|
||||
fn create_entity_synced(&mut self) -> specs::EntityBuilder {
|
||||
self.create_entity().marked::<super::Uid>()
|
||||
}
|
||||
|
||||
/// Get the UID of an entity
|
||||
fn uid_from_entity(&self, entity: specs::Entity) -> Option<Uid> {
|
||||
self.read_storage::<Uid>().get(entity).copied()
|
||||
}
|
||||
|
||||
/// Get the UID of an entity
|
||||
fn entity_from_uid(&self, uid: u64) -> Option<specs::Entity> {
|
||||
self.read_resource::<UidAllocator>()
|
||||
.retrieve_entity_internal(uid)
|
||||
}
|
||||
|
||||
fn apply_entity_package<P: CompPacket>(&mut self, entity_package: EntityPackage<P>) {
|
||||
let EntityPackage(entity_uid, packets) = entity_package;
|
||||
|
||||
let entity = create_entity_with_uid(self, entity_uid);
|
||||
for packet in packets {
|
||||
packet.apply_insert(entity, self)
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_state_package<P: CompPacket, R: ResPacket>(
|
||||
&mut self,
|
||||
state_package: StatePackage<P, R>,
|
||||
) {
|
||||
let StatePackage {
|
||||
entities,
|
||||
resources,
|
||||
} = state_package;
|
||||
|
||||
// Apply state package resources
|
||||
for res_packet in resources {
|
||||
res_packet.apply(self);
|
||||
}
|
||||
|
||||
// Apply state package entities
|
||||
for entity_package in entities {
|
||||
self.apply_entity_package(entity_package);
|
||||
}
|
||||
|
||||
// Initialize entities
|
||||
//specs_world.maintain();
|
||||
}
|
||||
|
||||
fn apply_sync_package<P: CompPacket>(&mut self, package: SyncPackage<P>) {
|
||||
// Take ownership of the fields
|
||||
let SyncPackage {
|
||||
comp_updates,
|
||||
created_entities,
|
||||
deleted_entities,
|
||||
} = package;
|
||||
|
||||
// Attempt to create entities
|
||||
for entity_uid in created_entities {
|
||||
create_entity_with_uid(self, entity_uid);
|
||||
}
|
||||
|
||||
// Update components
|
||||
for (entity_uid, update) in comp_updates {
|
||||
if let Some(entity) = self
|
||||
.read_resource::<UidAllocator>()
|
||||
.retrieve_entity_internal(entity_uid)
|
||||
{
|
||||
match update {
|
||||
CompUpdateKind::Inserted(packet) => {
|
||||
packet.apply_insert(entity, self);
|
||||
}
|
||||
CompUpdateKind::Modified(packet) => {
|
||||
packet.apply_modify(entity, self);
|
||||
}
|
||||
CompUpdateKind::Removed(phantom) => {
|
||||
P::apply_remove(phantom, entity, self);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to delete entities that were marked for deletion
|
||||
for entity_uid in deleted_entities {
|
||||
let entity = self
|
||||
.read_resource::<UidAllocator>()
|
||||
.retrieve_entity_internal(entity_uid);
|
||||
if let Some(entity) = entity {
|
||||
let _ = self.delete_entity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
fn apply_res_sync_package<R: ResPacket>(&mut self, package: ResSyncPackage<R>) {
|
||||
// Update resources
|
||||
for res_packet in package.resources {
|
||||
res_packet.apply(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Private utilities
|
||||
fn create_entity_with_uid(specs_world: &mut specs::World, entity_uid: u64) -> specs::Entity {
|
||||
let existing_entity = specs_world
|
||||
.read_resource::<UidAllocator>()
|
||||
.retrieve_entity_internal(entity_uid);
|
||||
|
||||
existing_entity.unwrap_or_else(|| specs_world.create_entity_synced().build())
|
||||
}
|
144
common/src/sync/track.rs
Normal file
144
common/src/sync/track.rs
Normal file
@ -0,0 +1,144 @@
|
||||
use super::{
|
||||
packet::{CompPacket, CompUpdateKind},
|
||||
uid::Uid,
|
||||
};
|
||||
use specs::{BitSet, Component, Entity, Join, ReadStorage, World};
|
||||
use std::{
|
||||
convert::{TryFrom, TryInto},
|
||||
marker::PhantomData,
|
||||
};
|
||||
|
||||
pub trait Tracker<C: Component + Clone + Send + Sync, P: CompPacket>: Send + 'static
|
||||
where
|
||||
P: From<C>,
|
||||
C: TryFrom<P>,
|
||||
P::Phantom: From<PhantomData<C>>,
|
||||
P::Phantom: TryInto<PhantomData<C>>,
|
||||
C::Storage: specs::storage::Tracked,
|
||||
{
|
||||
fn add_packet_for<'a>(
|
||||
&self,
|
||||
storage: &specs::ReadStorage<'a, C>,
|
||||
entity: specs::Entity,
|
||||
packets: &mut Vec<P>,
|
||||
);
|
||||
fn get_updates_for<'a>(
|
||||
&self,
|
||||
uids: &specs::ReadStorage<'a, Uid>,
|
||||
storage: &specs::ReadStorage<'a, C>,
|
||||
filter: impl Join + Copy,
|
||||
buf: &mut Vec<(u64, CompUpdateKind<P>)>,
|
||||
);
|
||||
}
|
||||
|
||||
pub struct UpdateTracker<C: Component> {
|
||||
reader_id: specs::ReaderId<specs::storage::ComponentEvent>,
|
||||
inserted: BitSet,
|
||||
modified: BitSet,
|
||||
removed: BitSet,
|
||||
phantom: PhantomData<C>,
|
||||
}
|
||||
impl<C: Component> UpdateTracker<C>
|
||||
where
|
||||
C::Storage: specs::storage::Tracked,
|
||||
{
|
||||
pub fn new(specs_world: &mut World) -> Self {
|
||||
Self {
|
||||
reader_id: specs_world.write_storage::<C>().register_reader(),
|
||||
inserted: BitSet::new(),
|
||||
modified: BitSet::new(),
|
||||
removed: BitSet::new(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
pub fn inserted(&self) -> &BitSet {
|
||||
&self.inserted
|
||||
}
|
||||
pub fn modified(&self) -> &BitSet {
|
||||
&self.modified
|
||||
}
|
||||
pub fn removed(&self) -> &BitSet {
|
||||
&self.removed
|
||||
}
|
||||
pub fn record_changes<'a>(&mut self, storage: &specs::ReadStorage<'a, C>) {
|
||||
self.inserted.clear();
|
||||
self.modified.clear();
|
||||
self.removed.clear();
|
||||
|
||||
for event in storage.channel().read(&mut self.reader_id) {
|
||||
match event {
|
||||
specs::storage::ComponentEvent::Inserted(id) => {
|
||||
// If previously removed/modified we don't need to know that anymore
|
||||
self.removed.remove(*id);
|
||||
self.modified.remove(*id);
|
||||
self.inserted.add(*id);
|
||||
}
|
||||
specs::storage::ComponentEvent::Modified(id) => {
|
||||
// We don't care about modification if the component was just added or was
|
||||
// removed
|
||||
if !self.removed.contains(*id) && !self.inserted.contains(*id) {
|
||||
self.modified.add(*id);
|
||||
}
|
||||
}
|
||||
specs::storage::ComponentEvent::Removed(id) => {
|
||||
// Don't need to know that it was inserted/modified if it was subsequently removed
|
||||
self.inserted.remove(*id);
|
||||
self.modified.remove(*id);
|
||||
self.removed.add(*id);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: Component + Clone + Send + Sync, P: CompPacket> Tracker<C, P> for UpdateTracker<C>
|
||||
where
|
||||
P: From<C>,
|
||||
C: TryFrom<P>,
|
||||
P::Phantom: From<PhantomData<C>>,
|
||||
P::Phantom: TryInto<PhantomData<C>>,
|
||||
C::Storage: specs::storage::Tracked,
|
||||
{
|
||||
fn add_packet_for<'a>(
|
||||
&self,
|
||||
storage: &ReadStorage<'a, C>,
|
||||
entity: Entity,
|
||||
packets: &mut Vec<P>,
|
||||
) {
|
||||
if let Some(comp) = storage.get(entity) {
|
||||
packets.push(P::from(comp.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
fn get_updates_for<'a>(
|
||||
&self,
|
||||
uids: &specs::ReadStorage<'a, Uid>,
|
||||
storage: &specs::ReadStorage<'a, C>,
|
||||
entity_filter: impl Join + Copy,
|
||||
buf: &mut Vec<(u64, CompUpdateKind<P>)>,
|
||||
) {
|
||||
// Generate inserted updates
|
||||
for (uid, comp, _, _) in (uids, storage, &self.inserted, entity_filter).join() {
|
||||
buf.push((
|
||||
(*uid).into(),
|
||||
CompUpdateKind::Inserted(P::from(comp.clone())),
|
||||
));
|
||||
}
|
||||
|
||||
// Generate modified updates
|
||||
for (uid, comp, _, _) in (uids, storage, &self.modified, entity_filter).join() {
|
||||
buf.push((
|
||||
(*uid).into(),
|
||||
CompUpdateKind::Modified(P::from(comp.clone())),
|
||||
));
|
||||
}
|
||||
|
||||
// Generate removed updates
|
||||
for (uid, _, _) in (uids, &self.removed, entity_filter).join() {
|
||||
buf.push((
|
||||
(*uid).into(),
|
||||
CompUpdateKind::Removed(P::Phantom::from(PhantomData::<C>)),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
88
common/src/sync/uid.rs
Normal file
88
common/src/sync/uid.rs
Normal file
@ -0,0 +1,88 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use specs::{
|
||||
saveload::{Marker, MarkerAllocator},
|
||||
world::EntitiesRes,
|
||||
Component, Entity, FlaggedStorage, Join, ReadStorage, VecStorage,
|
||||
};
|
||||
use std::{collections::HashMap, fmt, u64};
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Uid(pub u64);
|
||||
|
||||
impl Into<u64> for Uid {
|
||||
fn into(self) -> u64 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u64> for Uid {
|
||||
fn from(uid: u64) -> Self {
|
||||
Self(uid)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Uid {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for Uid {
|
||||
type Storage = FlaggedStorage<Self, VecStorage<Self>>;
|
||||
}
|
||||
|
||||
impl Marker for Uid {
|
||||
type Identifier = u64;
|
||||
type Allocator = UidAllocator;
|
||||
|
||||
fn id(&self) -> u64 {
|
||||
self.0
|
||||
}
|
||||
|
||||
fn update(&mut self, update: Self) {
|
||||
assert_eq!(self.0, update.0);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UidAllocator {
|
||||
index: u64,
|
||||
mapping: HashMap<u64, Entity>,
|
||||
}
|
||||
|
||||
impl UidAllocator {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
index: 0,
|
||||
mapping: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for UidAllocator {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl MarkerAllocator<Uid> for UidAllocator {
|
||||
fn allocate(&mut self, entity: Entity, id: Option<u64>) -> Uid {
|
||||
let id = id.unwrap_or_else(|| {
|
||||
let id = self.index;
|
||||
self.index += 1;
|
||||
self.mapping.insert(id, entity);
|
||||
id
|
||||
});
|
||||
Uid(id)
|
||||
}
|
||||
|
||||
fn retrieve_entity_internal(&self, id: u64) -> Option<Entity> {
|
||||
self.mapping.get(&id).cloned()
|
||||
}
|
||||
|
||||
fn maintain(&mut self, entities: &EntitiesRes, storage: &ReadStorage<Uid>) {
|
||||
self.mapping = (entities, storage)
|
||||
.join()
|
||||
.map(|(e, m)| (m.id(), e))
|
||||
.collect();
|
||||
}
|
||||
}
|
@ -4,7 +4,8 @@ use crate::{
|
||||
Ori, Pos, Stats,
|
||||
},
|
||||
event::{EventBus, LocalEvent, ServerEvent},
|
||||
state::{DeltaTime, Uid},
|
||||
state::DeltaTime,
|
||||
sync::Uid,
|
||||
};
|
||||
use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
|
||||
use std::time::Duration;
|
||||
|
@ -7,12 +7,12 @@ use crate::{
|
||||
},
|
||||
event::{Emitter, EventBus, LocalEvent, ServerEvent},
|
||||
state::DeltaTime,
|
||||
sync::{Uid, UidAllocator},
|
||||
};
|
||||
use specs::{
|
||||
saveload::{Marker, MarkerAllocator},
|
||||
Entities, Entity, Join, Read, ReadStorage, System, WriteStorage,
|
||||
};
|
||||
use sphynx::{Uid, UidAllocator};
|
||||
use std::time::Duration;
|
||||
use vek::*;
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
use crate::comp::{Controller, MountState, Mounting, Ori, Pos, Vel};
|
||||
use crate::{
|
||||
comp::{Controller, MountState, Mounting, Ori, Pos, Vel},
|
||||
sync::UidAllocator,
|
||||
};
|
||||
use specs::{
|
||||
saveload::{Marker, MarkerAllocator},
|
||||
Entities, Join, Read, System, WriteStorage,
|
||||
};
|
||||
use sphynx::UidAllocator;
|
||||
use vek::*;
|
||||
|
||||
/// This system is responsible for controlling mounts
|
||||
|
@ -5,10 +5,10 @@ use crate::{
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
state::DeltaTime,
|
||||
sync::Uid,
|
||||
terrain::TerrainGrid,
|
||||
};
|
||||
use specs::prelude::*;
|
||||
use sphynx::Uid;
|
||||
use specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage};
|
||||
use std::time::Duration;
|
||||
use vek::*;
|
||||
|
||||
|
@ -3,11 +3,11 @@ use {
|
||||
comp::{Body, Gravity, Mass, Mounting, Ori, PhysicsState, Pos, Scale, Sticky, Vel},
|
||||
event::{EventBus, ServerEvent},
|
||||
state::DeltaTime,
|
||||
sync::Uid,
|
||||
terrain::{Block, TerrainGrid},
|
||||
vol::ReadVol,
|
||||
},
|
||||
specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage},
|
||||
sphynx::Uid,
|
||||
vek::*,
|
||||
};
|
||||
|
||||
|
@ -10,8 +10,8 @@ use common::{
|
||||
msg::ServerMsg,
|
||||
npc::{get_npc_name, NpcKind},
|
||||
pathfinding::WorldPath,
|
||||
sphynx::WorldSyncExt,
|
||||
state::TimeOfDay,
|
||||
sync::WorldSyncExt,
|
||||
terrain::{Block, BlockKind, TerrainChunkSize},
|
||||
vol::RectVolSize,
|
||||
};
|
||||
|
@ -27,8 +27,8 @@ use common::{
|
||||
event::{EventBus, ServerEvent},
|
||||
msg::{ClientMsg, ClientState, ServerError, ServerInfo, ServerMsg},
|
||||
net::PostOffice,
|
||||
sphynx::WorldSyncExt,
|
||||
state::{BlockChange, State, TimeOfDay, Uid},
|
||||
state::{BlockChange, State, TimeOfDay},
|
||||
sync::{Uid, WorldSyncExt},
|
||||
terrain::{block::Block, TerrainChunkSize, TerrainGrid},
|
||||
vol::{ReadVol, RectVolSize, Vox},
|
||||
};
|
||||
@ -899,7 +899,7 @@ impl Server {
|
||||
.set((before_tick_6 - before_handle_events).as_nanos() as i64);
|
||||
self.metrics
|
||||
.tick_time
|
||||
.with_label_values(&["sphynx sync"])
|
||||
.with_label_values(&["entity deletion"])
|
||||
.set((before_tick_7 - before_tick_6).as_nanos() as i64);
|
||||
self.metrics
|
||||
.tick_time
|
||||
|
@ -10,7 +10,7 @@ use common::{
|
||||
comp::{CharacterState, ForceUpdate, Inventory, InventoryUpdate, Last, Ori, Pos, Vel},
|
||||
msg::ServerMsg,
|
||||
region::{Event as RegionEvent, RegionMap},
|
||||
state::Uid,
|
||||
sync::Uid,
|
||||
};
|
||||
use specs::{
|
||||
Entities, Entity as EcsEntity, Join, Read, ReadExpect, ReadStorage, System, Write, WriteStorage,
|
||||
@ -77,8 +77,8 @@ impl<'a> System<'a> for Sys {
|
||||
// 2. Iterate through region subscribers (ie clients)
|
||||
// - Collect a list of entity ids for clients who are subscribed to this region (hash calc to check each)
|
||||
// 3. Iterate through events from that region
|
||||
// - For each entity left event, iterate through the client list and check if they are subscribed to the destination (hash calc per subscribed client per entity left event)
|
||||
// - Do something with entity entered events when sphynx is removed??
|
||||
// - For each entity entered event, iterate through the client list and check if they are subscribed to the source (hash calc per subscribed client per entity event), if not subscribed to the source send a entity creation message to that client
|
||||
// - For each entity left event, iterate through the client list and check if they are subscribed to the destination (hash calc per subscribed client per entity event)
|
||||
// 4. Iterate through entities in that region
|
||||
// 5. Inform clients of the component changes for that entity
|
||||
// - Throttle update rate base on distance to each client
|
||||
|
@ -5,10 +5,11 @@ use common::{
|
||||
Projectile, Scale, Stats, Sticky,
|
||||
},
|
||||
msg::{EcsCompPacket, EcsResPacket},
|
||||
sphynx::{
|
||||
self, EntityPackage, ResSyncPackage, StatePackage, SyncPackage, UpdateTracker, WorldSyncExt,
|
||||
state::{Time, TimeOfDay},
|
||||
sync::{
|
||||
CompPacket, EntityPackage, ResSyncPackage, StatePackage, SyncPackage, Uid, UpdateTracker,
|
||||
WorldSyncExt,
|
||||
},
|
||||
state::{Time, TimeOfDay, Uid},
|
||||
};
|
||||
use shred_derive::SystemData;
|
||||
use specs::{
|
||||
@ -301,7 +302,7 @@ impl<'a> TrackedResources<'a> {
|
||||
.with_res(self.time_of_day.deref())
|
||||
}
|
||||
/// Create state package with resources included
|
||||
pub fn state_package<C: sphynx::CompPacket>(&self) -> StatePackage<C, EcsResPacket> {
|
||||
pub fn state_package<C: CompPacket>(&self) -> StatePackage<C, EcsResPacket> {
|
||||
StatePackage::new()
|
||||
.with_res(self.time.deref())
|
||||
.with_res(self.time_of_day.deref())
|
||||
|
@ -4,7 +4,7 @@ use common::{
|
||||
comp::{CharacterState, Ori, Player, Pos, Vel},
|
||||
msg::ServerMsg,
|
||||
region::{region_in_vd, regions_in_vd, Event as RegionEvent, RegionMap},
|
||||
state::Uid,
|
||||
sync::Uid,
|
||||
terrain::TerrainChunkSize,
|
||||
vol::RectVolSize,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user