git-subtree-dir: external/gainput git-subtree-split: 2be0a50089eafcc6fccb66142180082e48f27f4c
272 lines
9.2 KiB
C++
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
|
|
|