410 lines
10 KiB
Text
410 lines
10 KiB
Text
/**
|
|
* PANDA 3D SOFTWARE
|
|
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
*
|
|
* All use of this software is subject to the terms of the revised BSD
|
|
* license. You should have received a copy of this license along
|
|
* with this source code in a file named "LICENSE."
|
|
*
|
|
* @file inputDevice.I
|
|
* @author rdb
|
|
* @date 2015-12-11
|
|
*/
|
|
|
|
#include "config_device.h"
|
|
|
|
/**
|
|
*
|
|
*/
|
|
INLINE InputDevice::
|
|
InputDevice() {
|
|
_button_events = new ButtonEventList;
|
|
_pointer_events = new PointerEventList;
|
|
}
|
|
|
|
/**
|
|
* Returns a human-readable name for the device. Not necessarily unique.
|
|
*/
|
|
INLINE std::string InputDevice::
|
|
get_name() const {
|
|
LightMutexHolder holder(_lock);
|
|
return _name;
|
|
}
|
|
|
|
/**
|
|
* Returns a string containing the manufacturer of the device, if this
|
|
* information is known.
|
|
*/
|
|
INLINE std::string InputDevice::
|
|
get_manufacturer() const {
|
|
LightMutexHolder holder(_lock);
|
|
return _manufacturer;
|
|
}
|
|
|
|
/**
|
|
* Returns a string containing the serial number of the device, if this
|
|
* information is known.
|
|
*/
|
|
INLINE std::string InputDevice::
|
|
get_serial_number() const {
|
|
LightMutexHolder holder(_lock);
|
|
return _serial_number;
|
|
}
|
|
|
|
/**
|
|
* Returns a string containing the USB vendor ID of the device, if this
|
|
* information is known.
|
|
*/
|
|
INLINE unsigned short InputDevice::
|
|
get_vendor_id() const {
|
|
LightMutexHolder holder(_lock);
|
|
return _vendor_id;
|
|
}
|
|
|
|
/**
|
|
* Returns a string containing the USB product ID of the device, if this
|
|
* information is known.
|
|
*/
|
|
INLINE unsigned short InputDevice::
|
|
get_product_id() const {
|
|
LightMutexHolder holder(_lock);
|
|
return _product_id;
|
|
}
|
|
|
|
/**
|
|
* Returns true if the device is still connected and able to receive data,
|
|
* false otherwise. May return false positives.
|
|
*/
|
|
INLINE bool InputDevice::
|
|
is_connected() const {
|
|
LightMutexHolder holder(_lock);
|
|
return _is_connected;
|
|
}
|
|
|
|
/**
|
|
* Returns an identification of the general type of device. If this could not
|
|
* be determined, returns DeviceClass.unknown.
|
|
*/
|
|
INLINE InputDevice::DeviceClass InputDevice::
|
|
get_device_class() const {
|
|
LightMutexHolder holder(_lock);
|
|
return _device_class;
|
|
}
|
|
|
|
/**
|
|
* Returns true if the device supports the indicated feature.
|
|
*/
|
|
INLINE bool InputDevice::
|
|
has_feature(Feature feature) const {
|
|
LightMutexHolder holder(_lock);
|
|
return (_features & (1 << (unsigned int)feature)) != 0;
|
|
}
|
|
|
|
/**
|
|
* Returns true if this is a pointing device.
|
|
*/
|
|
INLINE bool InputDevice::
|
|
has_pointer() const {
|
|
return has_feature(Feature::pointer);
|
|
}
|
|
|
|
/**
|
|
* Returns true if the device has a physical keyboard designed for text entry.
|
|
*/
|
|
INLINE bool InputDevice::
|
|
has_keyboard() const {
|
|
return has_feature(Feature::keyboard);
|
|
}
|
|
|
|
/**
|
|
* Returns true if the device features a tracker that can track position and/or
|
|
* orientation in 3D space.
|
|
*/
|
|
INLINE bool InputDevice::
|
|
has_tracker() const {
|
|
return has_feature(Feature::tracker);
|
|
}
|
|
|
|
/**
|
|
* Returns true if the device has vibration motors that can be controlled by
|
|
* calling set_vibration().
|
|
*/
|
|
INLINE bool InputDevice::
|
|
has_vibration() const {
|
|
return has_feature(Feature::vibration);
|
|
}
|
|
|
|
/**
|
|
* Returns true if the device may be able to provide information about its
|
|
* battery life.
|
|
*/
|
|
INLINE bool InputDevice::
|
|
has_battery() const {
|
|
return has_feature(Feature::battery);
|
|
}
|
|
|
|
/**
|
|
* Returns the TrackerData associated with the input device's tracker. This
|
|
* only makes sense if has_tracker() also returns true.
|
|
*/
|
|
INLINE TrackerData InputDevice::
|
|
get_tracker() const {
|
|
LightMutexHolder holder(_lock);
|
|
return _tracker_data;
|
|
}
|
|
|
|
/**
|
|
* Returns a rough indication of the battery level, ranging from 0 (completely
|
|
* empty battery) to the indicated max_level value.
|
|
*/
|
|
INLINE InputDevice::BatteryData InputDevice::
|
|
get_battery() const {
|
|
LightMutexHolder holder(_lock);
|
|
return _battery_data;
|
|
}
|
|
|
|
/**
|
|
* Returns the number of buttons known to the device. This includes those
|
|
* buttons whose state has been seen, as well as buttons that have been
|
|
* associated with a ButtonHandle even if their state is unknown. This number
|
|
* may change as more buttons are discovered.
|
|
*/
|
|
INLINE size_t InputDevice::
|
|
get_num_buttons() const {
|
|
LightMutexHolder holder(_lock);
|
|
return _buttons.size();
|
|
}
|
|
|
|
/**
|
|
* Associates the indicated ButtonHandle with the button of the indicated index
|
|
* number. When the given button index changes state, a corresponding
|
|
* ButtonEvent will be generated with the given ButtonHandle. Pass
|
|
* ButtonHandle::none() to turn off any association.
|
|
*
|
|
* It is not necessary to call this if you simply want to query the state of
|
|
* the various buttons by index number; this is only necessary in order to
|
|
* generate ButtonEvents when the buttons change state.
|
|
*/
|
|
INLINE void InputDevice::
|
|
map_button(size_t index, ButtonHandle button) {
|
|
LightMutexHolder holder(_lock);
|
|
if (index >= _buttons.size()) {
|
|
_buttons.resize(index + 1, ButtonState());
|
|
}
|
|
|
|
_buttons[index].handle = button;
|
|
}
|
|
|
|
/**
|
|
* Returns the ButtonHandle that was previously associated with the given index
|
|
* number by a call to map_button(), or ButtonHandle::none() if no button
|
|
* was associated.
|
|
*/
|
|
INLINE ButtonHandle InputDevice::
|
|
get_button_map(size_t index) const {
|
|
if (index < _buttons.size()) {
|
|
return _buttons[index].handle;
|
|
} else {
|
|
return ButtonHandle::none();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns true if the indicated button (identified by its index number) is
|
|
* currently known to be down, or false if it is up or unknown.
|
|
*/
|
|
INLINE bool InputDevice::
|
|
is_button_pressed(size_t index) const {
|
|
if (index < _buttons.size()) {
|
|
return (_buttons[index]._state == S_down);
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns true if the state of the indicated button is known, or false if we
|
|
* have never heard anything about this particular button.
|
|
*/
|
|
INLINE bool InputDevice::
|
|
is_button_known(size_t index) const {
|
|
if (index < _buttons.size()) {
|
|
return _buttons[index]._state != S_unknown;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the ButtonState that is set at the given index, or throw an assert
|
|
* if the index was not found in the list.
|
|
*/
|
|
INLINE InputDevice::ButtonState InputDevice::
|
|
get_button(size_t index) const {
|
|
nassertr_always(index < _buttons.size(), ButtonState());
|
|
return _buttons[index];
|
|
}
|
|
|
|
/**
|
|
* Returns the first ButtonState found with the given axis, or throw an assert
|
|
* if the button handle was not found in the list.
|
|
*/
|
|
INLINE InputDevice::ButtonState InputDevice::
|
|
find_button(ButtonHandle handle) const {
|
|
for (size_t i = 0; i < _buttons.size(); ++i) {
|
|
if (_buttons[i].handle == handle) {
|
|
return _buttons[i];
|
|
}
|
|
}
|
|
return ButtonState();
|
|
}
|
|
|
|
/**
|
|
* Returns the number of analog axes known to the InputDevice. This number
|
|
* may change as more axes are discovered.
|
|
*/
|
|
INLINE size_t InputDevice::
|
|
get_num_axes() const {
|
|
return _axes.size();
|
|
}
|
|
|
|
/**
|
|
* Associates the indicated Axis with the axis of the indicated index
|
|
* number. Pass Axis::none to turn off any association.
|
|
*
|
|
* It is not necessary to call this if you simply want to query the state of
|
|
* the various axes by index number.
|
|
*/
|
|
INLINE void InputDevice::
|
|
map_axis(size_t index, InputDevice::Axis axis) {
|
|
LightMutexHolder holder(_lock);
|
|
if (index >= _axes.size()) {
|
|
_axes.resize(index + 1, AxisState());
|
|
}
|
|
|
|
_axes[index].axis = axis;
|
|
}
|
|
|
|
/**
|
|
* Returns the current position of indicated analog axis (identified by its
|
|
* index number), or 0.0 if the axis is unknown. The normal range of a
|
|
* single axis is -1.0 to 1.0.
|
|
*/
|
|
INLINE double InputDevice::
|
|
get_axis_value(size_t index) const {
|
|
if (index < _axes.size()) {
|
|
return _axes[index].value;
|
|
} else {
|
|
return 0.0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the axis state that is set at the given index, or throw an assert
|
|
* if the index was not found in the list.
|
|
*/
|
|
INLINE InputDevice::AxisState InputDevice::
|
|
get_axis(size_t index) const {
|
|
nassertr_always(index < _axes.size(), AxisState());
|
|
return _axes[index];
|
|
}
|
|
|
|
/**
|
|
* Returns the first AnalogAxis found with the given axis, or throw an assert
|
|
* if the axis was not found in the list.
|
|
*/
|
|
INLINE InputDevice::AxisState InputDevice::
|
|
find_axis(InputDevice::Axis axis) const {
|
|
for (size_t i = 0; i < _axes.size(); ++i) {
|
|
if (_axes[i].axis == axis) {
|
|
return _axes[i];
|
|
}
|
|
}
|
|
return AxisState();
|
|
}
|
|
|
|
/**
|
|
* Returns true if the state of the indicated analog axis is known, or false
|
|
* if we have never heard anything about this particular axis.
|
|
*/
|
|
INLINE bool InputDevice::
|
|
is_axis_known(size_t index) const {
|
|
if (index < _axes.size()) {
|
|
return _axes[index].known;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the strength of the vibration effect, if supported. The values are
|
|
* clamped to 0-1 range. The first value axes the low-frequency rumble
|
|
* motor, whereas the second axes the high-frequency motor, if present.
|
|
*/
|
|
INLINE void InputDevice::
|
|
set_vibration(double strong, double weak) {
|
|
LightMutexHolder holder(_lock);
|
|
do_set_vibration(std::max(std::min(strong, 1.0), 0.0), std::max(std::min(weak, 1.0), 0.0));
|
|
}
|
|
|
|
/**
|
|
* Enables the generation of mouse-movement events.
|
|
*/
|
|
INLINE void InputDevice::
|
|
enable_pointer_events() {
|
|
LightMutexHolder holder(_lock);
|
|
_enable_pointer_events = true;
|
|
}
|
|
|
|
/**
|
|
* Disables the generation of mouse-movement events.
|
|
*/
|
|
INLINE void InputDevice::
|
|
disable_pointer_events() {
|
|
LightMutexHolder holder(_lock);
|
|
_enable_pointer_events = false;
|
|
_pointer_events.clear();
|
|
}
|
|
|
|
/**
|
|
* Called to indicate that the device supports the given feature.
|
|
* Assumes the lock is held.
|
|
*/
|
|
INLINE void InputDevice::
|
|
enable_feature(Feature feature) {
|
|
_features |= (1 << (unsigned int)feature);
|
|
}
|
|
|
|
/**
|
|
* Called to indicate that the device has been disconnected or connected from
|
|
* its host.
|
|
*/
|
|
INLINE void InputDevice::
|
|
set_connected(bool connected) {
|
|
LightMutexHolder holder(_lock);
|
|
_is_connected = connected;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
INLINE InputDevice::ButtonState::
|
|
ButtonState(ButtonHandle handle) :
|
|
handle(handle) {
|
|
}
|
|
|
|
/**
|
|
* True if the button state is currently known.
|
|
*/
|
|
ALWAYS_INLINE bool InputDevice::ButtonState::
|
|
is_known() const {
|
|
return (_state != S_unknown);
|
|
}
|
|
|
|
/**
|
|
* True if the button is currently known to be pressed.
|
|
*/
|
|
ALWAYS_INLINE bool InputDevice::ButtonState::
|
|
is_pressed() const {
|
|
return (_state == S_down);
|
|
}
|