Only construct specs::Dispatcher once

* use version of shred that has an added SendDispatcher so we can
  construct the dispatcher and send it between threads (only State to
  remain sendable)
* move closure for adding systems from State::tick to the creation
  functions
* this does mean some voxygen systems always run instead of just in the
  session state, but that should not cause issues and we can always
  configure them to do nothing if needed
This commit is contained in:
Imbris 2024-01-02 23:38:31 -05:00
parent 35fc92f872
commit 6c6b9181a5
30 changed files with 177 additions and 125 deletions

93
Cargo.lock generated
View File

@ -58,14 +58,15 @@ dependencies = [
[[package]]
name = "ahash"
version = "0.8.3"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01"
dependencies = [
"cfg-if 1.0.0",
"getrandom 0.2.10",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
@ -320,7 +321,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f00425f4c1f3349b35daf0a73477249f6574fe89f4b9d76aca0b2a1356886b3b"
dependencies = [
"ab_glyph",
"ahash 0.8.3",
"ahash 0.8.7",
"bincode",
"crossbeam-channel",
"log",
@ -350,7 +351,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0"
dependencies = [
"proc-macro2 1.0.66",
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
]
[[package]]
@ -655,7 +656,7 @@ checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192"
dependencies = [
"proc-macro2 1.0.66",
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
]
[[package]]
@ -872,7 +873,7 @@ dependencies = [
"heck 0.4.1",
"proc-macro2 1.0.66",
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
]
[[package]]
@ -1572,7 +1573,7 @@ dependencies = [
"ident_case",
"proc-macro2 1.0.66",
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
]
[[package]]
@ -1594,7 +1595,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
dependencies = [
"darling_core 0.20.3",
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
]
[[package]]
@ -1755,7 +1756,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
dependencies = [
"proc-macro2 1.0.66",
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
]
[[package]]
@ -1773,7 +1774,7 @@ version = "5.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd05cab02d6074145c6f92ddf1b57357e4bc1424f87c790c044de62bdc94c13a"
dependencies = [
"ahash 0.8.3",
"ahash 0.8.7",
"lazy_static",
"log",
"nom",
@ -1875,7 +1876,7 @@ checksum = "ccb14d927583dd5c2eac0f2cf264fc4762aefe1ae14c47a8a20fc1939d3a5fc0"
dependencies = [
"proc-macro2 1.0.66",
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
]
[[package]]
@ -1896,7 +1897,7 @@ dependencies = [
"darling 0.20.3",
"proc-macro2 1.0.66",
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
]
[[package]]
@ -2238,7 +2239,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
dependencies = [
"proc-macro2 1.0.66",
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
]
[[package]]
@ -2703,7 +2704,7 @@ version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
dependencies = [
"ahash 0.8.3",
"ahash 0.8.7",
"rayon",
"serde",
]
@ -2714,7 +2715,7 @@ version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
dependencies = [
"ahash 0.8.3",
"ahash 0.8.7",
"allocator-api2",
]
@ -4005,7 +4006,7 @@ checksum = "9e6a0fd4f737c707bd9086cc16c925f294943eb62eb71499e9fd4cf71f8b9f4e"
dependencies = [
"proc-macro2 1.0.66",
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
]
[[package]]
@ -4112,7 +4113,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2 1.0.66",
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
]
[[package]]
@ -4511,7 +4512,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
dependencies = [
"proc-macro2 1.0.66",
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
]
[[package]]
@ -4667,7 +4668,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "097bf8b99121dfb8c75eed54dfbdbdb1d53e372c53d2353e8a15aad2a479249d"
dependencies = [
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
]
[[package]]
@ -5047,7 +5048,7 @@ dependencies = [
"quote 1.0.33",
"refinery-core",
"regex",
"syn 2.0.29",
"syn 2.0.32",
]
[[package]]
@ -5486,7 +5487,7 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "772575a524feeb803e5b0fcbc6dd9f367e579488197c94c6e4023aad2305774d"
dependencies = [
"ahash 0.8.3",
"ahash 0.8.7",
"cfg-if 1.0.0",
"hashbrown 0.13.2",
]
@ -5633,7 +5634,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
dependencies = [
"proc-macro2 1.0.66",
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
]
[[package]]
@ -5665,7 +5666,7 @@ checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00"
dependencies = [
"proc-macro2 1.0.66",
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
]
[[package]]
@ -5767,10 +5768,9 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
[[package]]
name = "shred"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc6b2cd1ccb08cf2b25d75c936e0cc9c8cb93c39a83814956da32653236338c0"
source = "git+https://github.com/Imberflur/shred.git?rev=5d52c6fc390dd04c12158633e77591f6523d1f85#5d52c6fc390dd04c12158633e77591f6523d1f85"
dependencies = [
"ahash 0.7.6",
"ahash 0.8.7",
"arrayvec 0.7.4",
"atomic_refcell",
"rayon",
@ -5782,8 +5782,7 @@ dependencies = [
[[package]]
name = "shred-derive"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5404c36bd155e41a54276ab6aafedad2fb627e5e5849d36ec439c9ddc044a2f"
source = "git+https://github.com/Imberflur/shred.git?rev=5d52c6fc390dd04c12158633e77591f6523d1f85#5d52c6fc390dd04c12158633e77591f6523d1f85"
dependencies = [
"proc-macro2 1.0.66",
"quote 1.0.33",
@ -6200,9 +6199,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.29"
version = "2.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a"
checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2"
dependencies = [
"proc-macro2 1.0.66",
"quote 1.0.33",
@ -6277,7 +6276,7 @@ checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b"
dependencies = [
"proc-macro2 1.0.66",
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
]
[[package]]
@ -6456,7 +6455,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
dependencies = [
"proc-macro2 1.0.66",
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
]
[[package]]
@ -6597,7 +6596,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
dependencies = [
"proc-macro2 1.0.66",
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
]
[[package]]
@ -6723,7 +6722,7 @@ version = "1.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
dependencies = [
"cfg-if 1.0.0",
"cfg-if 0.1.10",
"rand 0.8.5",
"static_assertions",
]
@ -7176,7 +7175,7 @@ version = "0.1.0"
dependencies = [
"proc-macro2 1.0.66",
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
]
[[package]]
@ -7596,7 +7595,7 @@ dependencies = [
"once_cell",
"proc-macro2 1.0.66",
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
"wasm-bindgen-shared",
]
@ -7653,7 +7652,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
dependencies = [
"proc-macro2 1.0.66",
"quote 1.0.33",
"syn 2.0.29",
"syn 2.0.32",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@ -8499,3 +8498,23 @@ checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd"
dependencies = [
"time 0.3.28",
]
[[package]]
name = "zerocopy"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [
"proc-macro2 1.0.66",
"quote 1.0.33",
"syn 2.0.32",
]

View File

@ -165,6 +165,7 @@ winit = { git = "https://github.com/Imberflur/winit.git", tag = "raw-window-hand
wgpu = { git = "https://github.com/pythonesque/wgpu.git", rev = "179ea209374a92837cde252f1d9ee01f628cae08" }
# ntapi 3.7 fails to compile under windows due to the bug https://github.com/MSxDOS/ntapi/pull/12
ntapi = { git = "https://github.com/MSxDOS/ntapi.git", rev = "9f56b149c9e25796739157c0fce3e0007a7de6eb" }
shred = { git = "https://github.com/Imberflur/shred.git", rev = "5d52c6fc390dd04c12158633e77591f6523d1f85" }
[patch."https://github.com/gfx-rs/gfx"]
gfx-hal = { git = "https://github.com/Imberflur/gfx.git", tag = "veloren-fixes-v1" }

View File

@ -65,6 +65,7 @@ fn main() {
&password,
|provider| provider == "https://auth.veloren.net",
&|_| {},
|_| {},
))
.expect("Failed to create client instance");
@ -85,7 +86,7 @@ fn main() {
client.send_chat(msg)
}
let events = match client.tick(comp::ControllerInputs::default(), clock.dt(), |_| {}) {
let events = match client.tick(comp::ControllerInputs::default(), clock.dt()) {
Ok(events) => events,
Err(err) => {
error!("Error: {:?}", err);

View File

@ -73,6 +73,7 @@ pub fn make_client(
password,
|_| true,
&|_| {},
|_| {},
))
.ok()
}
@ -99,7 +100,7 @@ impl BotClient {
for (username, client) in self.bot_clients.iter_mut() {
trace!(?username, "tick");
let _msgs: Result<Vec<veloren_client::Event>, veloren_client::Error> =
client.tick(comp::ControllerInputs::default(), self.clock.dt(), |_| {});
client.tick(comp::ControllerInputs::default(), self.clock.dt());
}
}

View File

@ -123,6 +123,7 @@ fn run_client(
&username,
"",
|_| false,
|_| {},
)) {
Err(e) => tracing::warn!(?e, "Client {} disconnected", index),
Ok(client) => break client,

View File

@ -307,6 +307,7 @@ impl Client {
password: &str,
auth_trusted: impl FnMut(&str) -> bool,
init_stage_update: &(dyn Fn(ClientInitStage) + Send + Sync),
add_foreign_systems: impl Fn(&mut DispatcherBuilder) + Send + 'static,
) -> Result<Self, Error> {
let network = Network::new(Pid::new(), &runtime);
@ -409,7 +410,13 @@ impl Client {
// Initialize `State`
let pools = State::pools(GameMode::Client);
let mut state = State::client(pools, map_size_lg, world_map.default_chunk);
let mut state = State::client(pools, map_size_lg, world_map.default_chunk,
// TODO: Add frontend systems
|dispatch_builder| {
add_local_systems(dispatch_builder);
add_foreign_systems(dispatch_builder);
},
);
// Client-only components
state.ecs_mut().register::<comp::Last<CharacterState>>();
let entity = state.ecs_mut().apply_entity_package(entity_package);
@ -1800,7 +1807,6 @@ impl Client {
&mut self,
inputs: ControllerInputs,
dt: Duration,
add_foreign_systems: impl Fn(&mut DispatcherBuilder),
) -> Result<Vec<Event>, Error> {
span!(_guard, "tick", "Client::tick");
// This tick function is the centre of the Veloren universe. Most client-side
@ -1902,10 +1908,6 @@ impl Client {
// 4) Tick the client's LocalState
self.state.tick(
Duration::from_secs_f64(dt.as_secs_f64() * self.dt_adjustment),
|dispatch_builder| {
add_local_systems(dispatch_builder);
add_foreign_systems(dispatch_builder);
},
true,
None,
&self.connected_server_constants,
@ -3011,6 +3013,7 @@ mod tests {
password,
|suggestion: &str| suggestion == auth_server,
&|_| {},
|_| {},
));
let localisation = LocalizationHandle::load_expect("en");
@ -3020,7 +3023,7 @@ mod tests {
//tick
let events_result: Result<Vec<Event>, Error> =
client.tick(ControllerInputs::default(), clock.dt(), |_| {});
client.tick(ControllerInputs::default(), clock.dt());
//chat functionality
client.send_chat("foobar".to_string());

View File

@ -33,7 +33,7 @@ use hashbrown::{HashMap, HashSet};
use rayon::{ThreadPool, ThreadPoolBuilder};
use specs::{
prelude::Resource,
shred::{Fetch, FetchMut},
shred::{Fetch, FetchMut, SendDispatcher},
storage::{MaskedStorage as EcsMaskedStorage, Storage as EcsStorage},
Component, DispatcherBuilder, Entity as EcsEntity, WorldExt,
};
@ -128,6 +128,7 @@ pub struct State {
ecs: specs::World,
// Avoid lifetime annotation by storing a thread pool instead of the whole dispatcher
thread_pool: Arc<ThreadPool>,
dispatcher: SendDispatcher<'static>,
}
pub type Pools = Arc<ThreadPool>;
@ -150,13 +151,35 @@ impl State {
}
/// Create a new `State` in client mode.
pub fn client(pools: Pools, map_size_lg: MapSizeLg, default_chunk: Arc<TerrainChunk>) -> Self {
Self::new(GameMode::Client, pools, map_size_lg, default_chunk)
pub fn client(
pools: Pools,
map_size_lg: MapSizeLg,
default_chunk: Arc<TerrainChunk>,
add_systems: impl Fn(&mut DispatcherBuilder),
) -> Self {
Self::new(
GameMode::Client,
pools,
map_size_lg,
default_chunk,
add_systems,
)
}
/// Create a new `State` in server mode.
pub fn server(pools: Pools, map_size_lg: MapSizeLg, default_chunk: Arc<TerrainChunk>) -> Self {
Self::new(GameMode::Server, pools, map_size_lg, default_chunk)
pub fn server(
pools: Pools,
map_size_lg: MapSizeLg,
default_chunk: Arc<TerrainChunk>,
add_systems: impl Fn(&mut DispatcherBuilder),
) -> Self {
Self::new(
GameMode::Server,
pools,
map_size_lg,
default_chunk,
add_systems,
)
}
pub fn new(
@ -164,10 +187,24 @@ impl State {
pools: Pools,
map_size_lg: MapSizeLg,
default_chunk: Arc<TerrainChunk>,
add_systems: impl Fn(&mut DispatcherBuilder),
) -> Self {
prof_span!(guard, "create dispatcher");
let mut dispatch_builder =
DispatcherBuilder::<'static, 'static>::new().with_pool(Arc::clone(&pools));
// TODO: Consider alternative ways to do this
add_systems(&mut dispatch_builder);
// This dispatches all the systems in parallel.
let dispatcher = dispatch_builder
.build()
.try_into_sendable()
.unwrap_or_else(|_| panic!("Thread local systems not allowed"));
drop(guard);
Self {
ecs: Self::setup_ecs_world(game_mode, Arc::clone(&pools), map_size_lg, default_chunk),
thread_pool: pools,
dispatcher,
}
}
@ -615,7 +652,6 @@ impl State {
pub fn tick(
&mut self,
dt: Duration,
add_systems: impl Fn(&mut DispatcherBuilder),
update_terrain: bool,
mut metrics: Option<&mut StateTickMetrics>,
server_constants: &ServerConstants,
@ -645,19 +681,8 @@ impl State {
self.ecs.write_resource::<DeltaTime>().0 =
(dt.as_secs_f32() * time_scale as f32).min(MAX_DELTA_TIME);
section_span!(guard, "create dispatcher");
// Run systems to update the world.
// Create and run a dispatcher for ecs systems.
let mut dispatch_builder =
DispatcherBuilder::new().with_pool(Arc::clone(&self.thread_pool));
// TODO: Consider alternative ways to do this
add_systems(&mut dispatch_builder);
// This dispatches all the systems in parallel.
let mut dispatcher = dispatch_builder.build();
drop(guard);
section_span!(guard, "run systems");
dispatcher.dispatch(&self.ecs);
self.dispatcher.dispatch(&self.ecs);
drop(guard);
section_span!(guard, "maintain ecs");

View File

@ -12,7 +12,7 @@ use common::{
};
use common_ecs::{Job, Origin, Phase, System};
use specs::{
shred::ResourceId, Entities, Entity as EcsEntity, Join, Read, ReadStorage, SystemData, World,
shred, Entities, Entity as EcsEntity, Join, Read, ReadStorage, SystemData,
};
#[derive(SystemData)]

View File

@ -17,8 +17,8 @@ use common_ecs::{Job, Origin, ParMode, Phase, System};
use rand::Rng;
use rayon::iter::ParallelIterator;
use specs::{
shred::ResourceId, Entities, LendJoin, ParJoin, Read, ReadExpect, ReadStorage, SystemData,
World, WriteStorage,
shred, Entities, LendJoin, ParJoin, Read, ReadExpect, ReadStorage,
SystemData, WriteStorage,
};
use vek::*;

View File

@ -22,8 +22,8 @@ use common_base::prof_span;
use common_ecs::{Job, Origin, ParMode, Phase, System};
use rayon::iter::ParallelIterator;
use specs::{
shred::ResourceId, Entities, Entity, LendJoin, ParJoin, Read, ReadExpect, ReadStorage,
SystemData, World, WriteStorage,
shred, Entities, Entity, LendJoin, ParJoin, Read, ReadExpect, ReadStorage,
SystemData, WriteStorage,
};
#[derive(SystemData)]

View File

@ -1,6 +1,6 @@
use specs::{
shred::ResourceId, Entities, LazyUpdate, LendJoin, Read, ReadExpect, ReadStorage, SystemData,
World, WriteStorage,
shred, Entities, LazyUpdate, LendJoin, Read, ReadExpect, ReadStorage,
SystemData, WriteStorage,
};
use common::{

View File

@ -10,7 +10,7 @@ use common::{
};
use common_ecs::{Job, Origin, Phase, System};
use specs::{
shred::ResourceId, Entities, Join, Read, ReadExpect, ReadStorage, SystemData, World,
shred, Entities, Join, Read, ReadExpect, ReadStorage, SystemData,
WriteStorage,
};
use vek::*;

View File

@ -6,8 +6,8 @@ use common_base::prof_span;
use common_ecs::{Job, Origin, Phase, System};
use common_net::sync::InterpolatableComponent;
use specs::{
prelude::ParallelIterator, shred::ResourceId, Entities, ParJoin, Read, ReadStorage, SystemData,
World, WriteStorage,
prelude::ParallelIterator, shred, Entities, ParJoin, Read, ReadStorage,
SystemData, WriteStorage,
};
#[derive(SystemData)]

View File

@ -18,8 +18,7 @@ use common::{
use common_ecs::{Job, Origin, Phase, System};
use itertools::Itertools;
use specs::{
shred::ResourceId, Entities, Join, LendJoin, Read, ReadExpect, ReadStorage, SystemData, World,
WriteStorage,
shred, Entities, Join, LendJoin, Read, ReadExpect, ReadStorage, SystemData, WriteStorage,
};
use vek::*;

View File

@ -22,7 +22,7 @@ use common_base::{prof_span, span};
use common_ecs::{Job, Origin, ParMode, Phase, PhysicsMetrics, System};
use rayon::iter::ParallelIterator;
use specs::{
shred::{ResourceId, World},
shred,
Entities, Entity, Join, LendJoin, ParJoin, Read, ReadExpect, ReadStorage, SystemData, Write,
WriteExpect, WriteStorage,
};

View File

@ -17,8 +17,8 @@ use common::vol::ReadVol;
use common_ecs::{Job, Origin, Phase, System};
use rand::Rng;
use specs::{
shred::ResourceId, Entities, Entity as EcsEntity, Join, Read, ReadExpect, ReadStorage,
SystemData, World, WriteStorage,
shred, Entities, Entity as EcsEntity, Join, Read, ReadExpect, ReadStorage,
SystemData, WriteStorage,
};
use std::time::Duration;
use vek::*;

View File

@ -16,7 +16,8 @@ use common::{
use common_ecs::{Job, Origin, Phase, System};
use rand::Rng;
use specs::{
shred::ResourceId, Entities, Join, LendJoin, Read, ReadStorage, SystemData, World, WriteStorage,
shred, Entities, Join, LendJoin, Read, ReadStorage, SystemData,
WriteStorage,
};
use vek::*;

View File

@ -12,8 +12,8 @@ use common::{
};
use common_ecs::{Job, Origin, Phase, System};
use specs::{
shred::ResourceId, Entities, LendJoin, Read, ReadExpect, ReadStorage, SystemData, World, Write,
WriteStorage,
shred, Entities, LendJoin, Read, ReadExpect, ReadStorage, SystemData,
Write, WriteStorage,
};
const ENERGY_REGEN_ACCEL: f32 = 1.0;

View File

@ -34,6 +34,9 @@ mod tests {
pools,
DEFAULT_WORLD_CHUNKS_LG,
Arc::new(TerrainChunk::water(0)),
|dispatch_builder| {
dispatch::<character_behavior::Sys>(dispatch_builder, &[]);
},
);
let msm = MaterialStatManifest::load().cloned();
state.ecs_mut().insert(msm);
@ -78,9 +81,6 @@ mod tests {
fn tick(state: &mut State, dt: Duration) {
state.tick(
dt,
|dispatch_builder| {
dispatch::<character_behavior::Sys>(dispatch_builder, &[]);
},
false,
None,
&ServerConstants {

View File

@ -5,17 +5,13 @@ use specs::WorldExt;
use std::error::Error;
use utils::{DT, DT_F64, EPSILON};
use vek::{approx, Vec2, Vec3};
use veloren_common_systems::add_local_systems;
#[test]
fn simple_run() {
let mut state = utils::setup();
let mut state = utils::setup(veloren_common_systems::add_local_systems);
utils::create_player(&mut state);
state.tick(
DT,
|dispatcher_builder| {
add_local_systems(dispatcher_builder);
},
false,
None,
&ServerConstants {
@ -27,7 +23,7 @@ fn simple_run() {
#[test]
fn dont_fall_outside_world() -> Result<(), Box<dyn Error>> {
let mut state = utils::setup();
let mut state = utils::setup(utils::add_char_and_phys_systems);
let p1 = utils::create_player(&mut state);
{
@ -54,7 +50,7 @@ fn dont_fall_outside_world() -> Result<(), Box<dyn Error>> {
#[test]
fn fall_simple() -> Result<(), Box<dyn Error>> {
let mut state = utils::setup();
let mut state = utils::setup(utils::add_char_and_phys_systems);
let p1 = utils::create_player(&mut state);
let (pos, vel, _) = utils::get_transform(&state, p1)?;
@ -93,8 +89,8 @@ fn fall_simple() -> Result<(), Box<dyn Error>> {
/// will fall in 20 x DT and 2 x 10*DT steps. compare the end result and make
/// log the "error" between both calculations
fn fall_dt_speed_diff() -> Result<(), Box<dyn Error>> {
let mut sstate = utils::setup();
let mut fstate = utils::setup();
let mut sstate = utils::setup(utils::add_char_and_phys_systems);
let mut fstate = utils::setup(utils::add_char_and_phys_systems);
let sp1 = utils::create_player(&mut sstate);
let fp1 = utils::create_player(&mut fstate);
@ -142,7 +138,7 @@ fn fall_dt_speed_diff() -> Result<(), Box<dyn Error>> {
#[test]
fn walk_simple() -> Result<(), Box<dyn Error>> {
let mut state = utils::setup();
let mut state = utils::setup(utils::add_char_and_phys_systems);
let p1 = utils::create_player(&mut state);
for _ in 0..100 {
@ -187,7 +183,7 @@ fn walk_simple() -> Result<(), Box<dyn Error>> {
#[test]
fn walk_max() -> Result<(), Box<dyn Error>> {
let mut state = utils::setup();
let mut state = utils::setup(utils::add_char_and_phys_systems);
for x in 2..30 {
utils::generate_chunk(&mut state, Vec2::new(x, 0));
}
@ -220,8 +216,8 @@ fn walk_max() -> Result<(), Box<dyn Error>> {
/// will run in 20 x DT and 2 x 10*DT steps. compare the end result and make
/// log the "error" between both calculations
fn walk_dt_speed_diff() -> Result<(), Box<dyn Error>> {
let mut sstate = utils::setup();
let mut fstate = utils::setup();
let mut sstate = utils::setup(utils::add_char_and_phys_systems);
let mut fstate = utils::setup(utils::add_char_and_phys_systems);
let sp1 = utils::create_player(&mut sstate);
let fp1 = utils::create_player(&mut fstate);
@ -275,7 +271,7 @@ fn walk_dt_speed_diff() -> Result<(), Box<dyn Error>> {
#[test]
fn cant_run_during_fall() -> Result<(), Box<dyn Error>> {
let mut state = utils::setup();
let mut state = utils::setup(utils::add_char_and_phys_systems);
let p1 = utils::create_player(&mut state);
let mut actions = Controller::default();

View File

@ -35,13 +35,14 @@ const DEFAULT_WORLD_CHUNKS_LG: MapSizeLg =
panic!("Default world chunk size does not satisfy required invariants.");
};
pub fn setup() -> State {
pub fn setup(add_systems: impl Fn(&mut specs::DispatcherBuilder)) -> State {
let pools = State::pools(GameMode::Server);
let mut state = State::new(
GameMode::Server,
pools,
DEFAULT_WORLD_CHUNKS_LG,
Arc::new(TerrainChunk::water(0)),
add_systems,
);
state.ecs_mut().insert(MaterialStatManifest::with_empty());
state.ecs_mut().insert(AbilityMap::load().cloned());
@ -55,14 +56,14 @@ pub fn setup() -> State {
state
}
pub fn add_char_and_phys_systems(dispatch_builder: &mut specs::DispatcherBuilder) {
dispatch::<character_behavior::Sys>(dispatch_builder, &[]);
dispatch::<phys::Sys>(dispatch_builder, &[&character_behavior::Sys::sys_name()]);
}
pub fn tick(state: &mut State, dt: Duration) {
state.tick(
dt,
|dispatch_builder| {
dispatch::<character_behavior::Sys>(dispatch_builder, &[]);
dispatch::<phys::Sys>(dispatch_builder, &[&character_behavior::Sys::sys_name()]);
},
false,
None,
&ServerConstants {

View File

@ -27,8 +27,8 @@ use common::{
uid::{IdMaps, Uid},
};
use specs::{
shred::ResourceId, Entities, Entity as EcsEntity, Read, ReadExpect, ReadStorage, SystemData,
World,
shred, Entities, Entity as EcsEntity, Read, ReadExpect, ReadStorage,
SystemData,
};
// TODO: Move rtsim back into AgentData after rtsim2 when it has a separate

View File

@ -306,6 +306,16 @@ impl Server {
pools,
world.sim().map_size_lg(),
Arc::clone(&map.default_chunk),
|dispatcher_builder| {
add_local_systems(dispatcher_builder);
sys::msg::add_server_systems(dispatcher_builder);
sys::add_server_systems(dispatcher_builder);
#[cfg(feature = "worldgen")]
{
rtsim::add_server_systems(dispatcher_builder);
weather::add_server_systems(dispatcher_builder);
}
},
);
state.ecs_mut().insert(battlemode_buffer);
state.ecs_mut().insert(settings.clone());
@ -752,6 +762,7 @@ impl Server {
let mut state_tick_metrics = Default::default();
self.state.tick(
dt,
/*
|dispatcher_builder| {
add_local_systems(dispatcher_builder);
sys::msg::add_server_systems(dispatcher_builder);
@ -762,6 +773,7 @@ impl Server {
weather::add_server_systems(dispatcher_builder);
}
},
*/
false,
Some(&mut state_tick_metrics),
&self.server_constants,

View File

@ -24,8 +24,8 @@ use itertools::Either;
use plugin_api::Health;
use rayon::prelude::*;
use specs::{
shred::ResourceId, Entities, Join, LendJoin, ParJoin, Read, ReadExpect, ReadStorage,
SystemData, World, WriteStorage,
shred, Entities, Join, LendJoin, ParJoin, Read, ReadExpect, ReadStorage, SystemData,
WriteStorage,
};
use tracing::{debug, info, trace, warn};

View File

@ -11,10 +11,7 @@ use common_net::{
sync::{CompSyncPackage, EntityPackage, EntitySyncPackage, NetSync, SyncFrom, UpdateTracker},
};
use hashbrown::HashMap;
use specs::{
shred::ResourceId, Entity as EcsEntity, Join, ReadExpect, ReadStorage, SystemData, World,
WriteExpect,
};
use specs::{shred, Entity as EcsEntity, Join, ReadExpect, ReadStorage, SystemData, WriteExpect};
use vek::*;
/// Always watching

View File

@ -8,8 +8,7 @@ use common_ecs::{Job, Origin, Phase, System};
use common_state::BlockChange;
use hashbrown::HashMap;
use specs::{
shred::ResourceId, Entities, Entity, Join, LendJoin, Read, ReadStorage, SystemData, World,
Write, WriteStorage,
shred, Entities, Entity, Join, LendJoin, Read, ReadStorage, SystemData, Write, WriteStorage,
};
#[derive(SystemData)]

View File

@ -206,11 +206,10 @@ impl PlayState for CharSelectionState {
// Tick the client (currently only to keep the connection alive).
let localized_strings = &global_state.i18n.read();
let res = self.client.borrow_mut().tick(
comp::ControllerInputs::default(),
global_state.clock.dt(),
|_| {},
);
let res = self
.client
.borrow_mut()
.tick(comp::ControllerInputs::default(), global_state.clock.dt());
match res {
Ok(events) => {
for event in events {

View File

@ -85,6 +85,7 @@ impl ClientInit {
&|stage| {
let _ = init_stage_tx.send(stage);
},
crate::ecs::sys::add_local_systems,
)
.await
{

View File

@ -251,11 +251,7 @@ impl PlayState for MainMenuState {
// Tick the client to keep the connection alive if we are waiting on pipelines
if let InitState::Pipeline(client) = &mut self.init {
match client.tick(
comp::ControllerInputs::default(),
global_state.clock.dt(),
|_| {},
) {
match client.tick(comp::ControllerInputs::default(), global_state.clock.dt()) {
Ok(events) => {
for event in events {
match event {

View File

@ -272,7 +272,7 @@ impl SessionState {
self.mumble_link.update(player_pos, player_pos);
}
for event in client.tick(self.inputs.clone(), dt, crate::ecs::sys::add_local_systems)? {
for event in client.tick(self.inputs.clone(), dt)? {
match event {
client::Event::Chat(m) => {
self.hud.new_message(m);