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 threadpool;
|
||||
use specs::{
|
||||
Builder,
|
||||
saveload::MarkerAllocator,
|
||||
};
|
||||
use specs::Builder;
|
||||
use common::{
|
||||
comp::{self, Uid},
|
||||
comp,
|
||||
state::State,
|
||||
terrain::TerrainChunk,
|
||||
net::PostBox,
|
||||
@ -104,30 +101,6 @@ impl Client {
|
||||
#[allow(dead_code)]
|
||||
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
|
||||
#[allow(dead_code)]
|
||||
pub fn player(&self) -> Option<EcsEntity> {
|
||||
@ -222,11 +195,17 @@ impl Client {
|
||||
ServerMsg::Pong => {},
|
||||
ServerMsg::Chat(msg) => frontend_events.push(Event::Chat(msg)),
|
||||
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);
|
||||
},
|
||||
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, vel);
|
||||
self.state.write_component(ecs_entity, dir);
|
||||
|
@ -1,5 +1,6 @@
|
||||
pub mod phys;
|
||||
pub mod uid;
|
||||
pub mod util;
|
||||
|
||||
// Reexports
|
||||
pub use uid::{Uid, UidAllocator};
|
||||
@ -10,6 +11,8 @@ pub fn register_local_components(ecs_world: &mut EcsWorld) {
|
||||
ecs_world.register::<Uid>();
|
||||
ecs_world.add_resource(UidAllocator::new());
|
||||
|
||||
ecs_world.register::<util::New>();
|
||||
|
||||
ecs_world.register::<phys::Pos>();
|
||||
ecs_world.register::<phys::Vel>();
|
||||
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,
|
||||
Component,
|
||||
DispatcherBuilder,
|
||||
EntityBuilder as EcsEntityBuilder,
|
||||
Entity as EcsEntity,
|
||||
World as EcsWorld,
|
||||
storage::{
|
||||
Storage as EcsStorage,
|
||||
MaskedStorage as EcsMaskedStorage,
|
||||
},
|
||||
saveload::MarkerAllocator,
|
||||
saveload::{MarkedBuilder, MarkerAllocator},
|
||||
};
|
||||
use vek::*;
|
||||
use crate::{
|
||||
@ -90,6 +91,24 @@ impl State {
|
||||
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
|
||||
pub fn get_entity(&self, uid: comp::Uid) -> Option<EcsEntity> {
|
||||
// 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.
|
||||
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
|
||||
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();
|
||||
|
@ -77,15 +77,9 @@ impl Server {
|
||||
#[allow(dead_code)]
|
||||
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
|
||||
pub fn build_player(&mut self) -> EcsEntityBuilder {
|
||||
self.build_entity()
|
||||
self.state.build_uid_entity()
|
||||
.with(comp::phys::Pos(Vec3::zero()))
|
||||
.with(comp::phys::Vel(Vec3::zero()))
|
||||
.with(comp::phys::Dir(Vec3::unit_y()))
|
||||
@ -207,7 +201,7 @@ impl Server {
|
||||
}
|
||||
} else if
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user