open_toontown_panda3d/panda/src/device/inputDevice.h

322 lines
8.6 KiB
C++

/**
* 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.h
* @author rdb
* @date 2015-12-11
*/
#ifndef INPUTDEVICE_H
#define INPUTDEVICE_H
#include "pandabase.h"
#include "buttonEvent.h"
#include "buttonEventList.h"
#include "pointerEvent.h"
#include "pointerEventList.h"
#include "mouseData.h"
#include "trackerData.h"
#include "clockObject.h"
#include "pdeque.h"
#include "pvector.h"
#include "lightMutex.h"
#include "lightMutexHolder.h"
typedef MouseData PointerData;
/**
* This is a structure representing a single input device. Input devices may
* have zero or more buttons, pointers, or controls associated with them, and
* optionally a motion tracker.
*
* These devices are brought under a common interface because there is such a
* large range of devices out there that may support any number of these types
* of controls, we couldn't even begin to cover them with type-specific
* subclasses.
*
* Use the various has_() and get_num_() methods to determine information about
* the device capabilities. For instance, has_keyboard() will give an
* indication that you can receive keystroke events from this device, and
* get_num_buttons() will tell you that the device may send button events.
*
* There is the DeviceType enumeration, however, which will (if known) contain
* identification of the general category of devices this fits in, such as
* keyboard, mouse, gamepad, or flight stick.
*/
class EXPCL_PANDA_DEVICE InputDevice : public TypedReferenceCount {
PUBLISHED:
// This enum contains information that can be used to identify the
// type of input device.
enum DeviceClass {
// It is not known what type of device this is.
DC_unknown,
// This means that the device doesn't correspond to a physical
// device, but rather to a dynamic source of input events.
DC_virtual,
// A physical, alphabetical keyboard.
DC_keyboard,
DC_mouse,
DC_touch,
// A gamepad with action buttons, a D-pad, and thumbsticks.
DC_gamepad,
DC_flight_stick,
DC_steering_wheel,
DC_dance_pad,
// Head-mounted display.
DC_hmd,
// Count of this enum, used for loops
DC_COUNT,
};
protected:
InputDevice(const string &name, DeviceClass dev_class, int flags);
public:
InputDevice();
InputDevice(const InputDevice &copy);
void operator = (const InputDevice &copy);
~InputDevice();
PUBLISHED:
enum ControlAxis {
C_none,
// Gamepad
C_left_x,
C_left_y,
C_left_trigger,
C_right_x,
C_right_y,
C_right_trigger,
// Flight stick
C_x,
C_y,
C_trigger,
C_throttle,
C_rudder,
C_hat_x,
C_hat_y,
// Steering wheel / pedals
C_wheel,
C_accelerator,
C_brake,
};
INLINE string get_name() const;
INLINE string get_manufacturer() const;
INLINE unsigned short get_vendor_id() const;
INLINE unsigned short get_product_id() const;
INLINE bool is_connected() const;
INLINE DeviceClass get_device_class() const;
// The human-readable name of this input device.
MAKE_PROPERTY(name, get_name);
// The device's manufacturer, or the empty string if not known.
MAKE_PROPERTY(manufacturer, get_manufacturer);
// USB vendor ID of the device, or 0 if not known.
MAKE_PROPERTY(vendor_id, get_vendor_id);
// USB product ID of the device, or 0 if not known.
MAKE_PROPERTY(product_id, get_product_id);
// This is false if we know that the device is not currently connected.
// May report false positives if we can't know this with certainty.
MAKE_PROPERTY(connected, is_connected);
// This contains an identification of the general type of device. If
// this could not be determined, it is set to DC_unknown.
MAKE_PROPERTY(device_class, get_device_class);
INLINE bool has_pointer() const;
INLINE bool has_keyboard() const;
INLINE bool has_tracker() const;
INLINE bool has_battery() const;
INLINE PointerData get_pointer() const;
INLINE TrackerData get_tracker() const;
INLINE short get_battery_level() const;
INLINE short get_max_battery_level() const;
INLINE size_t get_num_buttons() const;
INLINE void set_button_map(size_t index, ButtonHandle button);
INLINE ButtonHandle get_button_map(size_t index) const;
INLINE bool get_button_state(size_t index) const;
INLINE bool is_button_known(size_t index) const;
INLINE size_t get_num_controls() const;
INLINE void set_control_map(size_t index, ControlAxis axis);
INLINE ControlAxis get_control_map(size_t index) const;
INLINE double get_control_state(size_t index) const;
INLINE bool is_control_known(size_t index) const;
INLINE void set_vibration(double strong, double weak);
INLINE void enable_pointer_events();
INLINE void disable_pointer_events();
void poll();
bool has_button_event() const;
PT(ButtonEventList) get_button_events();
bool has_pointer_event() const;
PT(PointerEventList) get_pointer_events();
virtual void output(ostream &out) const;
protected:
void set_pointer(bool inwin, double x, double y, double time);
void set_pointer_out_of_window(double time);
void set_button_state(int index, bool down);
void set_control_state(int index, double state);
void set_tracker(const LPoint3 &pos, const LOrientation &orient, double time);
virtual void do_set_vibration(double low, double high);
virtual void do_poll();
public:
INLINE void set_connected(bool connected);
// We need these methods to make VC++ happy when we try to
// instantiate a pvector<InputDevice>. They don't do
// anything useful.
INLINE bool operator == (const InputDevice &other) const;
INLINE bool operator != (const InputDevice &other) const;
INLINE bool operator < (const InputDevice &other) const;
void output_buttons(ostream &out) const;
void write_buttons(ostream &out, int indent_level) const;
void write_controls(ostream &out, int indent_level) const;
protected:
enum InputDeviceFlags {
// The device provides absolute screen coordinates.
IDF_has_pointer = 0x01,
// The device has an interface for providing text input.
IDF_has_keyboard = 0x02,
// The device has a motion tracker, such as an HMD.
IDF_has_tracker = 0x04,
// The device can produce force feedback.
IDF_has_vibration = 0x08,
// The device provides information about battery life.
IDF_has_battery = 0x10,
};
protected:
typedef pdeque<ButtonEvent> ButtonEvents;
LightMutex _lock;
string _name;
string _serial_number;
string _manufacturer;
DeviceClass _device_class;
int _flags;
int _event_sequence;
unsigned short _vendor_id;
unsigned short _product_id;
bool _is_connected;
bool _enable_pointer_events;
PointerData _pointer_data;
PT(ButtonEventList) _button_events;
PT(PointerEventList) _pointer_events;
PUBLISHED:
enum State {
S_unknown,
S_up,
S_down
};
class ButtonState {
public:
INLINE ButtonState();
INLINE ButtonState(ButtonHandle handle);
PUBLISHED:
ButtonHandle handle;
State state;
};
typedef pvector<ButtonState> Buttons;
Buttons _buttons;
class AnalogState {
public:
INLINE AnalogState();
PUBLISHED:
ControlAxis axis;
double state;
bool known;
};
typedef pvector<AnalogState> Controls;
Controls _controls;
short _battery_level;
short _max_battery_level;
TrackerData _tracker_data;
INLINE ButtonState get_button(size_t index) const;
INLINE ButtonState find_button(ButtonHandle handle) const;
INLINE AnalogState get_control(size_t index) const;
INLINE AnalogState find_control(ControlAxis axis) const;
// Make device buttons and controls iterable
MAKE_SEQ_PROPERTY(buttons, get_num_buttons, get_button);
MAKE_SEQ_PROPERTY(controls, get_num_controls, get_control);
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedReferenceCount::init_type();
register_type(_type_handle, "InputDevice",
TypedReferenceCount::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
INLINE ostream &operator << (ostream &out, const InputDevice &device) {
device.output(out);
return out;
}
EXPCL_PANDA_DEVICE ostream &operator << (ostream &out, InputDevice::DeviceClass dc);
EXPCL_PANDA_DEVICE ostream &operator << (ostream &out, InputDevice::ControlAxis axis);
#include "inputDevice.I"
#endif