mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Improved State API design
Former-commit-id: a32ab93409b1044fe2838f684d30ca2b963d4eb2
This commit is contained in:
parent
99bd0630b7
commit
ffc4e6ebd4
@ -16,12 +16,9 @@ use std::{
|
|||||||
};
|
};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
use threadpool;
|
use threadpool;
|
||||||
use specs::{
|
use specs::Builder;
|
||||||
Builder,
|
|
||||||
saveload::MarkerAllocator,
|
|
||||||
};
|
|
||||||
use common::{
|
use common::{
|
||||||
comp::{self, Uid},
|
comp,
|
||||||
state::State,
|
state::State,
|
||||||
terrain::TerrainChunk,
|
terrain::TerrainChunk,
|
||||||
net::PostBox,
|
net::PostBox,
|
||||||
@ -104,30 +101,6 @@ impl Client {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn state_mut(&mut self) -> &mut State { &mut self.state }
|
pub fn state_mut(&mut self) -> &mut State { &mut self.state }
|
||||||
|
|
||||||
/// Get an entity from its UID, creating it if it does not exists
|
|
||||||
pub fn get_or_create_entity_from_uid(&mut self, uid: Uid) -> EcsEntity {
|
|
||||||
// Find the ECS entity from its UID
|
|
||||||
let ecs_entity = self.state().ecs_world()
|
|
||||||
.read_resource::<comp::UidAllocator>()
|
|
||||||
.retrieve_entity_internal(uid.into());
|
|
||||||
|
|
||||||
// Return the entity or create it
|
|
||||||
if let Some(ecs_entity) = ecs_entity {
|
|
||||||
ecs_entity
|
|
||||||
} else {
|
|
||||||
let ecs_entity = self.state.ecs_world_mut().create_entity()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Allocate it the specific UID given
|
|
||||||
self.state
|
|
||||||
.ecs_world_mut()
|
|
||||||
.write_resource::<comp::UidAllocator>()
|
|
||||||
.allocate(ecs_entity, Some(uid.into()));
|
|
||||||
|
|
||||||
ecs_entity
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the player entity
|
/// Get the player entity
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn player(&self) -> Option<EcsEntity> {
|
pub fn player(&self) -> Option<EcsEntity> {
|
||||||
@ -222,11 +195,17 @@ impl Client {
|
|||||||
ServerMsg::Pong => {},
|
ServerMsg::Pong => {},
|
||||||
ServerMsg::Chat(msg) => frontend_events.push(Event::Chat(msg)),
|
ServerMsg::Chat(msg) => frontend_events.push(Event::Chat(msg)),
|
||||||
ServerMsg::SetPlayerEntity(uid) => {
|
ServerMsg::SetPlayerEntity(uid) => {
|
||||||
let ecs_entity = self.get_or_create_entity_from_uid(uid);
|
let ecs_entity = self.state
|
||||||
|
.get_entity(uid)
|
||||||
|
.unwrap_or_else(|| self.state.build_uid_entity_with_uid(uid).build());
|
||||||
|
|
||||||
self.player = Some(ecs_entity);
|
self.player = Some(ecs_entity);
|
||||||
},
|
},
|
||||||
ServerMsg::EntityPhysics { uid, pos, vel, dir } => {
|
ServerMsg::EntityPhysics { uid, pos, vel, dir } => {
|
||||||
let ecs_entity = self.get_or_create_entity_from_uid(uid);
|
let ecs_entity = self.state
|
||||||
|
.get_entity(uid)
|
||||||
|
.unwrap_or_else(|| self.state.build_uid_entity_with_uid(uid).build());
|
||||||
|
|
||||||
self.state.write_component(ecs_entity, pos);
|
self.state.write_component(ecs_entity, pos);
|
||||||
self.state.write_component(ecs_entity, vel);
|
self.state.write_component(ecs_entity, vel);
|
||||||
self.state.write_component(ecs_entity, dir);
|
self.state.write_component(ecs_entity, dir);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
pub mod phys;
|
pub mod phys;
|
||||||
pub mod uid;
|
pub mod uid;
|
||||||
|
pub mod util;
|
||||||
|
|
||||||
// Reexports
|
// Reexports
|
||||||
pub use uid::{Uid, UidAllocator};
|
pub use uid::{Uid, UidAllocator};
|
||||||
@ -10,6 +11,8 @@ pub fn register_local_components(ecs_world: &mut EcsWorld) {
|
|||||||
ecs_world.register::<Uid>();
|
ecs_world.register::<Uid>();
|
||||||
ecs_world.add_resource(UidAllocator::new());
|
ecs_world.add_resource(UidAllocator::new());
|
||||||
|
|
||||||
|
ecs_world.register::<util::New>();
|
||||||
|
|
||||||
ecs_world.register::<phys::Pos>();
|
ecs_world.register::<phys::Pos>();
|
||||||
ecs_world.register::<phys::Vel>();
|
ecs_world.register::<phys::Vel>();
|
||||||
ecs_world.register::<phys::Dir>();
|
ecs_world.register::<phys::Dir>();
|
||||||
|
12
common/src/comp/util.rs
Normal file
12
common/src/comp/util.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Library
|
||||||
|
use specs::{Component, NullStorage};
|
||||||
|
use vek::*;
|
||||||
|
|
||||||
|
// Pos
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, Default)]
|
||||||
|
pub struct New;
|
||||||
|
|
||||||
|
impl Component for New {
|
||||||
|
type Storage = NullStorage<Self>;
|
||||||
|
}
|
@ -4,13 +4,14 @@ use specs::{
|
|||||||
Builder,
|
Builder,
|
||||||
Component,
|
Component,
|
||||||
DispatcherBuilder,
|
DispatcherBuilder,
|
||||||
|
EntityBuilder as EcsEntityBuilder,
|
||||||
Entity as EcsEntity,
|
Entity as EcsEntity,
|
||||||
World as EcsWorld,
|
World as EcsWorld,
|
||||||
storage::{
|
storage::{
|
||||||
Storage as EcsStorage,
|
Storage as EcsStorage,
|
||||||
MaskedStorage as EcsMaskedStorage,
|
MaskedStorage as EcsMaskedStorage,
|
||||||
},
|
},
|
||||||
saveload::MarkerAllocator,
|
saveload::{MarkedBuilder, MarkerAllocator},
|
||||||
};
|
};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -90,6 +91,24 @@ impl State {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Build a new entity with a generated UID
|
||||||
|
pub fn build_uid_entity(&mut self) -> EcsEntityBuilder {
|
||||||
|
self.ecs_world.create_entity()
|
||||||
|
.with(comp::util::New)
|
||||||
|
.marked::<comp::Uid>()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build an entity with a specific UID
|
||||||
|
pub fn build_uid_entity_with_uid(&mut self, uid: comp::Uid) -> EcsEntityBuilder {
|
||||||
|
let builder = self.build_uid_entity();
|
||||||
|
|
||||||
|
builder.world
|
||||||
|
.write_resource::<comp::UidAllocator>()
|
||||||
|
.allocate(builder.entity, Some(uid.into()));
|
||||||
|
|
||||||
|
builder
|
||||||
|
}
|
||||||
|
|
||||||
/// Get an entity from its UID, if it exists
|
/// Get an entity from its UID, if it exists
|
||||||
pub fn get_entity(&self, uid: comp::Uid) -> Option<EcsEntity> {
|
pub fn get_entity(&self, uid: comp::Uid) -> Option<EcsEntity> {
|
||||||
// Find the ECS entity from its UID
|
// Find the ECS entity from its UID
|
||||||
@ -168,6 +187,9 @@ impl State {
|
|||||||
|
|
||||||
/// Execute a single tick, simulating the game state by the given duration.
|
/// Execute a single tick, simulating the game state by the given duration.
|
||||||
pub fn tick(&mut self, dt: Duration) {
|
pub fn tick(&mut self, dt: Duration) {
|
||||||
|
// First, wipe all temporary marker components
|
||||||
|
self.ecs_world.write_storage::<comp::util::New>().clear();
|
||||||
|
|
||||||
// Change the time accordingly
|
// Change the time accordingly
|
||||||
self.ecs_world.write_resource::<TimeOfDay>().0 += dt.as_secs_f64() * DAY_CYCLE_FACTOR;
|
self.ecs_world.write_resource::<TimeOfDay>().0 += dt.as_secs_f64() * DAY_CYCLE_FACTOR;
|
||||||
self.ecs_world.write_resource::<Time>().0 += dt.as_secs_f64();
|
self.ecs_world.write_resource::<Time>().0 += dt.as_secs_f64();
|
||||||
|
@ -77,15 +77,9 @@ impl Server {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn state_mut(&mut self) -> &mut State { &mut self.state }
|
pub fn state_mut(&mut self) -> &mut State { &mut self.state }
|
||||||
|
|
||||||
/// Build a new entity with a generated UID
|
|
||||||
pub fn build_entity(&mut self) -> EcsEntityBuilder {
|
|
||||||
self.state.ecs_world_mut().create_entity()
|
|
||||||
.marked::<comp::Uid>()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Build a new player with a generated UID
|
/// Build a new player with a generated UID
|
||||||
pub fn build_player(&mut self) -> EcsEntityBuilder {
|
pub fn build_player(&mut self) -> EcsEntityBuilder {
|
||||||
self.build_entity()
|
self.state.build_uid_entity()
|
||||||
.with(comp::phys::Pos(Vec3::zero()))
|
.with(comp::phys::Pos(Vec3::zero()))
|
||||||
.with(comp::phys::Vel(Vec3::zero()))
|
.with(comp::phys::Vel(Vec3::zero()))
|
||||||
.with(comp::phys::Dir(Vec3::unit_y()))
|
.with(comp::phys::Dir(Vec3::unit_y()))
|
||||||
@ -207,7 +201,7 @@ impl Server {
|
|||||||
}
|
}
|
||||||
} else if
|
} else if
|
||||||
state.get_time() - client.last_ping > CLIENT_TIMEOUT || // Timeout
|
state.get_time() - client.last_ping > CLIENT_TIMEOUT || // Timeout
|
||||||
client.postbox.error().is_some() // Postbox eror
|
client.postbox.error().is_some() // Postbox error
|
||||||
{
|
{
|
||||||
disconnected = true;
|
disconnected = true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user