You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
4.1 KiB
Rust
133 lines
4.1 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
use std::collections::HashMap;
|
|
use crate::types::{InputCause, InputTypeFlags, ProcessingResult};
|
|
|
|
pub mod types;
|
|
|
|
|
|
// error out specifically if no backend is chosen
|
|
#[cfg(not(any(feature="backend_piston", feature="backend_gilrs")))]
|
|
compile_error!("No backend selected, use features=<backend> in Cargo.toml or --features <backend> when building directly.");
|
|
|
|
#[cfg(feature="backend_piston")]
|
|
pub mod backend_piston;
|
|
#[cfg(feature="backend_gilrs")]
|
|
pub mod backend_gilrs;
|
|
|
|
#[cfg(test)]
|
|
mod tests;
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
#[serde(transparent)]
|
|
struct EventType(u128);
|
|
|
|
impl EventType
|
|
{
|
|
fn new(rt: u64, rv: u64) -> Self {
|
|
EventType {
|
|
0: (rt as u128).rotate_left(64) + u128::from(rv)
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Converts backend events to more "generic" and serializable
|
|
/// event types. This usually means stripping down needless data
|
|
/// and making the result small (u64). For example, for keyboard key mapping
|
|
/// we only care about the event's "identifier" for the key and it's state (pressed/released)
|
|
/// If there's more info in the backend event we discard that as it could be tied to the
|
|
/// instance rather than the "type of input" such as event_id sequence or such.
|
|
/// This should be typically implemented by the prongs-backend-<name> sub-cargos.
|
|
trait ToEventType<TControllerID>
|
|
where TControllerID: Copy + PartialEq + Serialize
|
|
{
|
|
fn to_raw(&self) -> Option<EventType>;
|
|
|
|
fn controller_id(&self) -> Option<TControllerID>;
|
|
|
|
fn filter_for_assignment(&self, iaf: InputTypeFlags) -> bool;
|
|
|
|
fn get_cause(&self) -> Option<InputCause>;
|
|
}
|
|
|
|
type KeyMap<TUserAction> = HashMap<EventType, TUserAction>;
|
|
|
|
const TYPICAL_MAPPING_SIZE: usize = 255;
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
struct Schema<TEventType, TControllerID, TUserAction>
|
|
where TEventType: ToEventType<TControllerID>,
|
|
TControllerID: Copy + PartialEq + Serialize,
|
|
TUserAction: Clone + Serialize,
|
|
{
|
|
name: String,
|
|
player_id: Option<usize>,
|
|
controller_id: Option<TControllerID>,
|
|
keymap: KeyMap<TUserAction>,
|
|
|
|
#[serde(skip)]
|
|
_phantom: std::marker::PhantomData<TEventType>,
|
|
}
|
|
|
|
impl<TEventType, TControllerID, TUserAction> Schema<TEventType, TControllerID, TUserAction>
|
|
where TEventType: ToEventType<TControllerID>,
|
|
TControllerID: Copy + PartialEq + Serialize,
|
|
TUserAction: Clone + Serialize,
|
|
{
|
|
fn new(name: &str) -> Self {
|
|
Schema {
|
|
name: name.to_string(),
|
|
keymap: KeyMap::with_capacity(TYPICAL_MAPPING_SIZE),
|
|
player_id: None,
|
|
controller_id: None,
|
|
_phantom: std::marker::PhantomData,
|
|
}
|
|
}
|
|
|
|
fn assign_controller(&mut self, event: &TEventType, iaf: InputTypeFlags) -> bool {
|
|
let event_controller_id = event.controller_id();
|
|
|
|
if event_controller_id != self.controller_id
|
|
&& event_controller_id.is_some()
|
|
&& event.filter_for_assignment(iaf) {
|
|
self.controller_id = event.controller_id();
|
|
return true
|
|
}
|
|
|
|
false
|
|
}
|
|
|
|
fn assign_input(&mut self, event: &TEventType, action: TUserAction, iaf: InputTypeFlags) -> bool {
|
|
if event.filter_for_assignment(iaf) {
|
|
if let Some(event_type) = event.to_raw() {
|
|
self.keymap.insert(event_type, action);
|
|
self.assign_controller(event, iaf);
|
|
return true
|
|
}
|
|
}
|
|
|
|
false
|
|
}
|
|
|
|
fn process_event(&mut self, event: &TEventType) -> Option<ProcessingResult<TUserAction>> {
|
|
if let Some(event_type) = event.to_raw() {
|
|
if let Some(action) = self.keymap.get(&event_type) {
|
|
if self.controller_id.is_some() && self.controller_id != event.controller_id() {
|
|
return None
|
|
}
|
|
|
|
return Some(ProcessingResult {
|
|
action: action.clone(),
|
|
player_id: self.player_id,
|
|
cause: event.get_cause(),
|
|
});
|
|
}
|
|
}
|
|
|
|
None
|
|
}
|
|
|
|
fn set_player_id(&mut self, player_id: Option<usize>) {
|
|
self.player_id = player_id;
|
|
}
|
|
}
|