Files
kaizen/lib/include/gainput/GainputInputDevice.h
Simone 4e42229bdd Squashed 'external/gainput/' content from commit 2be0a50
git-subtree-dir: external/gainput
git-subtree-split: 2be0a50089eafcc6fccb66142180082e48f27f4c
2024-01-22 08:51:55 +01:00

272 lines
9.2 KiB
C++

#ifndef GAINPUTINPUTDEVICE_H_
#define GAINPUTINPUTDEVICE_H_
namespace gainput
{
/// Type of an input device button.
enum ButtonType
{
BT_BOOL, ///< A boolean value button, either down (true) or up (false).
BT_FLOAT, ///< A floating-point value button, between -1.0f and 1.0f or 0.0f and 1.0f.
BT_COUNT ///< The number of different button types.
};
/// Interface for anything that provides device inputs.
/**
* An InputDevice can be anything from a physical device, like a mouse or keyboard, to the more abstract
* concept of gestures that in turn themselves depend on other InputDevices. What they have in common is
* that they provide a number of device buttons (identified by a DeviceButtonId) which can be queried for
* their state.
*
* Note that you may not instantiate an InputDevice (or any derived implementation) directly. Instead you
* have to call InputManager::CreateDevice() or InputManager::CreateAndGetDevice() with the device you want
* to instantiate as the template parameter. That way the device will be properly registered with the
* InputManager and continuously updated.
*
* Normally, you won't interact with an InputDevice directly, but instead use its device ID and its device
* buttons' IDs to map the device buttons to user buttons (see InputMap).
*/
class GAINPUT_LIBEXPORT InputDevice
{
public:
/// Type of an input device.
enum DeviceType
{
DT_MOUSE, ///< A mouse/cursor input device featuring one pointer.
DT_KEYBOARD, ///< A keyboard input device.
DT_PAD, ///< A joypad/gamepad input device.
DT_TOUCH, ///< A touch-sensitive input device supporting multiple simultaneous pointers.
DT_BUILTIN, ///< Any controls directly built into the device that also contains the screen.
DT_REMOTE, ///< A generic networked input device.
DT_GESTURE, ///< A gesture input device, building on top of other input devices.
DT_CUSTOM, ///< A custom, user-created input device.
DT_COUNT ///< The count of input device types.
};
/// Variant of an input device type.
enum DeviceVariant
{
DV_STANDARD, ///< The standard implementation of the given device type.
DV_RAW, ///< The raw input implementation of the given device type.
DV_NULL ///< The null/empty implementation of the given device type.
};
/// State of an input device.
enum DeviceState
{
DS_OK, ///< Everything is okay.
DS_LOW_BATTERY, ///< The input device is low on battery.
DS_UNAVAILABLE ///< The input device is currently not available.
};
static const unsigned AutoIndex = unsigned(-1);
/// Initializes the input device.
/**
* Do not instantiate any input device directly. Call InputManager::CreateDevice() instead.
*/
InputDevice(InputManager& manager, DeviceId device, unsigned index);
/// Empty virtual destructor.
virtual ~InputDevice();
/// Update this device, internally called by InputManager.
/**
* \param delta The delta state to add changes to. May be 0.
*/
void Update(InputDeltaState* delta);
/// Returns this device's ID.
DeviceId GetDeviceId() const { return deviceId_; }
/// Returns the device's index among devices of the same type.
unsigned GetIndex() const { return index_; }
/// Returns the device type.
virtual DeviceType GetType() const = 0;
/// Returns the device variant.
virtual DeviceVariant GetVariant() const { return DV_STANDARD; }
/// Returns the device type's name.
virtual const char* GetTypeName() const = 0;
/// Returns if this device should be updated after other devices.
virtual bool IsLateUpdate() const { return false; }
/// Returns the device state.
DeviceState GetState() const;
/// Returns if this device is available.
virtual bool IsAvailable() const { return GetState() == DS_OK || GetState() == DS_LOW_BATTERY; }
/// Returns if the given button is valid for this device.
virtual bool IsValidButtonId(DeviceButtonId deviceButton) const = 0;
/// Returns the current state of the given button.
bool GetBool(DeviceButtonId deviceButton) const;
/// Returns the previous state of the given button.
bool GetBoolPrevious(DeviceButtonId deviceButton) const;
/// Returns the current state of the given button.
float GetFloat(DeviceButtonId deviceButton) const;
/// Returns the previous state of the given button.
float GetFloatPrevious(DeviceButtonId deviceButton) const;
/// Checks if any button on this device is down.
/**
* \param[out] outButtons An array with maxButtonCount fields to receive the device buttons that are down.
* \param maxButtonCount The number of fields in outButtons.
* \return The number of device buttons written to outButtons.
*/
virtual size_t GetAnyButtonDown(DeviceButtonSpec* outButtons, size_t maxButtonCount) const { GAINPUT_UNUSED(outButtons); GAINPUT_UNUSED(maxButtonCount); return 0; }
/// Gets the name of the given button.
/**
* \param deviceButton ID of the button.
* \param buffer A char-buffer to receive the button name.
* \param bufferLength Length of the buffer receiving the button name in bytes.
* \return The number of bytes written to buffer (includes the trailing \0).
*/
virtual size_t GetButtonName(DeviceButtonId deviceButton, char* buffer, size_t bufferLength) const { GAINPUT_UNUSED(deviceButton); GAINPUT_UNUSED(buffer); GAINPUT_UNUSED(bufferLength); return 0; }
/// Returns the type of the given button.
virtual ButtonType GetButtonType(DeviceButtonId deviceButton) const = 0;
/// Returns the button's ID if the name is of this device's buttons.
/**
* \param name Name of the device button to look for.
* \return The device button ID.
*/
virtual DeviceButtonId GetButtonByName(const char* name) const { GAINPUT_UNUSED(name); return InvalidDeviceButtonId; }
/// Returns the device's state, probably best if only used internally.
InputState* GetInputState() { return state_; }
/// Returns the device's state, probably best if only used internally.
const InputState* GetInputState() const { return state_; }
/// Returns the device's previous state, probably best if only used internally.
InputState* GetPreviousInputState() { return previousState_; }
/// Returns the device's state that is currently being determined, may be 0 if not available.
virtual InputState* GetNextInputState() { return 0; }
/// Returns the previously set dead zone for the given button or 0.0f if none was set yet.
float GetDeadZone(DeviceButtonId buttonId) const;
/// Sets the dead zone for the given button.
void SetDeadZone(DeviceButtonId buttonId, float value);
/// Enable/disable debug rendering of this device.
void SetDebugRenderingEnabled(bool enabled);
/// Returns true if debug rendering is enabled, false otherwise.
bool IsDebugRenderingEnabled() const { return debugRenderingEnabled_; }
#if defined(GAINPUT_DEV) || defined(GAINPUT_ENABLE_RECORDER)
/// Returns true if this device is being controlled by a remote device
/// or a recorded input sequence, false otherwise.
bool IsSynced() const { return synced_; }
/// Sets if this device is being controlled remotely or from a recording.
/**
* \sa IsSynced()
*/
void SetSynced(bool synced) { synced_ = synced; }
#endif
protected:
/// The manager this device belongs to.
InputManager& manager_;
/// The ID of this device.
DeviceId deviceId_;
/// Index of this device among devices of the same type.
unsigned index_;
/// The current state of this device.
InputState* state_;
/// The previous state of this device.
InputState* previousState_;
float* deadZones_;
/// Specifies if this device is currently rendering debug information.
bool debugRenderingEnabled_;
#if defined(GAINPUT_DEV) || defined(GAINPUT_ENABLE_RECORDER)
/// Specifies if this device's state is actually set from a device
/// or manually set by some other system.
bool synced_;
#endif
/// Implementation of the device's Update function.
/**
* \param delta The delta state to add changes to. May be 0.
*/
virtual void InternalUpdate(InputDeltaState* delta) = 0;
/// Implementation of the device's GetState function.
/**
* \return The device's state.
*/
virtual DeviceState InternalGetState() const = 0;
/// Checks which buttons are down.
/**
* This function is normally used by GetAnyButtonDown implementations internally.
* \param outButtons An array to write buttons that are down to.
* \param maxButtonCount The size of outButtons.
* \param start The lowest device button ID to check.
* \param end The biggest device button ID to check.
* \return The number of buttons written to outButtons.
*/
size_t CheckAllButtonsDown(DeviceButtonSpec* outButtons, size_t maxButtonCount, unsigned start, unsigned end) const;
};
inline
bool
InputDevice::GetBool(DeviceButtonId deviceButton) const
{
if (!IsAvailable())
{
return false;
}
GAINPUT_ASSERT(state_);
return state_->GetBool(deviceButton);
}
inline
bool
InputDevice::GetBoolPrevious(DeviceButtonId deviceButton) const
{
if (!IsAvailable())
{
return false;
}
GAINPUT_ASSERT(previousState_);
return previousState_->GetBool(deviceButton);
}
inline
float
InputDevice::GetFloat(DeviceButtonId deviceButton) const
{
if (!IsAvailable())
{
return 0.0f;
}
GAINPUT_ASSERT(state_);
return state_->GetFloat(deviceButton);
}
inline
float
InputDevice::GetFloatPrevious(DeviceButtonId deviceButton) const
{
if (!IsAvailable())
{
return 0.0f;
}
GAINPUT_ASSERT(previousState_);
return previousState_->GetFloat(deviceButton);
}
}
#endif