1 /*
2  *  Copyright (C) 2015-2020 Garrett Brown
3  *  Copyright (C) 2015-2020 Team Kodi
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSE.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "StorageTypes.h"
12 #include "buttonmapper/ButtonMapTypes.h"
13 #include "buttonmapper/JoystickFamily.h"
14 #include "utils/CommonMacros.h"
15 
16 #include <memory>
17 #include <string>
18 
19 class CPeripheralJoystick;
20 struct AddonProps_Peripheral;
21 
22 namespace kodi
23 {
24 namespace addon
25 {
26   class Joystick;
27 }
28 }
29 
30 namespace JOYSTICK
31 {
32   /*!
33    * \brief Helper functions for dealing with controllers and controller features
34    */
35   class IControllerHelper
36   {
37   public:
38     virtual ~IControllerHelper() = default;
39 
40     /*!
41      * \brief Return the type of the specified feature
42      *
43      * \param controllerId    The controller ID to check
44      * \param featureName     The feature to check
45      *
46      * \return The type of the feature, or JOYSTICK_FEATURE_TYPE_UNKNOWN if unknown
47      */
48     virtual JOYSTICK_FEATURE_TYPE FeatureType(const std::string& strControllerId, const std::string &featureName) = 0;
49   };
50 
51   class CButtonMapper;
52   class CDevice;
53   class IDatabase;
54 
55   class DLL_PRIVATE CStorageManager : public IControllerHelper
56   {
57   private:
58     CStorageManager(void);
59 
60   public:
61     static CStorageManager& Get(void);
62 
63     ~CStorageManager(void);
64 
65     /*!
66      * \brief Initialize storage manager
67      *
68      * \param peripheralLib The peripheral API helper library
69      * \param props used in add-on creation (TODO: Change to two strings)
70      *
71      * \return true if the storage manager has been initialized and can be safely used
72      */
73     bool Initialize(CPeripheralJoystick* peripheralLib);
74 
75     /*!
76      * \brief Deinitialize storage manager
77      */
78     void Deinitialize(void);
79 
80     /*!
81      * \brief Get the map of features to driver primitives from a storage backend
82      *
83      * \param joystick      The device's joystick properties; unknown values may be left at their default
84      * \param controller_id The controller profile being requested, e.g. game.controller.default
85      * \param features      The array of features and their driver primitives
86      */
87     void GetFeatures(const kodi::addon::Joystick& joystick,
88                      const std::string& strDeviceId,
89                      FeatureVector& features);
90 
91     /*!
92      * \brief Update button maps
93      *
94      * \param joystick      The device's joystick properties; unknown values may be left at their default
95      * \param controller_id The game controller profile being updated
96      * \param features      The array of features and their driver primitives
97      *
98      * \return true if features were mapped in a storage backend
99      */
100     bool MapFeatures(const kodi::addon::Joystick& joystick,
101                      const std::string& strDeviceId,
102                      const FeatureVector& features);
103 
104     /*!
105      * \brief Get the ignored primitives from a storage backend
106      *
107      * \param joystick      The device's joystick properties; unknown values may be left at their default
108      * \param primitives    The array of driver primitives
109      *
110      * \return true if results were loaded from a storage backend
111      */
112     void GetIgnoredPrimitives(const kodi::addon::Joystick& joystick, PrimitiveVector& primitives);
113 
114     /*!
115      * \brief Update the list of ignored driver primitives
116      *
117      * \param joystick      The device's joystick properties; unknown values may be left at their default
118      * \param primitives    The array of driver primitives
119      *
120      * \return true if driver primitives were set in a storage backend
121      */
122     bool SetIgnoredPrimitives(const kodi::addon::Joystick& joystick, const PrimitiveVector& primitives);
123 
124     /*!
125      * \brief Save the button map for the specified device
126      *
127      * \param deviceName The name of the device to reset
128      *
129      * \return true if the underlying storage was modified, false otherwise
130      */
131     bool SaveButtonMap(const kodi::addon::Joystick& joystick);
132 
133     /*!
134      * \brief Revert the button map to the last time it was loaded or committed to disk
135      *
136      * \param deviceName The name of the device to revert
137      * \param controllerId The controller ID to revert
138      *
139      * \return true if the underlying storage was modified, false otherwise
140      */
141     bool RevertButtonMap(const kodi::addon::Joystick& joystick);
142 
143     /*!
144      * \brief Reset the button map for the specified device and controller profile
145      *
146      * \param deviceName The name of the device to reset
147      * \param controllerId The controller ID to reset
148      *
149      * \return true if the underlying storage was modified, false otherwise
150      */
151     bool ResetButtonMap(const kodi::addon::Joystick& joystick, const std::string& strControllerId);
152 
153     /*!
154      * \brief Notify the frontend that button maps have changed
155      *
156      * \param[optional] deviceName The name of the device to refresh, or empty for all devices
157      * \param[optional] controllerId The controller ID to refresh, or empty for all controllers
158      */
159     void RefreshButtonMaps(const std::string& strDeviceName = "");
160 
161     // implementation of IControllerHelper
162     virtual JOYSTICK_FEATURE_TYPE FeatureType(const std::string& strControllerId, const std::string &featureName) override;
163 
164   private:
165     CPeripheralJoystick* m_peripheralLib;
166 
167     DatabaseVector                 m_databases;
168     std::unique_ptr<CButtonMapper> m_buttonMapper;
169     CJoystickFamilyManager         m_familyManager;
170   };
171 }
172