aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett Brown <themagnificentmrb@gmail.com>2023-02-23 21:28:00 -0800
committerGarrett Brown <themagnificentmrb@gmail.com>2023-02-24 15:14:38 -0800
commit6f1b87113e89864828b80bf146581af289bbc05e (patch)
tree29f968427c2c2a34fb16db5e523ceaa380e4abd0
parent0d769127fe62888b77f2c95aacee1e37a64b1a84 (diff)
Games: Keep controller profiles in sync
-rw-r--r--xbmc/games/controllers/ControllerManager.cpp33
-rw-r--r--xbmc/games/controllers/ControllerManager.h15
2 files changed, 47 insertions, 1 deletions
diff --git a/xbmc/games/controllers/ControllerManager.cpp b/xbmc/games/controllers/ControllerManager.cpp
index 95258c4de3..707733b2f9 100644
--- a/xbmc/games/controllers/ControllerManager.cpp
+++ b/xbmc/games/controllers/ControllerManager.cpp
@@ -10,21 +10,32 @@
#include "Controller.h"
#include "ControllerIDs.h"
+#include "addons/AddonEvents.h"
#include "addons/AddonManager.h"
#include "addons/addoninfo/AddonType.h"
+#include <mutex>
+
using namespace KODI;
using namespace GAME;
CControllerManager::CControllerManager(ADDON::CAddonMgr& addonManager)
: m_addonManager(addonManager)
{
+ m_addonManager.Events().Subscribe(this, &CControllerManager::OnEvent);
+}
+
+CControllerManager::~CControllerManager()
+{
+ m_addonManager.Events().Unsubscribe(this);
}
ControllerPtr CControllerManager::GetController(const std::string& controllerId)
{
using namespace ADDON;
+ std::lock_guard<CCriticalSection> lock(m_mutex);
+
ControllerPtr& cachedController = m_cache[controllerId];
if (!cachedController && m_failedControllers.find(controllerId) == m_failedControllers.end())
@@ -59,6 +70,8 @@ ControllerVector CControllerManager::GetControllers()
ControllerVector controllers;
+ std::lock_guard<CCriticalSection> lock(m_mutex);
+
VECADDONS addons;
if (m_addonManager.GetInstalledAddons(addons, AddonType::GAME_CONTROLLER))
{
@@ -76,6 +89,26 @@ ControllerVector CControllerManager::GetControllers()
return controllers;
}
+void CControllerManager::OnEvent(const ADDON::AddonEvent& event)
+{
+ if (typeid(event) == typeid(ADDON::AddonEvents::Enabled) || // Also called on install
+ typeid(event) == typeid(ADDON::AddonEvents::ReInstalled))
+ {
+ std::lock_guard<CCriticalSection> lock(m_mutex);
+
+ const std::string& addonId = event.addonId;
+
+ // Clear caches for add-on
+ auto it = m_cache.find(addonId);
+ if (it != m_cache.end())
+ m_cache.erase(it);
+
+ auto it2 = m_failedControllers.find(addonId);
+ if (it2 != m_failedControllers.end())
+ m_failedControllers.erase(it2);
+ }
+}
+
ControllerPtr CControllerManager::LoadController(const ADDON::AddonPtr& addon)
{
ControllerPtr controller = std::static_pointer_cast<CController>(addon);
diff --git a/xbmc/games/controllers/ControllerManager.h b/xbmc/games/controllers/ControllerManager.h
index 57177292a3..25ffe0fc88 100644
--- a/xbmc/games/controllers/ControllerManager.h
+++ b/xbmc/games/controllers/ControllerManager.h
@@ -10,11 +10,17 @@
#include "ControllerTypes.h"
#include "addons/IAddon.h"
+#include "threads/CriticalSection.h"
#include <map>
#include <set>
#include <string>
+namespace ADDON
+{
+struct AddonEvent;
+} // namespace ADDON
+
namespace KODI
{
namespace GAME
@@ -23,7 +29,7 @@ class CControllerManager
{
public:
CControllerManager(ADDON::CAddonMgr& addonManager);
- ~CControllerManager() = default;
+ ~CControllerManager();
/*!
* \brief Get a controller
@@ -67,6 +73,10 @@ public:
ControllerVector GetControllers();
private:
+ // Add-on event handler
+ void OnEvent(const ADDON::AddonEvent& event);
+
+ // Utility functions
ControllerPtr LoadController(const ADDON::AddonPtr& addon);
// Construction parameters
@@ -75,6 +85,9 @@ private:
// Controller state
std::map<std::string, ControllerPtr> m_cache;
std::set<std::string> m_failedControllers; // Controllers that failed to load
+
+ // Synchronization parameters
+ CCriticalSection m_mutex;
};
} // namespace GAME
} // namespace KODI