veloren_server/sys/
mod.rs

1pub mod agent;
2pub mod chunk_send;
3pub mod chunk_serialize;
4pub mod entity_sync;
5pub mod invite_timeout;
6pub mod item;
7pub mod loot;
8pub mod metrics;
9pub mod msg;
10pub mod object;
11pub mod persistence;
12pub mod pets;
13pub mod sentinel;
14pub mod server_info;
15pub mod subscription;
16pub mod teleporter;
17pub mod terrain;
18pub mod terrain_sync;
19pub mod waypoint;
20pub mod wiring;
21
22use common_ecs::{System, dispatch, run_now};
23use common_systems::{melee, projectile};
24use specs::DispatcherBuilder;
25use std::{
26    marker::PhantomData,
27    time::{Duration, Instant},
28};
29
30pub type PersistenceScheduler = SysScheduler<persistence::Sys>;
31
32pub fn add_server_systems(dispatch_builder: &mut DispatcherBuilder) {
33    dispatch::<melee::Sys>(dispatch_builder, &[&projectile::Sys::sys_name()]);
34    //Note: server should not depend on interpolation system
35    dispatch::<agent::Sys>(dispatch_builder, &[]);
36    dispatch::<terrain::Sys>(dispatch_builder, &[&msg::terrain::Sys::sys_name()]);
37    dispatch::<waypoint::Sys>(dispatch_builder, &[]);
38    dispatch::<teleporter::Sys>(dispatch_builder, &[]);
39    dispatch::<invite_timeout::Sys>(dispatch_builder, &[]);
40    dispatch::<persistence::Sys>(dispatch_builder, &[]);
41    dispatch::<object::Sys>(dispatch_builder, &[]);
42    dispatch::<wiring::Sys>(dispatch_builder, &[]);
43    // no dependency, as we only work once per sec anyway.
44    dispatch::<chunk_serialize::Sys>(dispatch_builder, &[]);
45    // don't depend on chunk_serialize, as we assume everything is done in a SlowJow
46    dispatch::<chunk_send::Sys>(dispatch_builder, &[]);
47    dispatch::<item::Sys>(dispatch_builder, &[]);
48    dispatch::<server_info::Sys>(dispatch_builder, &[]);
49}
50
51pub fn run_sync_systems(ecs: &mut specs::World) {
52    // Setup for entity sync
53    // If I'm not mistaken, these two could be ran in parallel
54    run_now::<sentinel::Sys>(ecs);
55    run_now::<subscription::Sys>(ecs);
56
57    // Sync
58    run_now::<terrain_sync::Sys>(ecs);
59    run_now::<entity_sync::Sys>(ecs);
60}
61
62/// Used to schedule systems to run at an interval
63pub struct SysScheduler<S> {
64    interval: Duration,
65    last_run: Instant,
66    _phantom: PhantomData<S>,
67}
68
69impl<S> SysScheduler<S> {
70    pub fn every(interval: Duration) -> Self {
71        Self {
72            interval,
73            last_run: Instant::now(),
74            _phantom: PhantomData,
75        }
76    }
77
78    pub fn should_run(&mut self) -> bool {
79        if self.last_run.elapsed() > self.interval {
80            self.last_run = Instant::now();
81
82            true
83        } else {
84            false
85        }
86    }
87}
88
89impl<S> Default for SysScheduler<S> {
90    fn default() -> Self {
91        Self {
92            interval: Duration::from_secs(30),
93            last_run: Instant::now(),
94            _phantom: PhantomData,
95        }
96    }
97}