2019-10-20 05:19:50 +00:00
|
|
|
pub mod entity_sync;
|
2019-10-15 04:06:14 +00:00
|
|
|
pub mod message;
|
2020-04-25 13:41:27 +00:00
|
|
|
pub mod persistence;
|
2019-11-04 00:57:36 +00:00
|
|
|
pub mod sentinel;
|
2020-05-24 22:18:41 +00:00
|
|
|
pub mod speech_bubble;
|
2019-10-15 04:06:14 +00:00
|
|
|
pub mod subscription;
|
2019-10-20 05:19:50 +00:00
|
|
|
pub mod terrain;
|
|
|
|
pub mod terrain_sync;
|
2020-01-25 12:27:36 +00:00
|
|
|
pub mod waypoint;
|
2019-10-15 04:06:14 +00:00
|
|
|
|
|
|
|
use specs::DispatcherBuilder;
|
2020-04-25 13:41:27 +00:00
|
|
|
use std::{
|
|
|
|
marker::PhantomData,
|
|
|
|
time::{Duration, Instant},
|
|
|
|
};
|
2019-10-20 07:20:21 +00:00
|
|
|
|
|
|
|
pub type EntitySyncTimer = SysTimer<entity_sync::Sys>;
|
|
|
|
pub type MessageTimer = SysTimer<message::Sys>;
|
2019-11-04 00:57:36 +00:00
|
|
|
pub type SentinelTimer = SysTimer<sentinel::Sys>;
|
2019-10-20 07:20:21 +00:00
|
|
|
pub type SubscriptionTimer = SysTimer<subscription::Sys>;
|
|
|
|
pub type TerrainTimer = SysTimer<terrain::Sys>;
|
|
|
|
pub type TerrainSyncTimer = SysTimer<terrain_sync::Sys>;
|
2020-03-09 03:32:34 +00:00
|
|
|
pub type WaypointTimer = SysTimer<waypoint::Sys>;
|
2020-05-24 22:18:41 +00:00
|
|
|
pub type SpeechBubbleTimer = SysTimer<speech_bubble::Sys>;
|
2020-05-11 10:06:53 +00:00
|
|
|
pub type StatsPersistenceTimer = SysTimer<persistence::stats::Sys>;
|
2020-04-25 13:41:27 +00:00
|
|
|
pub type StatsPersistenceScheduler = SysScheduler<persistence::stats::Sys>;
|
2019-10-15 04:06:14 +00:00
|
|
|
|
|
|
|
// System names
|
2020-03-09 03:32:34 +00:00
|
|
|
// Note: commented names may be useful in the future
|
|
|
|
//const ENTITY_SYNC_SYS: &str = "server_entity_sync_sys";
|
|
|
|
//const SENTINEL_SYS: &str = "sentinel_sys";
|
|
|
|
//const SUBSCRIPTION_SYS: &str = "server_subscription_sys";
|
|
|
|
//const TERRAIN_SYNC_SYS: &str = "server_terrain_sync_sys";
|
2019-10-20 05:19:50 +00:00
|
|
|
const TERRAIN_SYS: &str = "server_terrain_sys";
|
2020-01-25 12:27:36 +00:00
|
|
|
const WAYPOINT_SYS: &str = "waypoint_sys";
|
2020-05-24 22:18:41 +00:00
|
|
|
const SPEECH_BUBBLE_SYS: &str = "speech_bubble_sys";
|
2020-04-25 13:41:27 +00:00
|
|
|
const STATS_PERSISTENCE_SYS: &str = "stats_persistence_sys";
|
2019-10-15 04:06:14 +00:00
|
|
|
|
|
|
|
pub fn add_server_systems(dispatch_builder: &mut DispatcherBuilder) {
|
2020-03-09 03:32:34 +00:00
|
|
|
dispatch_builder.add(terrain::Sys, TERRAIN_SYS, &[]);
|
2020-01-25 12:27:36 +00:00
|
|
|
dispatch_builder.add(waypoint::Sys, WAYPOINT_SYS, &[]);
|
2020-05-24 22:18:41 +00:00
|
|
|
dispatch_builder.add(speech_bubble::Sys, SPEECH_BUBBLE_SYS, &[]);
|
2020-04-25 13:41:27 +00:00
|
|
|
dispatch_builder.add(persistence::stats::Sys, STATS_PERSISTENCE_SYS, &[]);
|
2019-10-15 04:06:14 +00:00
|
|
|
}
|
2019-10-20 07:20:21 +00:00
|
|
|
|
2020-03-09 03:32:34 +00:00
|
|
|
pub fn run_sync_systems(ecs: &mut specs::World) {
|
|
|
|
use specs::RunNow;
|
|
|
|
|
|
|
|
// Setup for entity sync
|
|
|
|
// If I'm not mistaken, these two could be ran in parallel
|
|
|
|
sentinel::Sys.run_now(ecs);
|
|
|
|
subscription::Sys.run_now(ecs);
|
|
|
|
|
|
|
|
// Sync
|
|
|
|
terrain_sync::Sys.run_now(ecs);
|
|
|
|
entity_sync::Sys.run_now(ecs);
|
|
|
|
}
|
|
|
|
|
2020-04-25 13:41:27 +00:00
|
|
|
/// Used to schedule systems to run at an interval
|
|
|
|
pub struct SysScheduler<S> {
|
|
|
|
interval: Duration,
|
|
|
|
last_run: Instant,
|
|
|
|
_phantom: PhantomData<S>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<S> SysScheduler<S> {
|
|
|
|
pub fn every(interval: Duration) -> Self {
|
|
|
|
Self {
|
|
|
|
interval,
|
|
|
|
last_run: Instant::now(),
|
|
|
|
_phantom: PhantomData,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn should_run(&mut self) -> bool {
|
|
|
|
if self.last_run.elapsed() > self.interval {
|
|
|
|
self.last_run = Instant::now();
|
|
|
|
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<S> Default for SysScheduler<S> {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
|
|
|
interval: Duration::from_secs(30),
|
|
|
|
last_run: Instant::now(),
|
|
|
|
_phantom: PhantomData,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-20 07:20:21 +00:00
|
|
|
/// Used to keep track of how much time each system takes
|
|
|
|
pub struct SysTimer<S> {
|
|
|
|
pub nanos: u64,
|
|
|
|
start: Option<Instant>,
|
|
|
|
_phantom: PhantomData<S>,
|
|
|
|
}
|
2020-04-25 13:41:27 +00:00
|
|
|
|
2019-10-20 07:20:21 +00:00
|
|
|
impl<S> SysTimer<S> {
|
|
|
|
pub fn start(&mut self) {
|
|
|
|
if self.start.is_some() {
|
|
|
|
panic!("Timer already started");
|
|
|
|
}
|
|
|
|
self.start = Some(Instant::now());
|
|
|
|
}
|
2020-02-01 20:39:39 +00:00
|
|
|
|
2019-10-20 07:20:21 +00:00
|
|
|
pub fn end(&mut self) {
|
|
|
|
self.nanos = self
|
|
|
|
.start
|
|
|
|
.take()
|
|
|
|
.expect("Timer ended without starting it")
|
|
|
|
.elapsed()
|
|
|
|
.as_nanos() as u64;
|
|
|
|
}
|
|
|
|
}
|
2020-04-25 13:41:27 +00:00
|
|
|
|
2019-10-20 07:20:21 +00:00
|
|
|
impl<S> Default for SysTimer<S> {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
|
|
|
nanos: 0,
|
|
|
|
start: None,
|
|
|
|
_phantom: PhantomData,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|