OpenSourceSimWheelESP32
Open-source wireless steering wheel/button box for ESP32 boards
Loading...
Searching...
No Matches
InternalServices.hpp
Go to the documentation of this file.
12#pragma once
13
14//-------------------------------------------------------------------
15// Imports
16//-------------------------------------------------------------------
17
18#include "InternalTypes.hpp"
19#include <cstdint>
20#include <type_traits>
21#include <cassert>
22#include <typeinfo>
23#include <vector>
24
25//-------------------------------------------------------------------
26// Global macros
27//-------------------------------------------------------------------
28
30#define MOCK \
31 { \
32 }
33
35#define MOCK_R(value) \
36 { \
37 return value; \
38 }
39
41#define SERVICE(ClassName) \
42 ClassName: \
43public \
44 DependencyManager<ClassName>
45
47#define VOID_SINGLETON_INVOKER(Decl, Call) \
48 static void Decl \
49 { \
50 getInstance()->Call; \
51 }
52
54#define SINGLETON_INVOKER(ReturnType, Decl, Call) \
55 static ReturnType Decl \
56 { \
57 return getInstance()->Call; \
58 }
59
61#define ALL_INVOKER(Decl, Call) \
62 static void Decl \
63 { \
64 auto instances = getAllInstances(); \
65 for (auto instance : instances) \
66 instance->Call; \
67 }
68
70#define BOTH_INVOKER(Decl, Call) \
71 static void Decl \
72 { \
73 getInstance()->Call; \
74 auto instances = getAllInstances(); \
75 for (auto instance : instances) \
76 instance->Call; \
77 }
78
79//-------------------------------------------------------------------
80// Dependency manager
81//-------------------------------------------------------------------
82
88template <typename Service>
90{
92 typedef std::vector<Service *> InstanceSet;
93
100 static Service *getInstance()
101 {
102 if constexpr ((std::is_abstract<Service>::value) || (!std::is_default_constructible<Service>::value))
103 {
104 assert((_singleton != nullptr) && "Provider not injected to Service");
105 }
106 else
107 {
108 if (_singleton == nullptr)
109 _singleton = new Service();
110 }
111 return _singleton;
112 }
113
120 static const InstanceSet getAllInstances() { return _instanceSet; }
121
130 template <typename Provider>
131 static void inject(Provider *instance, bool multipleInstances = false)
132 {
133 static_assert(std::is_base_of<Service, Provider>::value, "Provider is not derived from Service");
134 assert((instance != nullptr) && "A null provider is not allowed");
135 if (multipleInstances)
136 {
137 _instanceSet.push_back(instance);
138 }
139 else
140 {
141 assert((_singleton == nullptr) && "Provider already injected to service");
142 _singleton = instance;
143 }
144 }
145
151 static void reset()
152 {
153 if (_singleton != nullptr)
154 {
155 delete _singleton;
156 _singleton = nullptr;
157 }
158 for (auto instance : _instanceSet)
159 delete instance;
160 _instanceSet.clear();
161 }
162
163 virtual ~DependencyManager() = default;
164
165private:
166 inline static InstanceSet _instanceSet = {};
167 inline static Service *_singleton = nullptr;
168};
169
170//-------------------------------------------------------------------
171// Input service
172//-------------------------------------------------------------------
173
178class SERVICE(InputService)
179{
180public:
185 virtual void recalibrateAxes() MOCK;
186
192 virtual void reverseLeftAxis() MOCK;
193
199 virtual void reverseRightAxis() MOCK;
200
209 virtual void setRotaryPulseWidthMultiplier(
210 PulseWidthMultiplier multiplier,
211 bool save) MOCK;
212
218 virtual PulseWidthMultiplier getRotaryPulseWidthMultiplier() MOCK_R(PulseWidthMultiplier::X1);
219
233 virtual bool getAxisCalibration(
234 int &minLeft,
235 int &maxLeft,
236 int &minRight,
237 int &maxRight) MOCK_R(false);
238
250 virtual void setAxisCalibration(
251 int minLeft,
252 int maxLeft,
253 int minRight,
254 int maxRight,
255 bool save) MOCK;
256
263 virtual void getAxisPolarity(
264 bool &leftAxisReversed,
265 bool &rightAxisReversed) MOCK;
266
274 virtual void setAxisPolarity(
275 bool leftAxisReversed,
276 bool rightAxisReversed,
277 bool save) MOCK;
278
283 virtual void update() MOCK;
284
286
287 struct call
288 {
289 VOID_SINGLETON_INVOKER(recalibrateAxes(), recalibrateAxes())
290 VOID_SINGLETON_INVOKER(reverseLeftAxis(), reverseLeftAxis())
291 VOID_SINGLETON_INVOKER(reverseRightAxis(), reverseRightAxis())
293 setRotaryPulseWidthMultiplier(PulseWidthMultiplier multiplier, bool save = true),
294 setRotaryPulseWidthMultiplier(multiplier, save))
297 getRotaryPulseWidthMultiplier(),
298 getRotaryPulseWidthMultiplier())
300 bool,
301 getAxisCalibration(
302 int &minLeft,
303 int &maxLeft,
304 int &minRight,
305 int &maxRight),
306 getAxisCalibration(minLeft, maxLeft, minRight, maxRight))
308 setAxisCalibration(
309 int minLeft,
310 int maxLeft,
311 int minRight,
312 int maxRight,
313 bool save = true),
314 setAxisCalibration(minLeft, maxLeft, minRight, maxRight, save))
316 getAxisPolarity(
317 bool &leftAxisReversed,
318 bool &rightAxisReversed),
319 getAxisPolarity(
320 leftAxisReversed,
321 rightAxisReversed))
323 setAxisPolarity(
324 bool leftAxisReversed,
325 bool rightAxisReversed,
326 bool save = true),
327 setAxisPolarity(
328 leftAxisReversed,
329 rightAxisReversed,
330 save))
331 VOID_SINGLETON_INVOKER(update(), update());
332 };
333
335
336};
337
338//-------------------------------------------------------------------
339// Input hub service
340//-------------------------------------------------------------------
341
346class SERVICE(InputHubService)
347{
348public:
349 virtual bool getSecurityLock() MOCK_R(false);
350 virtual uint8_t getBitePoint() MOCK_R(CLUTCH_DEFAULT_VALUE);
351 virtual ClutchWorkingMode getClutchWorkingMode() MOCK_R(ClutchWorkingMode::_DEFAULT_VALUE);
352 virtual AltButtonsWorkingMode getAltButtonsWorkingMode() MOCK_R(AltButtonsWorkingMode::_DEFAULT_VALUE);
353 virtual DPadWorkingMode getDPadWorkingMode() MOCK_R(DPadWorkingMode::_DEFAULT_VALUE);
354 virtual void setBitePoint(uint8_t value, bool save) MOCK;
355 virtual void setClutchWorkingMode(ClutchWorkingMode mode, bool save) MOCK;
356 virtual void setAltButtonsWorkingMode(AltButtonsWorkingMode mode, bool save) MOCK;
357 virtual void setDPadWorkingMode(DPadWorkingMode mode, bool save) MOCK;
358 virtual void setSecurityLock(bool value, bool save) MOCK;
359
361
362 struct call
363 {
364 SINGLETON_INVOKER(bool, getSecurityLock(), getSecurityLock())
365 SINGLETON_INVOKER(uint8_t, getBitePoint(), getBitePoint())
366 SINGLETON_INVOKER(ClutchWorkingMode, getClutchWorkingMode(), getClutchWorkingMode())
367 SINGLETON_INVOKER(AltButtonsWorkingMode, getAltButtonsWorkingMode(), getAltButtonsWorkingMode())
368 SINGLETON_INVOKER(DPadWorkingMode, getDPadWorkingMode(), getDPadWorkingMode())
369
370 VOID_SINGLETON_INVOKER(setBitePoint(uint8_t value, bool save = true), setBitePoint(value, save))
372 setClutchWorkingMode(ClutchWorkingMode mode, bool save = true),
373 setClutchWorkingMode(mode, save))
375 setAltButtonsWorkingMode(AltButtonsWorkingMode mode, bool save = true),
376 setAltButtonsWorkingMode(mode, save))
378 setDPadWorkingMode(DPadWorkingMode mode, bool save = true),
379 setDPadWorkingMode(mode, save))
381 setSecurityLock(bool value, bool save = true),
382 setSecurityLock(value, save))
383 };
384
386
387};
388
389//-------------------------------------------------------------------
390// Input map service
391//-------------------------------------------------------------------
392
397class SERVICE(InputMapService)
398{
399public:
400 virtual void setMap(
401 uint8_t firmware_defined,
402 uint8_t user_defined,
403 uint8_t user_defined_alt) MOCK;
404 virtual void getMap(
405 uint8_t firmware_defined,
406 uint8_t &user_defined,
407 uint8_t &user_defined_alt)
408 {
409 user_defined = firmware_defined;
410 user_defined_alt = firmware_defined + 64;
411 };
412 virtual void resetMap() MOCK;
413
414 struct call
415 {
417 setMap(uint8_t firmware_defined, uint8_t user_defined, uint8_t user_defined_alt),
418 setMap(firmware_defined, user_defined, user_defined_alt))
420 getMap(uint8_t firmware_defined, uint8_t &user_defined, uint8_t &user_defined_alt),
421 getMap(firmware_defined, user_defined, user_defined_alt))
422 VOID_SINGLETON_INVOKER(resetMap(), resetMap())
423 };
424};
425
426//-------------------------------------------------------------------
427// Power service
428//-------------------------------------------------------------------
429
434class SERVICE(PowerService)
435{
436public:
437 virtual void shutdown() MOCK;
438
439 struct call
440 {
441 VOID_SINGLETON_INVOKER(shutdown(), shutdown())
442 };
443};
444
445//-------------------------------------------------------------------
446// Battery service
447//-------------------------------------------------------------------
448
453class SERVICE(BatteryService)
454{
455public:
460 virtual int getLastBatteryLevel() MOCK_R(0);
461
470 virtual bool hasBattery() MOCK_R(false);
471
482 virtual bool isBatteryPresent() MOCK_R(false);
483
489 virtual void getStatus(BatteryStatus &status) MOCK;
490
491 struct call
492 {
493 SINGLETON_INVOKER(int, getLastBatteryLevel(), getLastBatteryLevel())
494 SINGLETON_INVOKER(bool, hasBattery(), hasBattery())
495 SINGLETON_INVOKER(bool, isBatteryPresent(), isBatteryPresent())
497 getStatus(BatteryStatus &status),
498 getStatus(status))
499 };
500};
501
502//-------------------------------------------------------------------
503// Battery calibration
504//-------------------------------------------------------------------
505
510class SERVICE(BatteryCalibrationService)
511{
512public:
517 virtual void restartAutoCalibration() MOCK;
518
526 virtual int getBatteryLevel(int reading) MOCK_R(-1);
527
541 virtual int getBatteryLevelAutoCalibrated(int reading) MOCK_R(0);
542
547 virtual uint8_t getCalibrationDataCount() MOCK_R(0);
548
555 virtual uint16_t getCalibrationData(uint8_t index) MOCK_R(0);
556
564 virtual void setCalibrationData(uint8_t index, uint16_t data, bool save) MOCK;
565
571 virtual int getAutoCalibrationParameter() MOCK_R(-1);
572
579 virtual void setAutoCalibrationParameter(int value, bool save) MOCK;
580
582
583 struct call
584 {
585 VOID_SINGLETON_INVOKER(restartAutoCalibration(), restartAutoCalibration())
586 SINGLETON_INVOKER(int, getBatteryLevel(int reading), getBatteryLevel(reading))
587 SINGLETON_INVOKER(int, getBatteryLevelAutoCalibrated(int reading), getBatteryLevelAutoCalibrated(reading))
588 SINGLETON_INVOKER(uint8_t, getCalibrationDataCount(), getCalibrationDataCount())
589 SINGLETON_INVOKER(uint16_t, getCalibrationData(uint8_t index), getCalibrationData(index))
591 setCalibrationData(uint8_t index, uint16_t data, bool save = true),
592 setCalibrationData(index, data, save))
593 SINGLETON_INVOKER(int, getAutoCalibrationParameter(), getAutoCalibrationParameter())
595 setAutoCalibrationParameter(int value, bool save = true),
596 setAutoCalibrationParameter(value, save))
597 };
598
600};
601
602//-------------------------------------------------------------------
603// HID
604//-------------------------------------------------------------------
605
610class SERVICE(HidService)
611{
612public:
619 virtual void getCustomHardwareID(
620 uint16_t &customVID,
621 uint16_t &customPID) MOCK;
622
634 virtual void setCustomHardwareID(
635 uint16_t customVID,
636 uint16_t customPID,
637 bool save) MOCK;
638
639 struct call
640 {
642 getCustomHardwareID(uint16_t &customVID, uint16_t &customPID),
643 getCustomHardwareID(customVID, customPID))
645 setCustomHardwareID(uint16_t customVID, uint16_t customPID, bool save = true),
646 setCustomHardwareID(customVID, customPID, save))
647 };
648};
649
650//-------------------------------------------------------------------
651// UI
652//-------------------------------------------------------------------
653
658class SERVICE(UIService)
659{
660public:
661 virtual uint8_t getMaxFPS() MOCK_R(0);
662
663 struct call
664 {
665 SINGLETON_INVOKER(uint8_t, getMaxFPS(), getMaxFPS())
666 };
667};
668
669//-------------------------------------------------------------------
670// Firmware
671//-------------------------------------------------------------------
672
677class SERVICE(FirmwareService)
678{
679 friend void firmwareSetIsRunningState(bool state);
680
681public:
682 virtual bool isRunning() MOCK_R(_is_running);
683
684 struct call
685 {
686 SINGLETON_INVOKER(bool, isRunning(), isRunning())
687 };
688
689private:
690 inline static bool _is_running = false;
691};
#define VOID_SINGLETON_INVOKER(Decl, Call)
Macro to declare a void static method in a service class.
#define SINGLETON_INVOKER(ReturnType, Decl, Call)
Macro to declare a non-void static method in a service class.
#define SERVICE(ClassName)
Macro to declare an internal service class.
#define MOCK
Macro to mark a mock implementation for void methods.
#define MOCK_R(value)
Macro to mark a mock implementation for non-void methods.
Types and constants used everywhere for firmware implementation.
ClutchWorkingMode
User-selected working mode of the clutch paddles.
PulseWidthMultiplier
User-selected pulse width multiplier.
AltButtonsWorkingMode
User-selected working mode of "ALT" buttons.
DPadWorkingMode
User-selected working mode of directional pads.
#define CLUTCH_DEFAULT_VALUE
Default bite point value.
Battery status.
Dependency Manager.
static void inject(Provider *instance, bool multipleInstances=false)
Inject an instance of the service provider to the service interface.
static const InstanceSet getAllInstances()
Get all instances of the service provider.
static Service * getInstance()
Get a singleton instance of the service provider.
std::vector< Service * > InstanceSet
Type of the set of injected instances.
static void reset()
Remove all injected service providers (for testing)