input_actions/
lib.rs

1//! input-actions is a Rust crate heavily inspired by Unity library [Rewired](https://assetstore.unity.com/packages/tools/utilities/rewired-21676) ([Website](https://guavaman.com/projects/rewired/)).
2//!
3//! This crate utilizes "gilrs" (which uses "rusty-xinput") to handle gamepad input,
4//! and both of these crates expose potentially spammy levels of logging when devices are connected.
5//! It is recommended you ignore or limit the logging levels of "gilrs" and "rusty_xinput" log targets/modules.
6//! This is being tracked by https://gitlab.com/gilrs-project/gilrs/-/issues/105.
7//!
8//! # Setup
9//! input-actions uses a "set it and forget it" approach to system management.
10//! As long as the system stays active for the lifecycle of the application,
11//! and its [`update`](System::update) is called at regular intervals,
12//! the rest is pretty hands-off.
13//! 
14//! ```rust
15//! let mut input_sys = System::new();
16//! input_sys
17//! 	// There is only 1 player/user to send inputs for.
18//! 	.add_users(1)
19//! 	// These action names are complete up to you.
20//! 	// It is recommended that you store the strings as static properties
21//! 	// so they can be referenced throughout the consuming crate.
22//! 	.add_action("button1", Action::new(Kind::Button))
23//! 	.add_action("button2", Action::new(Kind::Button))
24//! 	.add_action("axis1", Action::new(Kind::Axis))
25//! 	.add_action("axis2", Action::new(Kind::Axis))
26//! 	// This specifies that there is 1 layout (the default layout, which is equivalent to `None`).
27//! 	.add_layout(LayoutId::default())
28//! 	// This adds bindings for each action for a given layout.
29//! 	// The group of bindings per layout is called an "action set".
30//! 	.add_action_set(
31//! 		// This specifies the name of the set. `ActionSetId::default()` is equivalent to `None`.
32//! 		ActionSetId::default(),
33//! 		ActionSet::default().with(
34//! 			// This action set contains 1 layout, the default layout added to the system above.
35//! 			LayoutId::default(),
36//! 			ActionMap::default()
37//! 				.bind(
38//! 					"button1",
39//! 					vec![
40//! 						binding::Source::Keyboard(source::Key::Return).bound(),
41//! 						binding::Source::Keyboard(source::Key::NumpadEnter).bound(),
42//! 						binding::Source::Gamepad(GamepadKind::DualAxisGamepad,
43//! 							binding::Source::Button(source::Button::VirtualConfirm
44//! 						)).bound(),
45//! 					],
46//! 				)
47//! 				.bind(
48//! 					"button2",
49//! 					vec![
50//! 						binding::Source::Keyboard(source::Key::Escape).bound(),
51//! 						binding::Source::Gamepad(GamepadKind::DualAxisGamepad,
52//! 							binding::Source::Button(source::Button::VirtualDeny)
53//! 						).bound(),
54//! 					],
55//! 				)
56//! 				.bind(
57//! 					"axis1",
58//! 					vec![
59//! 						binding::Source::Keyboard(source::Key::W).with_modifier(1.0),
60//! 						binding::Source::Keyboard(source::Key::S).with_modifier(-1.0),
61//! 						binding::Source::Gamepad(GamepadKind::DualAxisGamepad,
62//! 							binding::Source::Axis(source::Axis::LThumbstickX)
63//! 						).bound(),
64//! 					],
65//! 				)
66//! 				.bind(
67//! 					"axis2",
68//! 					vec![
69//! 						binding::Source::Keyboard(source::Key::A).with_modifier(-1.0),
70//! 						binding::Source::Keyboard(source::Key::D).with_modifier(1.0),
71//! 						binding::Source::Gamepad(GamepadKind::DualAxisGamepad,
72//! 							binding::Source::Axis(source::Axis::LThumbstickY)
73//! 						).bound(),
74//! 					],
75//! 				)
76//! 		),
77//! 	)
78//! 	// In order to use action set bindings, the user needs the action set enabled.
79//! 	// This call says "all users should have this action set enabled",
80//! 	// though it is equivalent to `mark_action_set_enabled` since there is only 1 user in this example.
81//! 	.enable_action_set_for_all(ActionSetId::default());
82//! ```
83//! 
84//! From there it is up to you to determine when and how to send the system updates
85//! so it knows what actions are in what state.
86//! 
87//! You should call [`System::update`](System::update) during your update loop
88//! (which will update the state of all actions for all users). This is primarily for
89//! gamepad input polling and updating actions that need simulation.
90//! 
91//! The input-actions system also needs to know about mouse and keyboard input,
92//! which can be supplied by any external source. If you are using [winit](https://crates.io/crates/winit),
93//! you can enable the `winit` feature,
94//! `input-actions = { version = "...", features = ["winit"] }`
95//! and use the code below to sent window-based gameplay events:
96//! ```rust
97//! event_loop.run(move |event, _, _| {
98//! 	if let Ok((source, input_event)) = input::winit::parse_winit_event(&event) {
99//! 		input_sys.send_event(source, input_event);
100//! 	}
101//! }
102//! ```
103//! 
104//! The input-actions system also supports logging via the `log` feature:
105//! `input-actions = { version = "...", features = ["log"] }`
106//! 
107
108#[cfg(feature = "log")]
109extern crate log;
110
111/// Submodule for handling integration with `winit` when the feature is enabled.
112#[cfg(feature = "winit")]
113pub mod winit;
114
115pub static LOG: &'static str = "input-actions";
116pub static DEPENDENCY_LOG_TARGETS: [&'static str; 2] = ["gilrs", "rusty_xinput"];
117
118/// Configuration and state data for handling an action set by consuemrs of input-actions.
119pub mod action;
120
121/// Data for telling input-actions how a device input is mapped to an action.
122pub mod binding;
123
124/// Data pertaining to physical devices (like mice, keyboards, and gamepads) which send input to input-actions.
125pub mod device;
126
127/// Enumerations for differentiating between device inputs (buttons, axes, keys, mouse buttons).
128pub mod source;
129
130/// Data sent to input-actions when device inputs are detected.
131pub mod event;
132
133mod system;
134pub use system::*;
135
136mod user;
137pub(crate) use user::*;