/*
* Copyright (C) 2014-2017 Team Kodi
* http://kodi.tv
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this Program; see the file COPYING. If not, see
* .
*
*/
#pragma once
#include "Peripheral.h"
#include // Requires c++11
#include
#include
#include
#include
#define PERIPHERAL_SAFE_DELETE(x) do { delete (x); (x) = NULL; } while (0)
#define PERIPHERAL_SAFE_DELETE_ARRAY(x) do { delete[] (x); (x) = NULL; } while (0)
namespace kodi
{
namespace addon
{
/*!
* Utility class to manipulate arrays of peripheral types.
*/
template
class PeripheralVector
{
public:
static void ToStructs(const std::vector& vecObjects, THE_STRUCT** pStructs)
{
if (!pStructs)
return;
if (vecObjects.empty())
{
*pStructs = NULL;
}
else
{
(*pStructs) = new THE_STRUCT[vecObjects.size()];
for (unsigned int i = 0; i < vecObjects.size(); i++)
vecObjects.at(i).ToStruct((*pStructs)[i]);
}
}
static void ToStructs(const std::vector& vecObjects, THE_STRUCT** pStructs)
{
if (!pStructs)
return;
if (vecObjects.empty())
{
*pStructs = NULL;
}
else
{
*pStructs = new THE_STRUCT[vecObjects.size()];
for (unsigned int i = 0; i < vecObjects.size(); i++)
vecObjects.at(i)->ToStruct((*pStructs)[i]);
}
}
static void FreeStructs(unsigned int structCount, THE_STRUCT* structs)
{
if (structs)
{
for (unsigned int i = 0; i < structCount; i++)
THE_CLASS::FreeStruct(structs[i]);
}
PERIPHERAL_SAFE_DELETE_ARRAY(structs);
}
};
/*!
* ADDON::Peripheral
*
* Wrapper class providing peripheral information. Classes can extend
* Peripheral to inherit peripheral properties.
*/
class Peripheral
{
public:
Peripheral(PERIPHERAL_TYPE type = PERIPHERAL_TYPE_UNKNOWN, const std::string& strName = "") :
m_type(type),
m_strName(strName),
m_vendorId(0),
m_productId(0),
m_index(0)
{
}
explicit Peripheral(const PERIPHERAL_INFO& info) :
m_type(info.type),
m_strName(info.name ? info.name : ""),
m_vendorId(info.vendor_id),
m_productId(info.product_id),
m_index(info.index)
{
}
virtual ~Peripheral(void) = default;
PERIPHERAL_TYPE Type(void) const { return m_type; }
const std::string& Name(void) const { return m_strName; }
uint16_t VendorID(void) const { return m_vendorId; }
uint16_t ProductID(void) const { return m_productId; }
unsigned int Index(void) const { return m_index; }
// Derived property: VID and PID are 0x0000 if unknown
bool IsVidPidKnown(void) const { return m_vendorId != 0 || m_productId != 0; }
void SetType(PERIPHERAL_TYPE type) { m_type = type; }
void SetName(const std::string& strName) { m_strName = strName; }
void SetVendorID(uint16_t vendorId) { m_vendorId = vendorId; }
void SetProductID(uint16_t productId) { m_productId = productId; }
void SetIndex(unsigned int index) { m_index = index; }
void ToStruct(PERIPHERAL_INFO& info) const
{
info.type = m_type;
info.name = new char[m_strName.size() + 1];
info.vendor_id = m_vendorId;
info.product_id = m_productId;
info.index = m_index;
std::strcpy(info.name, m_strName.c_str());
}
static void FreeStruct(PERIPHERAL_INFO& info)
{
PERIPHERAL_SAFE_DELETE_ARRAY(info.name);
}
private:
PERIPHERAL_TYPE m_type;
std::string m_strName;
uint16_t m_vendorId;
uint16_t m_productId;
unsigned int m_index;
};
typedef PeripheralVector Peripherals;
/*!
* ADDON::PeripheralEvent
*
* Wrapper class for peripheral events.
*/
class PeripheralEvent
{
public:
PeripheralEvent(void)
{
}
PeripheralEvent(unsigned int peripheralIndex, unsigned int buttonIndex, JOYSTICK_STATE_BUTTON state) :
m_type(PERIPHERAL_EVENT_TYPE_DRIVER_BUTTON),
m_peripheralIndex(peripheralIndex),
m_driverIndex(buttonIndex),
m_buttonState(state)
{
}
PeripheralEvent(unsigned int peripheralIndex, unsigned int hatIndex, JOYSTICK_STATE_HAT state) :
m_type(PERIPHERAL_EVENT_TYPE_DRIVER_HAT),
m_peripheralIndex(peripheralIndex),
m_driverIndex(hatIndex),
m_hatState(state)
{
}
PeripheralEvent(unsigned int peripheralIndex, unsigned int axisIndex, JOYSTICK_STATE_AXIS state) :
m_type(PERIPHERAL_EVENT_TYPE_DRIVER_AXIS),
m_peripheralIndex(peripheralIndex),
m_driverIndex(axisIndex),
m_axisState(state)
{
}
explicit PeripheralEvent(const PERIPHERAL_EVENT& event) :
m_type(event.type),
m_peripheralIndex(event.peripheral_index),
m_driverIndex(event.driver_index),
m_buttonState(event.driver_button_state),
m_hatState(event.driver_hat_state),
m_axisState(event.driver_axis_state),
m_motorState(event.motor_state)
{
}
PERIPHERAL_EVENT_TYPE Type(void) const { return m_type; }
unsigned int PeripheralIndex(void) const { return m_peripheralIndex; }
unsigned int DriverIndex(void) const { return m_driverIndex; }
JOYSTICK_STATE_BUTTON ButtonState(void) const { return m_buttonState; }
JOYSTICK_STATE_HAT HatState(void) const { return m_hatState; }
JOYSTICK_STATE_AXIS AxisState(void) const { return m_axisState; }
JOYSTICK_STATE_MOTOR MotorState(void) const { return m_motorState; }
void SetType(PERIPHERAL_EVENT_TYPE type) { m_type = type; }
void SetPeripheralIndex(unsigned int index) { m_peripheralIndex = index; }
void SetDriverIndex(unsigned int index) { m_driverIndex = index; }
void SetButtonState(JOYSTICK_STATE_BUTTON state) { m_buttonState = state; }
void SetHatState(JOYSTICK_STATE_HAT state) { m_hatState = state; }
void SetAxisState(JOYSTICK_STATE_AXIS state) { m_axisState = state; }
void SetMotorState(JOYSTICK_STATE_MOTOR state) { m_motorState = state; }
void ToStruct(PERIPHERAL_EVENT& event) const
{
event.type = m_type;
event.peripheral_index = m_peripheralIndex;
event.driver_index = m_driverIndex;
event.driver_button_state = m_buttonState;
event.driver_hat_state = m_hatState;
event.driver_axis_state = m_axisState;
event.motor_state = m_motorState;
}
static void FreeStruct(PERIPHERAL_EVENT& event)
{
(void)event;
}
private:
PERIPHERAL_EVENT_TYPE m_type = PERIPHERAL_EVENT_TYPE_NONE;
unsigned int m_peripheralIndex = 0;
unsigned int m_driverIndex = 0;
JOYSTICK_STATE_BUTTON m_buttonState = JOYSTICK_STATE_BUTTON_UNPRESSED;
JOYSTICK_STATE_HAT m_hatState = JOYSTICK_STATE_HAT_UNPRESSED;
JOYSTICK_STATE_AXIS m_axisState = 0.0f;
JOYSTICK_STATE_MOTOR m_motorState = 0.0f;
};
typedef PeripheralVector PeripheralEvents;
/*!
* kodi::addon::Joystick
*
* Wrapper class providing additional joystick information not provided by
* ADDON::Peripheral.
*/
class Joystick : public Peripheral
{
public:
Joystick(const std::string& provider = "", const std::string& strName = "") :
Peripheral(PERIPHERAL_TYPE_JOYSTICK, strName),
m_provider(provider),
m_requestedPort(NO_PORT_REQUESTED),
m_buttonCount(0),
m_hatCount(0),
m_axisCount(0),
m_motorCount(0),
m_supportsPowerOff(false)
{
}
Joystick(const Joystick& other)
{
*this = other;
}
explicit Joystick(const JOYSTICK_INFO& info) :
Peripheral(info.peripheral),
m_provider(info.provider ? info.provider : ""),
m_requestedPort(info.requested_port),
m_buttonCount(info.button_count),
m_hatCount(info.hat_count),
m_axisCount(info.axis_count),
m_motorCount(info.motor_count),
m_supportsPowerOff(info.supports_poweroff)
{
}
~Joystick(void) override = default;
Joystick& operator=(const Joystick& rhs)
{
if (this != &rhs)
{
Peripheral::operator=(rhs);
m_provider = rhs.m_provider;
m_requestedPort = rhs.m_requestedPort;
m_buttonCount = rhs.m_buttonCount;
m_hatCount = rhs.m_hatCount;
m_axisCount = rhs.m_axisCount;
m_motorCount = rhs.m_motorCount;
m_supportsPowerOff = rhs.m_supportsPowerOff;
}
return *this;
}
const std::string& Provider(void) const { return m_provider; }
int RequestedPort(void) const { return m_requestedPort; }
unsigned int ButtonCount(void) const { return m_buttonCount; }
unsigned int HatCount(void) const { return m_hatCount; }
unsigned int AxisCount(void) const { return m_axisCount; }
unsigned int MotorCount(void) const { return m_motorCount; }
bool SupportsPowerOff(void) const { return m_supportsPowerOff; }
void SetProvider(const std::string& provider) { m_provider = provider; }
void SetRequestedPort(int requestedPort) { m_requestedPort = requestedPort; }
void SetButtonCount(unsigned int buttonCount) { m_buttonCount = buttonCount; }
void SetHatCount(unsigned int hatCount) { m_hatCount = hatCount; }
void SetAxisCount(unsigned int axisCount) { m_axisCount = axisCount; }
void SetMotorCount(unsigned int motorCount) { m_motorCount = motorCount; }
void SetSupportsPowerOff(bool supportsPowerOff) { m_supportsPowerOff = supportsPowerOff; }
void ToStruct(JOYSTICK_INFO& info) const
{
Peripheral::ToStruct(info.peripheral);
info.provider = new char[m_provider.size() + 1];
info.requested_port = m_requestedPort;
info.button_count = m_buttonCount;
info.hat_count = m_hatCount;
info.axis_count = m_axisCount;
info.motor_count = m_motorCount;
info.supports_poweroff = m_supportsPowerOff;
std::strcpy(info.provider, m_provider.c_str());
}
static void FreeStruct(JOYSTICK_INFO& info)
{
Peripheral::FreeStruct(info.peripheral);
PERIPHERAL_SAFE_DELETE_ARRAY(info.provider);
}
private:
std::string m_provider;
int m_requestedPort;
unsigned int m_buttonCount;
unsigned int m_hatCount;
unsigned int m_axisCount;
unsigned int m_motorCount;
bool m_supportsPowerOff;
};
typedef PeripheralVector Joysticks;
/*!
* ADDON::DriverPrimitive
*
* Base class for joystick driver primitives. A driver primitive can be:
*
* 1) a button
* 2) a hat direction
* 3) a semiaxis (either the positive or negative half of an axis)
* 4) a motor
* 5) a keyboard key
* 6) a mouse button
* 7) a relative pointer direction
*
* The type determines the fields in use:
*
* Button:
* - driver index
*
* Hat direction:
* - driver index
* - hat direction
*
* Semiaxis:
* - driver index
* - center
* - semiaxis direction
* - range
*
* Motor:
* - driver index
*
* Key:
* - key code
*
* Mouse button:
* - driver index
*
* Relative pointer direction:
* - relative pointer direction
*/
struct DriverPrimitive
{
protected:
/*!
* \brief Construct a driver primitive of the specified type
*/
DriverPrimitive(JOYSTICK_DRIVER_PRIMITIVE_TYPE type, unsigned int driverIndex) :
m_type(type),
m_driverIndex(driverIndex),
m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN),
m_center(0),
m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN),
m_range(1),
m_relPointerDirection(JOYSTICK_DRIVER_RELPOINTER_UNKNOWN)
{
}
public:
/*!
* \brief Construct an invalid driver primitive
*/
DriverPrimitive(void) :
m_type(JOYSTICK_DRIVER_PRIMITIVE_TYPE_UNKNOWN),
m_driverIndex(0),
m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN),
m_center(0),
m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN),
m_range(1),
m_relPointerDirection(JOYSTICK_DRIVER_RELPOINTER_UNKNOWN)
{
}
/*!
* \brief Construct a driver primitive representing a joystick button
*/
static DriverPrimitive CreateButton(unsigned int buttonIndex)
{
return DriverPrimitive(JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON, buttonIndex);
}
/*!
* \brief Construct a driver primitive representing one of the four direction
* arrows on a dpad
*/
DriverPrimitive(unsigned int hatIndex, JOYSTICK_DRIVER_HAT_DIRECTION direction) :
m_type(JOYSTICK_DRIVER_PRIMITIVE_TYPE_HAT_DIRECTION),
m_driverIndex(hatIndex),
m_hatDirection(direction),
m_center(0),
m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN),
m_range(1),
m_relPointerDirection(JOYSTICK_DRIVER_RELPOINTER_UNKNOWN)
{
}
/*!
* \brief Construct a driver primitive representing the positive or negative
* half of an axis
*/
DriverPrimitive(unsigned int axisIndex, int center, JOYSTICK_DRIVER_SEMIAXIS_DIRECTION direction, unsigned int range) :
m_type(JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS),
m_driverIndex(axisIndex),
m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN),
m_center(center),
m_semiAxisDirection(direction),
m_range(range),
m_relPointerDirection(JOYSTICK_DRIVER_RELPOINTER_UNKNOWN)
{
}
/*!
* \brief Construct a driver primitive representing a motor
*/
static DriverPrimitive CreateMotor(unsigned int motorIndex)
{
return DriverPrimitive(JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR, motorIndex);
}
/*!
* \brief Construct a driver primitive representing a key on a keyboard
*/
DriverPrimitive(std::string keycode) :
m_type(JOYSTICK_DRIVER_PRIMITIVE_TYPE_KEY),
m_driverIndex(0),
m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN),
m_center(0),
m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN),
m_range(1),
m_keycode(std::move(keycode)),
m_relPointerDirection(JOYSTICK_DRIVER_RELPOINTER_UNKNOWN)
{
}
/*!
* \brief Construct a driver primitive representing a mouse button
*/
static DriverPrimitive CreateMouseButton(JOYSTICK_DRIVER_MOUSE_INDEX buttonIndex)
{
return DriverPrimitive(JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOUSE_BUTTON, static_cast(buttonIndex));
}
/*!
* \brief Construct a driver primitive representing one of the four
* direction in which a relative pointer can move
*/
DriverPrimitive(JOYSTICK_DRIVER_RELPOINTER_DIRECTION direction) :
m_type(JOYSTICK_DRIVER_PRIMITIVE_TYPE_RELPOINTER_DIRECTION),
m_driverIndex(0),
m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN),
m_center(0),
m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN),
m_range(1),
m_relPointerDirection(direction)
{
}
explicit DriverPrimitive(const JOYSTICK_DRIVER_PRIMITIVE& primitive) :
m_type(primitive.type),
m_driverIndex(0),
m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN),
m_center(0),
m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN),
m_range(1),
m_relPointerDirection(JOYSTICK_DRIVER_RELPOINTER_UNKNOWN)
{
switch (m_type)
{
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON:
{
m_driverIndex = primitive.button.index;
break;
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_HAT_DIRECTION:
{
m_driverIndex = primitive.hat.index;
m_hatDirection = primitive.hat.direction;
break;
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS:
{
m_driverIndex = primitive.semiaxis.index;
m_center = primitive.semiaxis.center;
m_semiAxisDirection = primitive.semiaxis.direction;
m_range = primitive.semiaxis.range;
break;
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR:
{
m_driverIndex = primitive.motor.index;
break;
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_KEY:
{
m_keycode = primitive.key.keycode;
break;
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOUSE_BUTTON:
{
m_driverIndex = primitive.mouse.button;
break;
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_RELPOINTER_DIRECTION:
{
m_relPointerDirection = primitive.relpointer.direction;
break;
}
default:
break;
}
}
JOYSTICK_DRIVER_PRIMITIVE_TYPE Type(void) const { return m_type; }
unsigned int DriverIndex(void) const { return m_driverIndex; }
JOYSTICK_DRIVER_HAT_DIRECTION HatDirection(void) const { return m_hatDirection; }
int Center(void) const { return m_center; }
JOYSTICK_DRIVER_SEMIAXIS_DIRECTION SemiAxisDirection(void) const { return m_semiAxisDirection; }
unsigned int Range(void) const { return m_range; }
const std::string& Keycode(void) const { return m_keycode; }
JOYSTICK_DRIVER_MOUSE_INDEX MouseIndex(void) const { return static_cast(m_driverIndex); }
JOYSTICK_DRIVER_RELPOINTER_DIRECTION RelPointerDirection(void) const { return m_relPointerDirection; }
bool operator==(const DriverPrimitive& other) const
{
if (m_type == other.m_type)
{
switch (m_type)
{
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON:
{
return m_driverIndex == other.m_driverIndex;
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_HAT_DIRECTION:
{
return m_driverIndex == other.m_driverIndex &&
m_hatDirection == other.m_hatDirection;
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS:
{
return m_driverIndex == other.m_driverIndex &&
m_center == other.m_center &&
m_semiAxisDirection == other.m_semiAxisDirection &&
m_range == other.m_range;
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_KEY:
{
return m_keycode == other.m_keycode;
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR:
{
return m_driverIndex == other.m_driverIndex;
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOUSE_BUTTON:
{
return m_driverIndex == other.m_driverIndex;
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_RELPOINTER_DIRECTION:
{
return m_relPointerDirection == other.m_relPointerDirection;
}
default:
break;
}
}
return false;
}
void ToStruct(JOYSTICK_DRIVER_PRIMITIVE& driver_primitive) const
{
driver_primitive.type = m_type;
switch (m_type)
{
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON:
{
driver_primitive.button.index = m_driverIndex;
break;
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_HAT_DIRECTION:
{
driver_primitive.hat.index = m_driverIndex;
driver_primitive.hat.direction = m_hatDirection;
break;
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS:
{
driver_primitive.semiaxis.index = m_driverIndex;
driver_primitive.semiaxis.center = m_center;
driver_primitive.semiaxis.direction = m_semiAxisDirection;
driver_primitive.semiaxis.range = m_range;
break;
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR:
{
driver_primitive.motor.index = m_driverIndex;
break;
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_KEY:
{
const size_t size = sizeof(driver_primitive.key.keycode);
std::strncpy(driver_primitive.key.keycode, m_keycode.c_str(), size - 1);
driver_primitive.key.keycode[size - 1] = '\0';
break;
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOUSE_BUTTON:
{
driver_primitive.mouse.button = static_cast(m_driverIndex);
break;
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_RELPOINTER_DIRECTION:
{
driver_primitive.relpointer.direction = m_relPointerDirection;
break;
}
default:
break;
}
}
static void FreeStruct(JOYSTICK_DRIVER_PRIMITIVE& primitive)
{
(void)primitive;
}
private:
JOYSTICK_DRIVER_PRIMITIVE_TYPE m_type;
unsigned int m_driverIndex;
JOYSTICK_DRIVER_HAT_DIRECTION m_hatDirection;
int m_center;
JOYSTICK_DRIVER_SEMIAXIS_DIRECTION m_semiAxisDirection;
unsigned int m_range;
std::string m_keycode;
JOYSTICK_DRIVER_RELPOINTER_DIRECTION m_relPointerDirection;
};
typedef PeripheralVector DriverPrimitives;
/*!
* kodi::addon::JoystickFeature
*
* Class for joystick features. A feature can be:
*
* 1) scalar[1]
* 2) analog stick
* 3) accelerometer
* 4) motor
* 5) relative pointer[2]
* 6) absolute pointer
* 7) wheel
* 8) throttle
* 9) keyboard key
*
* [1] All three driver primitives (buttons, hats and axes) have a state that
* can be represented using a single scalar value. For this reason,
* features that map to a single primitive are called "scalar features".
*
* [2] Relative pointers are similar to analog sticks, but they use
* relative distances instead of positions.
*/
class JoystickFeature
{
public:
JoystickFeature(const std::string& name = "", JOYSTICK_FEATURE_TYPE type = JOYSTICK_FEATURE_TYPE_UNKNOWN) :
m_name(name),
m_type(type),
m_primitives{}
{
}
JoystickFeature(const JoystickFeature& other)
{
*this = other;
}
explicit JoystickFeature(const JOYSTICK_FEATURE& feature) :
m_name(feature.name ? feature.name : ""),
m_type(feature.type)
{
for (unsigned int i = 0; i < JOYSTICK_PRIMITIVE_MAX; i++)
m_primitives[i] = DriverPrimitive(feature.primitives[i]);
}
JoystickFeature& operator=(const JoystickFeature& rhs)
{
if (this != &rhs)
{
m_name = rhs.m_name;
m_type = rhs.m_type;
m_primitives = rhs.m_primitives;
}
return *this;
}
bool operator==(const JoystickFeature& other) const
{
return m_name == other.m_name &&
m_type == other.m_type &&
m_primitives == other.m_primitives;
}
const std::string& Name(void) const { return m_name; }
JOYSTICK_FEATURE_TYPE Type(void) const { return m_type; }
bool IsValid() const { return m_type != JOYSTICK_FEATURE_TYPE_UNKNOWN; }
void SetName(const std::string& name) { m_name = name; }
void SetType(JOYSTICK_FEATURE_TYPE type) { m_type = type; }
void SetInvalid(void) { m_type = JOYSTICK_FEATURE_TYPE_UNKNOWN; }
const DriverPrimitive& Primitive(JOYSTICK_FEATURE_PRIMITIVE which) const { return m_primitives[which]; }
void SetPrimitive(JOYSTICK_FEATURE_PRIMITIVE which, const DriverPrimitive& primitive) { m_primitives[which] = primitive; }
std::array& Primitives() { return m_primitives; }
const std::array& Primitives() const { return m_primitives; }
void ToStruct(JOYSTICK_FEATURE& feature) const
{
feature.name = new char[m_name.length() + 1];
feature.type = m_type;
for (unsigned int i = 0; i < JOYSTICK_PRIMITIVE_MAX; i++)
m_primitives[i].ToStruct(feature.primitives[i]);
std::strcpy(feature.name, m_name.c_str());
}
static void FreeStruct(JOYSTICK_FEATURE& feature)
{
PERIPHERAL_SAFE_DELETE_ARRAY(feature.name);
}
private:
std::string m_name;
JOYSTICK_FEATURE_TYPE m_type;
std::array m_primitives;
};
typedef PeripheralVector JoystickFeatures;
} /* namespace addon */
} /* namespace kodi */