From c97b77e54daae42123db3ab250dd737d5fb3923c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diogo=20Mendon=C3=A7a?= Date: Mon, 25 Sep 2023 10:41:49 +0100 Subject: [PATCH] docs(engine): document Input sample --- docs/pages/3_examples/2_engine/main.md | 1 + engine/include/cubos/engine/input/plugin.hpp | 2 + engine/samples/input/assets/sample.bind | 34 --------- engine/samples/input/main.cpp | 62 ++++++----------- engine/samples/input/page.md | 72 ++++++++++++++++++++ 5 files changed, 96 insertions(+), 75 deletions(-) create mode 100644 engine/samples/input/page.md diff --git a/docs/pages/3_examples/2_engine/main.md b/docs/pages/3_examples/2_engine/main.md index f395d8e407..0069b7108a 100644 --- a/docs/pages/3_examples/2_engine/main.md +++ b/docs/pages/3_examples/2_engine/main.md @@ -7,4 +7,5 @@ multiple plugins of the engine: - @subpage examples-engine-settings - @copybrief examples-engine-settings - @subpage examples-engine-renderer - @copybrief examples-engine-renderer +- @subpage examples-engine-input - @copybrief examples-engine-input - @subpage examples-engine-scene - @copybrief examples-engine-scene \ No newline at end of file diff --git a/engine/include/cubos/engine/input/plugin.hpp b/engine/include/cubos/engine/input/plugin.hpp index 954276e61f..9d32f86d1c 100644 --- a/engine/include/cubos/engine/input/plugin.hpp +++ b/engine/include/cubos/engine/input/plugin.hpp @@ -15,6 +15,8 @@ namespace cubos::engine /// @defgroup input-plugin Input /// @ingroup engine /// @brief Adds input handling to @b CUBOS. + /// @see Take a look at the @ref examples-engine-input example for a demonstration of this + /// plugin. /// /// ## Bridges /// - @ref JSONBridge - registered with the `.bind` extension, loads @ref InputBindings assets. diff --git a/engine/samples/input/assets/sample.bind b/engine/samples/input/assets/sample.bind index 4ca23be2aa..7a67124891 100644 --- a/engine/samples/input/assets/sample.bind +++ b/engine/samples/input/assets/sample.bind @@ -21,46 +21,12 @@ ], "gamepad": [] }, - "alt-space": { - "keys": [ - "M-Space" - ], - "gamepad": [] - }, - "ctrl-space": { - "keys": [ - "C-Space" - ], - "gamepad": [] - }, - "system-space": { - "keys": [ - "D-Space" - ], - "gamepad": [] - }, "ctrl-shift-space": { "keys": [ "C-S-Space" ], "gamepad": [] }, - "ctrl": { - "keys": [ - "LControl", - "RControl" - ], - "gamepad": [] - }, - "ctrl-shift": { - "keys": [ - "C-LShift", - "C-RShift", - "S-LControl", - "S-RControl" - ], - "gamepad": [] - } }, "axes": { "vertical": { diff --git a/engine/samples/input/main.cpp b/engine/samples/input/main.cpp index bfdf270b56..b59ad42b92 100644 --- a/engine/samples/input/main.cpp +++ b/engine/samples/input/main.cpp @@ -12,7 +12,9 @@ using cubos::core::io::Window; using namespace cubos::engine; +/// [Setting the Bindings] static const Asset bindingsAsset = AnyAsset("bf49ba61-5103-41bc-92e0-8a442d7842c3"); +/// [Setting the Bindings] struct State { @@ -31,6 +33,7 @@ static void explain(bool& explained) } } +/// [Showcase Action Press] static void showcaseXZ(const Input& input, bool& explained) { if (!explained) @@ -45,13 +48,14 @@ static void showcaseXZ(const Input& input, bool& explained) CUBOS_INFO("X or Z"); } } +/// [Showcase Action Press] +/// [Showcase Modifier] static void showcaseModifiers(const Input& input, bool& explained) { if (!explained) { - CUBOS_WARN("Modifiers are supported. This showcase will print `Shift` when Shift+Space is pressed, `Alt` when " - "Alt+Space is pressed, `Ctrl` when Ctrl+Space is pressed and `System` when System+Space is pressed. " + CUBOS_WARN("Modifiers are supported. This showcase will print `Shift` when Shift+Space is pressed. " "Press Enter to advance to the next showcase."); explained = true; } @@ -60,23 +64,10 @@ static void showcaseModifiers(const Input& input, bool& explained) { CUBOS_INFO("Shift"); } - - if (input.pressed("alt-space")) - { - CUBOS_INFO("Alt"); - } - - if (input.pressed("ctrl-space")) - { - CUBOS_INFO("Ctrl"); - } - - if (input.pressed("system-space")) - { - CUBOS_INFO("System"); - } } +/// [Showcase Modifier] +/// [Showcase Multi Modifier] static void showcaseMultipleModifiers(const Input& input, bool& explained) { if (!explained) @@ -91,27 +82,9 @@ static void showcaseMultipleModifiers(const Input& input, bool& explained) CUBOS_INFO("Ctrl Shift"); } } +/// [Showcase Multi Modifier] -static void showcaseModifierKeys(const Input& input, bool& explained) -{ - if (!explained) - { - CUBOS_WARN("Modifier keys are supported. This showcase will print `Ctrl` when Ctrl is pressed and `Ctrl Shift` " - "when Ctrl+Shift is pressed. Press Enter to advance to the next showcase."); - explained = true; - } - - if (input.pressed("ctrl")) - { - CUBOS_INFO("Ctrl"); - } - - if (input.pressed("ctrl-shift")) - { - CUBOS_INFO("Ctrl Shift"); - } -} - +/// [Showcase Axis] static void showcaseAxis(const Input& input, bool& explained) { if (!explained) @@ -127,7 +100,9 @@ static void showcaseAxis(const Input& input, bool& explained) CUBOS_INFO("horizontal: {}, vertical: {}", input.axis("horizontal"), input.axis("vertical")); } } +/// [Showcase Axis] +/// [Showcase Modifier Axis] static void showcaseModifierAxis(const Input& input, bool& explained) { if (!explained) @@ -143,7 +118,9 @@ static void showcaseModifierAxis(const Input& input, bool& explained) CUBOS_INFO("shift-vertical: {}", input.axis("shift-vertical")); } } +/// [Showcase Modifier Axis] +/// [Showcase Unbound] static void showcaseUnbound(const Window& window, bool& explained) { if (!explained) @@ -159,10 +136,12 @@ static void showcaseUnbound(const Window& window, bool& explained) CUBOS_INFO("Unbound"); } } +/// [Showcase Unbound] static void update(Read input, Read window, Write state, Write shouldQuit) { // FIXME: This is an hack to have one-shot actions while we don't have input events. + /// [Checking Type of Press] if (input->pressed("next-showcase")) { state->nextPressed = true; @@ -173,6 +152,7 @@ static void update(Read input, Read window, Write state, W state->explained = false; state->showcase++; } + /// [Checking Type of Press] switch (state->showcase) { @@ -185,12 +165,10 @@ static void update(Read input, Read window, Write state, W case 3: return showcaseMultipleModifiers(*input, state->explained); case 4: - return showcaseModifierKeys(*input, state->explained); - case 5: return showcaseAxis(*input, state->explained); - case 6: + case 5: return showcaseModifierAxis(*input, state->explained); - case 7: + case 6: return showcaseUnbound(*window, state->explained); default: shouldQuit->value = true; @@ -213,7 +191,9 @@ int main() { auto cubos = Cubos(); + /// [Adding the plugin] cubos.addPlugin(inputPlugin); + /// [Adding the plugin] cubos.addResource(); diff --git a/engine/samples/input/page.md b/engine/samples/input/page.md new file mode 100644 index 0000000000..2a546a128e --- /dev/null +++ b/engine/samples/input/page.md @@ -0,0 +1,72 @@ +# Input {#examples-engine-input} + +@brief Using the @ref input-plugin plugin. + +This example shows how the @ref scene-input plugin can be used to handle user input. + +The plugin function is included from the @ref engine/input/plugin.hpp header. + +@snippet input/main.cpp Adding the plugin + +The Input plugin requires a @ref cubos::engine::InputBindings "InputBindings" asset to be set. +Let's take a look at the file the sample uses. + +@include assets/sample.bind + +There are two types of bindings: `actions` and `axes`. +An `action` is an input that only has two states: pressed or not pressed. +This would be most keys on a keyboard. +An `axe` is an input that has a numeric value. +For example, the joysticks on a controller can go from -1 to 1, depending on how much they are tilt in which direction. +Using `axes` can also be useful for keys with symetric behaviour. +For example, in this sample, `w` sets the `vertical` axe to 1, while `s` sets it to -1. + +To define an action or an axe, you simply have to add it to the respective list, giving it a name. +The very first action in the file is called `next-showcase`. +Then, if it's an action, you simply have to define which keys trigger it. +You can also define key combinations by using a `-`. +To check which strings map to which keys, you check the `keyToString` function implementation on [this file](https://github.com/GameDevTecnico/cubos/blob/main/core/src/cubos/core/io/keyboard.cpp). + +Now that we have our bindings file, let's get our application to do something with it. +The first thing we're going to need is a reference to the bindings asset. +For the purposes of this sample we can simply use an hardcoded reference to the asset. + +@snippet input/main.cpp Setting the Bindings + +What this sample does is show in order, a series of prompt to showcase the different functionalities of the Input plugin. +For this, it keeps a `state` integer that indicates the current prompt. +Whenever the action `next-showcase` is triggered, it advances to the next prompt. +However, as the plugin currently does not have events, we have to manually check whether the key has just been pressed, is being pressed continuously, or was just released. + +@snippet input/main.cpp Checking Type of Press + +What this does is only advance the state when the return key is released. +This avoids the state advancing more than once if the user presses it for more than one frame. + +Now let's see each of the prompt, to understand the full breadth of the plugin's functionalities. + +@snippet input/main.cpp Showcase Action Press + +Finding out whether the user is pressing a key is checked by a simple call to @ref cubos::engine::Input::pressed "Input::pressed". + +@snippet input/main.cpp Showcase Modifier + +Getting modified input (such as with a `CTRL` or a `SHIFT` hold) is no different from getting non-modified input, just make sure the binding for it is defined in the Bindings asset. + +@snippet input/main.cpp Showcase Multi Modifier + +You can have more than one modifier. + +@snippet input/main.cpp Showcase Axis + +Getting axis is very similar to actions, by calling @ref cubos::engine::Input::axis "Input::axis". +The difference is that this funtion returns a float instead of a boolean value. + +@snippet input/main.cpp Showcase Modifier Axis + +Modifier keys work with axis too. + +@snippet input/main.cpp Showcase Unbound + +If, for any reason, you want to read an input that is not defined in the Bindings asset, you cannot use the Input plugin for it. +Instead, you will have to call the @ref cubos::core::io::Window::pressed "Window::pressed" function.