summaryrefslogtreecommitdiffstats
path: root/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/PeripheralUtils.h
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/PeripheralUtils.h')
-rw-r--r--xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/PeripheralUtils.h668
1 files changed, 668 insertions, 0 deletions
diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/PeripheralUtils.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/PeripheralUtils.h
new file mode 100644
index 0000000..8cfa91b
--- /dev/null
+++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/PeripheralUtils.h
@@ -0,0 +1,668 @@
1/*
2 * Copyright (C) 2014-2017 Team Kodi
3 * http://kodi.tv
4 *
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this Program; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 */
20#pragma once
21
22#include "Peripheral.h"
23
24#include <array> // Requires c++11
25#include <cstring>
26#include <map>
27#include <string>
28#include <vector>
29
30#define PERIPHERAL_SAFE_DELETE(x) do { delete (x); (x) = NULL; } while (0)
31#define PERIPHERAL_SAFE_DELETE_ARRAY(x) do { delete[] (x); (x) = NULL; } while (0)
32
33namespace kodi
34{
35namespace addon
36{
37 /*!
38 * Utility class to manipulate arrays of peripheral types.
39 */
40 template <class THE_CLASS, typename THE_STRUCT>
41 class PeripheralVector
42 {
43 public:
44 static void ToStructs(const std::vector<THE_CLASS>& vecObjects, THE_STRUCT** pStructs)
45 {
46 if (!pStructs)
47 return;
48
49 if (vecObjects.empty())
50 {
51 *pStructs = NULL;
52 }
53 else
54 {
55 (*pStructs) = new THE_STRUCT[vecObjects.size()];
56 for (unsigned int i = 0; i < vecObjects.size(); i++)
57 vecObjects.at(i).ToStruct((*pStructs)[i]);
58 }
59 }
60
61 static void ToStructs(const std::vector<THE_CLASS*>& vecObjects, THE_STRUCT** pStructs)
62 {
63 if (!pStructs)
64 return;
65
66 if (vecObjects.empty())
67 {
68 *pStructs = NULL;
69 }
70 else
71 {
72 *pStructs = new THE_STRUCT[vecObjects.size()];
73 for (unsigned int i = 0; i < vecObjects.size(); i++)
74 vecObjects.at(i)->ToStruct((*pStructs)[i]);
75 }
76 }
77
78 static void FreeStructs(unsigned int structCount, THE_STRUCT* structs)
79 {
80 if (structs)
81 {
82 for (unsigned int i = 0; i < structCount; i++)
83 THE_CLASS::FreeStruct(structs[i]);
84 }
85 PERIPHERAL_SAFE_DELETE_ARRAY(structs);
86 }
87 };
88
89 /*!
90 * ADDON::Peripheral
91 *
92 * Wrapper class providing peripheral information. Classes can extend
93 * Peripheral to inherit peripheral properties.
94 */
95 class Peripheral
96 {
97 public:
98 Peripheral(PERIPHERAL_TYPE type = PERIPHERAL_TYPE_UNKNOWN, const std::string& strName = "") :
99 m_type(type),
100 m_strName(strName),
101 m_vendorId(0),
102 m_productId(0),
103 m_index(0)
104 {
105 }
106
107 Peripheral(const PERIPHERAL_INFO& info) :
108 m_type(info.type),
109 m_strName(info.name ? info.name : ""),
110 m_vendorId(info.vendor_id),
111 m_productId(info.product_id),
112 m_index(info.index)
113 {
114 }
115
116 virtual ~Peripheral(void) = default;
117
118 PERIPHERAL_TYPE Type(void) const { return m_type; }
119 const std::string& Name(void) const { return m_strName; }
120 uint16_t VendorID(void) const { return m_vendorId; }
121 uint16_t ProductID(void) const { return m_productId; }
122 unsigned int Index(void) const { return m_index; }
123
124 // Derived property: VID and PID are 0x0000 if unknown
125 bool IsVidPidKnown(void) const { return m_vendorId != 0 || m_productId != 0; }
126
127 void SetType(PERIPHERAL_TYPE type) { m_type = type; }
128 void SetName(const std::string& strName) { m_strName = strName; }
129 void SetVendorID(uint16_t vendorId) { m_vendorId = vendorId; }
130 void SetProductID(uint16_t productId) { m_productId = productId; }
131 void SetIndex(unsigned int index) { m_index = index; }
132
133 void ToStruct(PERIPHERAL_INFO& info) const
134 {
135 info.type = m_type;
136 info.name = new char[m_strName.size() + 1];
137 info.vendor_id = m_vendorId;
138 info.product_id = m_productId;
139 info.index = m_index;
140
141 std::strcpy(info.name, m_strName.c_str());
142 }
143
144 static void FreeStruct(PERIPHERAL_INFO& info)
145 {
146 PERIPHERAL_SAFE_DELETE_ARRAY(info.name);
147 }
148
149 private:
150 PERIPHERAL_TYPE m_type;
151 std::string m_strName;
152 uint16_t m_vendorId;
153 uint16_t m_productId;
154 unsigned int m_index;
155 };
156
157 typedef PeripheralVector<Peripheral, PERIPHERAL_INFO> Peripherals;
158
159 /*!
160 * ADDON::PeripheralEvent
161 *
162 * Wrapper class for peripheral events.
163 */
164 class PeripheralEvent
165 {
166 public:
167 PeripheralEvent(void) :
168 m_event()
169 {
170 }
171
172 PeripheralEvent(unsigned int peripheralIndex, unsigned int buttonIndex, JOYSTICK_STATE_BUTTON state) :
173 m_event()
174 {
175 SetType(PERIPHERAL_EVENT_TYPE_DRIVER_BUTTON);
176 SetPeripheralIndex(peripheralIndex);
177 SetDriverIndex(buttonIndex);
178 SetButtonState(state);
179 }
180
181 PeripheralEvent(unsigned int peripheralIndex, unsigned int hatIndex, JOYSTICK_STATE_HAT state) :
182 m_event()
183 {
184 SetType(PERIPHERAL_EVENT_TYPE_DRIVER_HAT);
185 SetPeripheralIndex(peripheralIndex);
186 SetDriverIndex(hatIndex);
187 SetHatState(state);
188 }
189
190 PeripheralEvent(unsigned int peripheralIndex, unsigned int axisIndex, JOYSTICK_STATE_AXIS state) :
191 m_event()
192 {
193 SetType(PERIPHERAL_EVENT_TYPE_DRIVER_AXIS);
194 SetPeripheralIndex(peripheralIndex);
195 SetDriverIndex(axisIndex);
196 SetAxisState(state);
197 }
198
199 PeripheralEvent(const PERIPHERAL_EVENT& event) :
200 m_event(event)
201 {
202 }
203
204 PERIPHERAL_EVENT_TYPE Type(void) const { return m_event.type; }
205 unsigned int PeripheralIndex(void) const { return m_event.peripheral_index; }
206 unsigned int DriverIndex(void) const { return m_event.driver_index; }
207 JOYSTICK_STATE_BUTTON ButtonState(void) const { return m_event.driver_button_state; }
208 JOYSTICK_STATE_HAT HatState(void) const { return m_event.driver_hat_state; }
209 JOYSTICK_STATE_AXIS AxisState(void) const { return m_event.driver_axis_state; }
210 JOYSTICK_STATE_MOTOR MotorState(void) const { return m_event.motor_state; }
211
212 void SetType(PERIPHERAL_EVENT_TYPE type) { m_event.type = type; }
213 void SetPeripheralIndex(unsigned int index) { m_event.peripheral_index = index; }
214 void SetDriverIndex(unsigned int index) { m_event.driver_index = index; }
215 void SetButtonState(JOYSTICK_STATE_BUTTON state) { m_event.driver_button_state = state; }
216 void SetHatState(JOYSTICK_STATE_HAT state) { m_event.driver_hat_state = state; }
217 void SetAxisState(JOYSTICK_STATE_AXIS state) { m_event.driver_axis_state = state; }
218 void SetMotorState(JOYSTICK_STATE_MOTOR state) { m_event.motor_state = state; }
219
220 void ToStruct(PERIPHERAL_EVENT& event) const
221 {
222 event = m_event;
223 }
224
225 static void FreeStruct(PERIPHERAL_EVENT& event)
226 {
227 (void)event;
228 }
229
230 private:
231 PERIPHERAL_EVENT m_event;
232 };
233
234 typedef PeripheralVector<PeripheralEvent, PERIPHERAL_EVENT> PeripheralEvents;
235
236 /*!
237 * kodi::addon::Joystick
238 *
239 * Wrapper class providing additional joystick information not provided by
240 * ADDON::Peripheral.
241 */
242 class Joystick : public Peripheral
243 {
244 public:
245 Joystick(const std::string& provider = "", const std::string& strName = "") :
246 Peripheral(PERIPHERAL_TYPE_JOYSTICK, strName),
247 m_provider(provider),
248 m_requestedPort(NO_PORT_REQUESTED),
249 m_buttonCount(0),
250 m_hatCount(0),
251 m_axisCount(0),
252 m_motorCount(0),
253 m_supportsPowerOff(false)
254 {
255 }
256
257 Joystick(const Joystick& other)
258 {
259 *this = other;
260 }
261
262 Joystick(const JOYSTICK_INFO& info) :
263 Peripheral(info.peripheral),
264 m_provider(info.provider ? info.provider : ""),
265 m_requestedPort(info.requested_port),
266 m_buttonCount(info.button_count),
267 m_hatCount(info.hat_count),
268 m_axisCount(info.axis_count),
269 m_motorCount(info.motor_count),
270 m_supportsPowerOff(info.supports_poweroff)
271 {
272 }
273
274 ~Joystick(void) override = default;
275
276 Joystick& operator=(const Joystick& rhs)
277 {
278 if (this != &rhs)
279 {
280 Peripheral::operator=(rhs);
281
282 m_provider = rhs.m_provider;
283 m_requestedPort = rhs.m_requestedPort;
284 m_buttonCount = rhs.m_buttonCount;
285 m_hatCount = rhs.m_hatCount;
286 m_axisCount = rhs.m_axisCount;
287 m_motorCount = rhs.m_motorCount;
288 m_supportsPowerOff = rhs.m_supportsPowerOff;
289 }
290 return *this;
291 }
292
293 const std::string& Provider(void) const { return m_provider; }
294 int RequestedPort(void) const { return m_requestedPort; }
295 unsigned int ButtonCount(void) const { return m_buttonCount; }
296 unsigned int HatCount(void) const { return m_hatCount; }
297 unsigned int AxisCount(void) const { return m_axisCount; }
298 unsigned int MotorCount(void) const { return m_motorCount; }
299 bool SupportsPowerOff(void) const { return m_supportsPowerOff; }
300
301 // Derived property: Counts are unknown if all are zero
302 bool AreElementCountsKnown(void) const { return m_buttonCount != 0 || m_hatCount != 0 || m_axisCount != 0; }
303
304 void SetProvider(const std::string& provider) { m_provider = provider; }
305 void SetRequestedPort(int requestedPort) { m_requestedPort = requestedPort; }
306 void SetButtonCount(unsigned int buttonCount) { m_buttonCount = buttonCount; }
307 void SetHatCount(unsigned int hatCount) { m_hatCount = hatCount; }
308 void SetAxisCount(unsigned int axisCount) { m_axisCount = axisCount; }
309 void SetMotorCount(unsigned int motorCount) { m_motorCount = motorCount; }
310 void SetSupportsPowerOff(bool supportsPowerOff) { m_supportsPowerOff = supportsPowerOff; }
311
312 void ToStruct(JOYSTICK_INFO& info) const
313 {
314 Peripheral::ToStruct(info.peripheral);
315
316 info.provider = new char[m_provider.size() + 1];
317 info.requested_port = m_requestedPort;
318 info.button_count = m_buttonCount;
319 info.hat_count = m_hatCount;
320 info.axis_count = m_axisCount;
321 info.motor_count = m_motorCount;
322 info.supports_poweroff = m_supportsPowerOff;
323
324 std::strcpy(info.provider, m_provider.c_str());
325 }
326
327 static void FreeStruct(JOYSTICK_INFO& info)
328 {
329 Peripheral::FreeStruct(info.peripheral);
330
331 PERIPHERAL_SAFE_DELETE_ARRAY(info.provider);
332 }
333
334 private:
335 std::string m_provider;
336 int m_requestedPort;
337 unsigned int m_buttonCount;
338 unsigned int m_hatCount;
339 unsigned int m_axisCount;
340 unsigned int m_motorCount;
341 bool m_supportsPowerOff;
342 };
343
344 typedef PeripheralVector<Joystick, JOYSTICK_INFO> Joysticks;
345
346 /*!
347 * ADDON::DriverPrimitive
348 *
349 * Base class for joystick driver primitives. A driver primitive can be:
350 *
351 * 1) a button
352 * 2) a hat direction
353 * 3) a semiaxis (either the positive or negative half of an axis)
354 * 4) a motor
355 *
356 * The type determines the fields in use:
357 *
358 * Button:
359 * - driver index
360 *
361 * Hat direction:
362 * - driver index
363 * - hat direction
364 *
365 * Semiaxis:
366 * - driver index
367 * - center
368 * - semiaxis direction
369 * - range
370 *
371 * Motor:
372 * - driver index
373 */
374 struct DriverPrimitive
375 {
376 protected:
377 /*!
378 * \brief Construct a driver primitive of the specified type
379 */
380 DriverPrimitive(JOYSTICK_DRIVER_PRIMITIVE_TYPE type, unsigned int driverIndex) :
381 m_type(type),
382 m_driverIndex(driverIndex),
383 m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN),
384 m_center(0),
385 m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN),
386 m_range(1)
387 {
388 }
389
390 public:
391 /*!
392 * \brief Construct an invalid driver primitive
393 */
394 DriverPrimitive(void) :
395 m_type(JOYSTICK_DRIVER_PRIMITIVE_TYPE_UNKNOWN),
396 m_driverIndex(0),
397 m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN),
398 m_center(0),
399 m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN),
400 m_range(1)
401 {
402 }
403
404 /*!
405 * \brief Construct a driver primitive representing a button
406 */
407 static DriverPrimitive CreateButton(unsigned int buttonIndex)
408 {
409 return DriverPrimitive(JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON, buttonIndex);
410 }
411
412 /*!
413 * \brief Construct a driver primitive representing one of the four direction
414 * arrows on a dpad
415 */
416 DriverPrimitive(unsigned int hatIndex, JOYSTICK_DRIVER_HAT_DIRECTION direction) :
417 m_type(JOYSTICK_DRIVER_PRIMITIVE_TYPE_HAT_DIRECTION),
418 m_driverIndex(hatIndex),
419 m_hatDirection(direction),
420 m_center(0),
421 m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN),
422 m_range(1)
423 {
424 }
425
426 /*!
427 * \brief Construct a driver primitive representing the positive or negative
428 * half of an axis
429 */
430 DriverPrimitive(unsigned int axisIndex, int center, JOYSTICK_DRIVER_SEMIAXIS_DIRECTION direction, unsigned int range) :
431 m_type(JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS),
432 m_driverIndex(axisIndex),
433 m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN),
434 m_center(center),
435 m_semiAxisDirection(direction),
436 m_range(range)
437 {
438 }
439
440 /*!
441 * \brief Construct a driver primitive representing a motor
442 */
443 static DriverPrimitive CreateMotor(unsigned int motorIndex)
444 {
445 return DriverPrimitive(JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR, motorIndex);
446 }
447
448 DriverPrimitive(const JOYSTICK_DRIVER_PRIMITIVE& primitive) :
449 m_type(primitive.type),
450 m_driverIndex(0),
451 m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN),
452 m_center(0),
453 m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN),
454 m_range(1)
455 {
456 switch (m_type)
457 {
458 case JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON:
459 {
460 m_driverIndex = primitive.button.index;
461 break;
462 }
463 case JOYSTICK_DRIVER_PRIMITIVE_TYPE_HAT_DIRECTION:
464 {
465 m_driverIndex = primitive.hat.index;
466 m_hatDirection = primitive.hat.direction;
467 break;
468 }
469 case JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS:
470 {
471 m_driverIndex = primitive.semiaxis.index;
472 m_center = primitive.semiaxis.center;
473 m_semiAxisDirection = primitive.semiaxis.direction;
474 m_range = primitive.semiaxis.range;
475 break;
476 }
477 case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR:
478 {
479 m_driverIndex = primitive.motor.index;
480 break;
481 }
482 default:
483 break;
484 }
485 }
486
487 JOYSTICK_DRIVER_PRIMITIVE_TYPE Type(void) const { return m_type; }
488 unsigned int DriverIndex(void) const { return m_driverIndex; }
489 JOYSTICK_DRIVER_HAT_DIRECTION HatDirection(void) const { return m_hatDirection; }
490 int Center(void) const { return m_center; }
491 JOYSTICK_DRIVER_SEMIAXIS_DIRECTION SemiAxisDirection(void) const { return m_semiAxisDirection; }
492 unsigned int Range(void) const { return m_range; }
493
494 bool operator==(const DriverPrimitive& other) const
495 {
496 if (m_type == other.m_type)
497 {
498 switch (m_type)
499 {
500 case JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON:
501 case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR:
502 {
503 return m_driverIndex == other.m_driverIndex;
504 }
505 case JOYSTICK_DRIVER_PRIMITIVE_TYPE_HAT_DIRECTION:
506 {
507 return m_driverIndex == other.m_driverIndex &&
508 m_hatDirection == other.m_hatDirection;
509 }
510 case JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS:
511 {
512 return m_driverIndex == other.m_driverIndex &&
513 m_center == other.m_center &&
514 m_semiAxisDirection == other.m_semiAxisDirection &&
515 m_range == other.m_range;
516 }
517 default:
518 break;
519 }
520 }
521 return false;
522 }
523
524 void ToStruct(JOYSTICK_DRIVER_PRIMITIVE& driver_primitive) const
525 {
526 driver_primitive.type = m_type;
527 switch (m_type)
528 {
529 case JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON:
530 {
531 driver_primitive.button.index = m_driverIndex;
532 break;
533 }
534 case JOYSTICK_DRIVER_PRIMITIVE_TYPE_HAT_DIRECTION:
535 {
536 driver_primitive.hat.index = m_driverIndex;
537 driver_primitive.hat.direction = m_hatDirection;
538 break;
539 }
540 case JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS:
541 {
542 driver_primitive.semiaxis.index = m_driverIndex;
543 driver_primitive.semiaxis.center = m_center;
544 driver_primitive.semiaxis.direction = m_semiAxisDirection;
545 driver_primitive.semiaxis.range = m_range;
546 break;
547 }
548 case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR:
549 {
550 driver_primitive.motor.index = m_driverIndex;
551 break;
552 }
553 default:
554 break;
555 }
556 }
557
558 static void FreeStruct(JOYSTICK_DRIVER_PRIMITIVE& primitive)
559 {
560 (void)primitive;
561 }
562
563 private:
564 JOYSTICK_DRIVER_PRIMITIVE_TYPE m_type;
565 unsigned int m_driverIndex;
566 JOYSTICK_DRIVER_HAT_DIRECTION m_hatDirection;
567 int m_center;
568 JOYSTICK_DRIVER_SEMIAXIS_DIRECTION m_semiAxisDirection;
569 unsigned int m_range;
570 };
571
572 typedef PeripheralVector<DriverPrimitive, JOYSTICK_DRIVER_PRIMITIVE> DriverPrimitives;
573
574 /*!
575 * kodi::addon::JoystickFeature
576 *
577 * Class for joystick features. A feature can be:
578 *
579 * 1) scalar[1]
580 * 2) analog stick
581 * 3) accelerometer
582 * 4) motor
583 *
584 * [1] All three driver primitives (buttons, hats and axes) have a state that
585 * can be represented using a single scalar value. For this reason,
586 * features that map to a single primitive are called "scalar features".
587 */
588 class JoystickFeature
589 {
590 public:
591 JoystickFeature(const std::string& name = "", JOYSTICK_FEATURE_TYPE type = JOYSTICK_FEATURE_TYPE_UNKNOWN) :
592 m_name(name),
593 m_type(type),
594 m_primitives()
595 {
596 }
597
598 JoystickFeature(const JoystickFeature& other)
599 {
600 *this = other;
601 }
602
603 JoystickFeature(const JOYSTICK_FEATURE& feature) :
604 m_name(feature.name ? feature.name : ""),
605 m_type(feature.type)
606 {
607 for (unsigned int i = 0; i < JOYSTICK_PRIMITIVE_MAX; i++)
608 m_primitives[i] = feature.primitives[i];
609 }
610
611 JoystickFeature& operator=(const JoystickFeature& rhs)
612 {
613 if (this != &rhs)
614 {
615 m_name = rhs.m_name;
616 m_type = rhs.m_type;
617 m_primitives = rhs.m_primitives;
618 }
619 return *this;
620 }
621
622 bool operator==(const JoystickFeature& other) const
623 {
624 return m_name == other.m_name &&
625 m_type == other.m_type &&
626 m_primitives == other.m_primitives;
627 }
628
629 const std::string& Name(void) const { return m_name; }
630 JOYSTICK_FEATURE_TYPE Type(void) const { return m_type; }
631 bool IsValid() const { return m_type != JOYSTICK_FEATURE_TYPE_UNKNOWN; }
632
633 void SetName(const std::string& name) { m_name = name; }
634 void SetType(JOYSTICK_FEATURE_TYPE type) { m_type = type; }
635 void SetInvalid(void) { m_type = JOYSTICK_FEATURE_TYPE_UNKNOWN; }
636
637 const DriverPrimitive& Primitive(JOYSTICK_FEATURE_PRIMITIVE which) const { return m_primitives[which]; }
638 void SetPrimitive(JOYSTICK_FEATURE_PRIMITIVE which, const DriverPrimitive& primitive) { m_primitives[which] = primitive; }
639
640 std::array<DriverPrimitive, JOYSTICK_PRIMITIVE_MAX>& Primitives() { return m_primitives; }
641 const std::array<DriverPrimitive, JOYSTICK_PRIMITIVE_MAX>& Primitives() const { return m_primitives; }
642
643 void ToStruct(JOYSTICK_FEATURE& feature) const
644 {
645 feature.name = new char[m_name.length() + 1];
646 feature.type = m_type;
647 for (unsigned int i = 0; i < JOYSTICK_PRIMITIVE_MAX; i++)
648 m_primitives[i].ToStruct(feature.primitives[i]);
649
650 std::strcpy(feature.name, m_name.c_str());
651 }
652
653 static void FreeStruct(JOYSTICK_FEATURE& feature)
654 {
655 PERIPHERAL_SAFE_DELETE_ARRAY(feature.name);
656 }
657
658 private:
659 std::string m_name;
660 JOYSTICK_FEATURE_TYPE m_type;
661 std::array<DriverPrimitive, JOYSTICK_PRIMITIVE_MAX> m_primitives;
662 };
663
664 typedef PeripheralVector<JoystickFeature, JOYSTICK_FEATURE> JoystickFeatures;
665
666} /* namespace addon */
667} /* namespace kodi */
668