Skip to content

Commit

Permalink
docs(engine): document Input sample
Browse files Browse the repository at this point in the history
  • Loading branch information
DiogoMendonc-a committed Sep 27, 2023
1 parent 3948aad commit c97b77e
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 75 deletions.
1 change: 1 addition & 0 deletions docs/pages/3_examples/2_engine/main.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 2 additions & 0 deletions engine/include/cubos/engine/input/plugin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
34 changes: 0 additions & 34 deletions engine/samples/input/assets/sample.bind
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
62 changes: 21 additions & 41 deletions engine/samples/input/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ using cubos::core::io::Window;

using namespace cubos::engine;

/// [Setting the Bindings]
static const Asset<InputBindings> bindingsAsset = AnyAsset("bf49ba61-5103-41bc-92e0-8a442d7842c3");
/// [Setting the Bindings]

struct State
{
Expand All @@ -31,6 +33,7 @@ static void explain(bool& explained)
}
}

/// [Showcase Action Press]
static void showcaseXZ(const Input& input, bool& explained)
{
if (!explained)
Expand All @@ -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;
}
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -159,10 +136,12 @@ static void showcaseUnbound(const Window& window, bool& explained)
CUBOS_INFO("Unbound");
}
}
/// [Showcase Unbound]

static void update(Read<Input> input, Read<Window> window, Write<State> state, Write<ShouldQuit> 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;
Expand All @@ -173,6 +152,7 @@ static void update(Read<Input> input, Read<Window> window, Write<State> state, W
state->explained = false;
state->showcase++;
}
/// [Checking Type of Press]

switch (state->showcase)
{
Expand All @@ -185,12 +165,10 @@ static void update(Read<Input> input, Read<Window> window, Write<State> 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;
Expand All @@ -213,7 +191,9 @@ int main()
{
auto cubos = Cubos();

/// [Adding the plugin]
cubos.addPlugin(inputPlugin);
/// [Adding the plugin]

cubos.addResource<State>();

Expand Down
72 changes: 72 additions & 0 deletions engine/samples/input/page.md
Original file line number Diff line number Diff line change
@@ -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.

0 comments on commit c97b77e

Please sign in to comment.