253 lines
5.7 KiB
Rust
253 lines
5.7 KiB
Rust
|
use std::{collections::HashMap, cell::RefCell, borrow::BorrowMut};
|
||
|
|
||
|
use edict::action;
|
||
|
|
||
|
use crate::castable_any::CastableAny;
|
||
|
|
||
|
use super::{Button, KeyCode};
|
||
|
|
||
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||
|
enum GamepadFormat {
|
||
|
DualAxis,
|
||
|
Joystick,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||
|
enum GamepadButton {
|
||
|
FaceBottom,
|
||
|
FaceLeft,
|
||
|
FaceRight,
|
||
|
FaceTop,
|
||
|
VirtualConfirm,
|
||
|
VirtualDeny,
|
||
|
LThumbstick,
|
||
|
RThumbstick,
|
||
|
DPadUp,
|
||
|
DPadDown,
|
||
|
DPadLeft,
|
||
|
DPadRight,
|
||
|
LShoulder,
|
||
|
RShoulder,
|
||
|
LTrigger,
|
||
|
RTrigger,
|
||
|
Special,
|
||
|
LSpecial,
|
||
|
RSpecial,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||
|
enum GamepadAxis {
|
||
|
LThumbstickX,
|
||
|
LThumbstickY,
|
||
|
RThumbstickX,
|
||
|
RThumbstickY,
|
||
|
LTrigger,
|
||
|
RTrigger,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||
|
enum GamepadInput {
|
||
|
Button(GamepadButton),
|
||
|
Axis(GamepadAxis),
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||
|
pub enum ActionSource {
|
||
|
Keyboard(KeyCode),
|
||
|
Gamepad(GamepadFormat, GamepadInput),
|
||
|
}
|
||
|
|
||
|
impl ActionSource {
|
||
|
/// Convert this Source into a Binding. Uses a default Binding modifier value of `1.0`.
|
||
|
pub fn into_binding(self) -> Binding {
|
||
|
Binding::from_source(self)
|
||
|
}
|
||
|
|
||
|
/// Convert this Source into a Binding, setting the modifier.
|
||
|
pub fn into_binding_modifier(self, modifier: f32) -> Binding {
|
||
|
Binding::from_source_modifier(self, modifier)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Clone, Debug)]
|
||
|
pub struct Binding {
|
||
|
pub source: ActionSource,
|
||
|
pub modifier: f32,
|
||
|
}
|
||
|
|
||
|
impl Binding {
|
||
|
/// Create a binding from a Source. Uses a default value of `1.0` as the modifier.
|
||
|
pub fn from_source(source: ActionSource) -> Self {
|
||
|
Self {
|
||
|
source,
|
||
|
modifier: 1.0,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Create a binding from a Source, with a modifier
|
||
|
pub fn from_source_modifier(source: ActionSource, modifier: f32) -> Self {
|
||
|
Self {
|
||
|
source,
|
||
|
modifier,
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||
|
pub enum ActionKind {
|
||
|
Button,
|
||
|
Axis
|
||
|
}
|
||
|
|
||
|
#[derive(Clone, Debug)]
|
||
|
pub struct Action {
|
||
|
kind: ActionKind,
|
||
|
}
|
||
|
|
||
|
impl Action {
|
||
|
pub fn new(kind: ActionKind) -> Self {
|
||
|
Self {
|
||
|
kind,
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||
|
pub struct LayoutId(u32);
|
||
|
|
||
|
impl From<u32> for LayoutId {
|
||
|
fn from(value: u32) -> Self {
|
||
|
Self(value)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl Default for LayoutId {
|
||
|
fn default() -> Self {
|
||
|
Self(0)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Clone)]
|
||
|
pub struct Layout {
|
||
|
mappings: HashMap<ActionMappingId, ActionMapping>,
|
||
|
}
|
||
|
|
||
|
impl Layout {
|
||
|
pub fn new() -> Self {
|
||
|
Self {
|
||
|
mappings: HashMap::new(),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn add_mapping(&mut self, mapping: ActionMapping) -> &mut Self {
|
||
|
self.mappings.insert(mapping.id, mapping);
|
||
|
|
||
|
self
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||
|
pub struct ActionMappingId(u32);
|
||
|
|
||
|
impl From<u32> for ActionMappingId {
|
||
|
fn from(value: u32) -> Self {
|
||
|
Self(value)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl Default for ActionMappingId {
|
||
|
fn default() -> Self {
|
||
|
Self(0)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Clone)]
|
||
|
pub struct ActionMapping {
|
||
|
layout: LayoutId,
|
||
|
id: ActionMappingId,
|
||
|
action_binds: HashMap<String, Vec<Binding>>,
|
||
|
}
|
||
|
|
||
|
impl ActionMapping {
|
||
|
pub fn new(layout: LayoutId, id: ActionMappingId) -> Self {
|
||
|
Self {
|
||
|
layout,
|
||
|
id,
|
||
|
action_binds: HashMap::new(),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Creates a binding for the action.
|
||
|
///
|
||
|
/// If the action is not in this layout, this will panic!
|
||
|
///
|
||
|
/// Parameters:
|
||
|
/// * `action_label` - The label corresponding to the action in this Layout.
|
||
|
/// * `bind` - The Binding to add to the Action.
|
||
|
pub fn bind(mut self, action_label: &str, bindings: &[Binding]) -> Self {
|
||
|
let mut bindings = bindings.to_vec();
|
||
|
|
||
|
let action_binds = self.action_binds.entry(action_label.to_string())
|
||
|
.or_insert_with(|| Vec::new());
|
||
|
action_binds.append(&mut bindings);
|
||
|
|
||
|
self
|
||
|
}
|
||
|
|
||
|
/// Creates multiple binding for the action.
|
||
|
///
|
||
|
/// If the action is not in this layout, this will panic!
|
||
|
///
|
||
|
/// Parameters:
|
||
|
/// * `action_label` - The label corresponding to the action in this Layout.
|
||
|
/// * `bindings` - The list of Bindings to add to the Action.
|
||
|
/* pub fn add_bindings(&mut self, action_label: String, bindings: &[Binding]) -> &mut Self {
|
||
|
let mut bindings = bindings.to_vec();
|
||
|
let action_binds = self.action_binds.entry(action_label)
|
||
|
.or_insert_with(|| Vec::new());
|
||
|
action_binds.append(&mut bindings);
|
||
|
|
||
|
self
|
||
|
} */
|
||
|
|
||
|
pub fn finish(self) -> Self {
|
||
|
self
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub struct ActionHandler {
|
||
|
actions: HashMap<String, Action>,
|
||
|
layouts: HashMap<LayoutId, Layout>,
|
||
|
current_layout: LayoutId,
|
||
|
}
|
||
|
|
||
|
impl ActionHandler {
|
||
|
pub fn new() -> Self {
|
||
|
Self {
|
||
|
actions: HashMap::new(),
|
||
|
layouts: HashMap::new(),
|
||
|
current_layout: LayoutId::default(),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn add_layout(&mut self, id: LayoutId) -> &mut Self {
|
||
|
self.layouts.insert(id, Layout::new());
|
||
|
|
||
|
self
|
||
|
}
|
||
|
|
||
|
pub fn add_action(&mut self, label: &str, action: Action) -> &mut Self {
|
||
|
/* let layout = self.layouts.get_mut(&layout_id).unwrap();
|
||
|
layout.actions.insert(label.to_string(), action); */
|
||
|
self.actions.insert(label.to_string(), action);
|
||
|
|
||
|
self
|
||
|
}
|
||
|
|
||
|
pub fn add_mapping(&mut self, mapping: ActionMapping) -> &mut Self {
|
||
|
let layout = self.layouts.get_mut(&mapping.layout).unwrap();
|
||
|
layout.add_mapping(mapping);
|
||
|
|
||
|
self
|
||
|
}
|
||
|
}
|