3#include "structure/math/spk_vector2.hpp"
4#include "structure/system/device/spk_keyboard.hpp"
5#include "structure/system/device/spk_mouse.hpp"
6#include "structure/system/event/spk_update_event.hpp"
7#include "structure/system/time/spk_duration.hpp"
8#include "structure/system/time/spk_timer.hpp"
9#include "type/spk_input_state.hpp"
47 template <
typename Device,
typename DeviceValue>
52 using Job = std::function<void(
const Device *)>;
59 const Device *_device =
nullptr;
61 DeviceValue _deviceValue;
62 spk::InputState _targetState;
66 Job _onTriggerCallback;
71 bool _lastState =
false;
98 _deviceValue(p_deviceValue),
99 _targetState(p_state),
100 _repeatInterval(p_repeatInterval),
101 _timer(p_repeatInterval),
102 _onTriggerCallback(p_jobCallback),
103 _predicateCallback(p_predicateCallback)
112 void setDeviceValue(
const DeviceValue &p_deviceValue,
const spk::InputState &p_state)
114 _deviceValue = p_deviceValue;
115 _targetState = p_state;
124 _repeatInterval = p_repeatInterval;
134 _onTriggerCallback = p_callback;
143 _predicateCallback = p_callback ? std::move(p_callback) :
Predicate{[]() {
154 return (_device !=
nullptr);
163 if constexpr (std::is_same_v<Device, spk::Mouse>)
165 _device = p_event.
mouse;
167 else if constexpr (std::is_same_v<Device, spk::Keyboard>)
173 throw std::runtime_error(
"Invalid device type");
198 if (_device ==
nullptr)
200 throw std::runtime_error(
"Can't update a DeviceInputTrigger without device");
203 spk::InputState currentState = (*_device)[_deviceValue];
205 bool needTrigger = (currentState == _targetState);
207 bool justPressed = needTrigger && _lastState ==
false;
208 _lastState = needTrigger;
210 const bool shouldFire = _predicateCallback() &&
211 (justPressed ==
true ||
212 (justPressed ==
false && needTrigger && _repeatInterval >=
spk::Duration(0, spk::TimeUnit::Nanosecond) && _timer.state() != spk::Timer::State::Running));
214 if (shouldFire ==
true)
216 _onTriggerCallback(_device);
218 if (_repeatInterval >
spk::Duration(0, spk::TimeUnit::Nanosecond))
226 using KeyboardInputTrigger = DeviceInputTrigger<spk::Keyboard, spk::Keyboard::Key>;
227 using MouseButtonInputTrigger = DeviceInputTrigger<spk::Mouse, spk::Mouse::Button>;
247 std::function<void(
const spk::Vector2Int &)> _onTriggerCallback;
258 _onTriggerCallback(p_callback),
270 return (_mouse !=
nullptr);
279 _mouse = p_event.
mouse;
303 if (_mouse ==
nullptr)
305 throw std::runtime_error(
"Can't update a MouseMotionTrigger without device");
308 _onTriggerCallback(_mode == Mode::Absolute ? _mouse->position : _mouse->deltaPosition);
Strongly-typed time span with cached conversions between ns/ms/s.
Definition spk_duration.hpp:15
void update() override
Updates the trigger and fires the callback.
Definition spk_input_trigger.hpp:301
Mode
Mouse motion mode to report.
Definition spk_input_trigger.hpp:241
void setMouse(const spk::Mouse *p_mouse)
Manually sets the mouse.
Definition spk_input_trigger.hpp:295
bool isInitialized() const override
Reports whether the trigger is initialized.
Definition spk_input_trigger.hpp:268
void initialize(spk::UpdateEvent &p_event) override
Initializes the trigger by extracting the mouse from an update event.
Definition spk_input_trigger.hpp:277
MouseMotionTrigger(Mode p_mode, const std::function< void(const spk::Vector2Int &)> &p_callback)
Creates a mouse motion trigger.
Definition spk_input_trigger.hpp:257
const spk::Mouse * mouse() const
Returns the assigned mouse.
Definition spk_input_trigger.hpp:286
Countdown helper tracking elapsed ratio and timeout state.
Definition spk_timer.hpp:24
Captures mouse state at a given instant (buttons, position, wheel).
Definition spk_mouse.hpp:17
Carries per-frame update timing and input state snapshot.
Definition spk_update_event.hpp:15
const spk::Mouse * mouse
Snapshot of the mouse state for the frame.
Definition spk_update_event.hpp:19
const spk::Keyboard * keyboard
Snapshot of the keyboard state for the frame.
Definition spk_update_event.hpp:21