use bevy::app::App;
use bevy::log::{error, warn};
use crate::input_action::InputAction;
use crate::resources::meta_data::{IneffableMetaData, IneffableMetaItem};
pub trait InputActionRegistrar {
fn register_input_action<I: InputAction>(&mut self) -> &mut Self;
}
impl InputActionRegistrar for App {
fn register_input_action<I: InputAction>(&mut self) -> &mut Self {
if !self.world.contains_resource::<IneffableMetaData>() {
self.world.insert_resource(IneffableMetaData::default());
}
let mut resource = self
.world
.get_resource_mut::<IneffableMetaData>()
.expect("Missing resource IneffableMetaData. Try adding the IneffablePlugin first.");
if let Some(previously_registered_group) = resource.group(I::group_id()) {
let conflicting_group = construct_variants_meta_data::<I>();
if &conflicting_group == previously_registered_group {
warn!(
"Tried to register an InputAction more than once. \
You can safely remove the redundant call to `app.register_input_action::<{}>()`",
I::group_id()
);
} else {
error!(
"Tried to register two different InputActions with the same name: `{}`.\n\
\tEach InputAction enum must have a unique name.\n\
\tThis is almost certainly a bug, and may result in input not being read properly.",
I::group_id()
);
}
return self;
}
resource
.map
.insert(I::group_id(), construct_variants_meta_data::<I>());
self
}
}
fn construct_variants_meta_data<I: InputAction>() -> Vec<IneffableMetaItem> {
I::iter()
.map(|action| IneffableMetaItem {
group_id: I::group_id().to_string(),
action_id: action.action_id().to_string(),
kind: action.kind(),
index: action.index(),
})
.collect()
}