-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcommands.rs
105 lines (99 loc) · 4.47 KB
/
commands.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//! Contains the `SystemParam` that systems can use to set `InputConfig`s.
use bevy::asset::{AssetPath, AssetServer};
use bevy::ecs::system::SystemParam;
use bevy::prelude::{Commands, Res, ResMut};
use crate::config::simple_asset_loading::{CurrentlyLoading, MergeMode};
use crate::config::InputConfig;
use crate::prelude::Ineffable;
use crate::processed::bound_action::BoundAction;
use crate::processed::processor::{collect_inputs, validate};
use crate::reporting::InputConfigReport;
use crate::resources::ineffable_settings::IneffableSettings;
use crate::resources::meta_data::IneffableMetaData;
/// Use this as a system parameter to validate and set `InputConfig`s.
///
/// # Examples
///
/// ```
/// # use bevy_ineffable::config::InputConfig;
/// # use bevy_ineffable::prelude::IneffableCommands;
/// pub fn system(mut commands: IneffableCommands) {
/// let config = InputConfig::default();
/// // You can validate the config, to obtain a report:
/// let report = commands.validate(&config);
/// // You can set the config, which automatically generates a report,
/// // dumps it to the log and returns it:
/// let report = commands.set_config(&config);
/// // You can set the config silently, which does not perform
/// // validation and does not write to the log:
/// commands.set_config_silent(&config);
/// }
/// ```
#[allow(missing_debug_implementations)]
#[derive(SystemParam)]
pub struct IneffableCommands<'w, 's> {
commands: Commands<'w, 's>,
/// Contains information about action groups and `InputAction`s, and which `InputKind`s they are.
/// Used to validate the config.
meta_data: Res<'w, IneffableMetaData>,
processed_actions: ResMut<'w, Ineffable>,
settings: ResMut<'w, IneffableSettings>,
asset_server: Res<'w, AssetServer>,
}
impl IneffableCommands<'_, '_> {
/// Scan the given `InputConfig` and check for errors. Compiles and returns a report of all the problems it finds.
///
/// This is most useful when loading and merging multiple configs. This function allows you to generate a report
/// for each config, before merging them, and give feedback to your players specifically about their custom config.
#[must_use]
pub fn validate(&self, config: &InputConfig) -> InputConfigReport {
validate(&self.meta_data, config)
}
/// Sets the new `InputConfig`.
///
/// This overrides any `InputConfig`s that were set before. To use settings from multiple configs at the same time,
/// first merge them and then set the merged config.
///
/// This function also automatically generates a report and dumps it to the log. If you don't want it to do that,
/// use `set_config_silent()` instead.
pub fn set_config(&mut self, config: &InputConfig) -> InputConfigReport {
let report = self.validate(config);
report.dump_to_log();
self.set_config_silent(config);
report
}
/// Sets the new `InputConfig`.
///
/// This overrides any `InputConfig`s that were set before. To use settings from multiple configs at the same time,
/// first merge them and then set the merged config.
///
/// Consider using `set_config()` instead, for it will warn you if you make a mistake with your
/// keybinding configuration. This function will silently swallow any bugs.
pub fn set_config_silent(&mut self, config: &InputConfig) {
let helper = collect_inputs(&self.meta_data, config);
self.processed_actions.groups = config
.bindings
.iter()
.filter(|(group_id, _)| self.meta_data.group_exists(group_id))
.map(|(group_id, group_data)| {
let mut bound_actions = Vec::new();
for meta in self.meta_data.actions(group_id) {
if let Some(action) = group_data.get(&meta.action_id) {
bound_actions.push(BoundAction::new(meta, action, &helper));
} else {
bound_actions.push(BoundAction::new(meta, &[], &helper));
}
}
(group_id.clone(), bound_actions)
})
.collect();
self.settings.set(config);
}
pub fn load_configs<'a>(&mut self, mut paths: Vec<(MergeMode, impl Into<AssetPath<'a>>)>) {
let handles = paths
.drain(..)
.map(|(merge_mode, path)| (merge_mode, self.asset_server.load(path)))
.collect();
self.commands.insert_resource(CurrentlyLoading { handles });
}
}