[Windows] Fix driver version detection of AMD RDNA+ GPU on Windows 10
[xbmc.git] / xbmc / addons / binary-addons / AddonInstanceHandler.cpp
blob34c303b965901033c9a9802ef421dc9e4cb88303
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "AddonInstanceHandler.h"
11 #include "ServiceBroker.h"
12 #include "addons/AddonVersion.h"
13 #include "addons/binary-addons/AddonDll.h"
14 #include "addons/binary-addons/BinaryAddonManager.h"
15 #include "addons/interfaces/AddonBase.h"
16 #include "addons/kodi-dev-kit/include/kodi/AddonBase.h"
17 #include "addons/settings/AddonSettings.h"
18 #include "filesystem/Directory.h"
19 #include "filesystem/SpecialProtocol.h"
20 #include "settings/lib/Setting.h"
21 #include "utils/StringUtils.h"
22 #include "utils/log.h"
24 #include <mutex>
26 namespace ADDON
29 CCriticalSection IAddonInstanceHandler::m_cdSec;
31 IAddonInstanceHandler::IAddonInstanceHandler(
32 ADDON_TYPE type,
33 const AddonInfoPtr& addonInfo,
34 AddonInstanceId instanceId /* = ADDON_INSTANCE_ID_UNUSED */,
35 KODI_HANDLE parentInstance /* = nullptr*/,
36 const std::string& uniqueWorkID /* = ""*/)
37 : m_type(type), m_instanceId(instanceId), m_parentInstance(parentInstance), m_addonInfo(addonInfo)
39 // if no special instance ID is given generate one from class pointer (is
40 // faster as unique id and also safe enough for them).
41 m_uniqueWorkID = !uniqueWorkID.empty() ? uniqueWorkID : StringUtils::Format("{}", fmt::ptr(this));
42 m_addonBase = CServiceBroker::GetBinaryAddonManager().GetAddonBase(addonInfo, this, m_addon);
44 KODI_ADDON_INSTANCE_INFO* info = new KODI_ADDON_INSTANCE_INFO();
45 info->number = m_instanceId; // @todo change within next big API change to "instance_id"
46 info->id = m_uniqueWorkID.c_str(); // @todo change within next big API change to "unique_work_id"
47 info->version = kodi::addon::GetTypeVersion(m_type);
48 info->type = m_type;
49 info->kodi = this;
50 info->parent = m_parentInstance;
51 info->first_instance = m_addon && !m_addon->Initialized();
52 info->functions = new KODI_ADDON_INSTANCE_FUNC_CB();
53 info->functions->get_instance_user_path = get_instance_user_path;
54 info->functions->is_instance_setting_using_default = is_instance_setting_using_default;
55 info->functions->get_instance_setting_bool = get_instance_setting_bool;
56 info->functions->get_instance_setting_int = get_instance_setting_int;
57 info->functions->get_instance_setting_float = get_instance_setting_float;
58 info->functions->get_instance_setting_string = get_instance_setting_string;
59 info->functions->set_instance_setting_bool = set_instance_setting_bool;
60 info->functions->set_instance_setting_int = set_instance_setting_int;
61 info->functions->set_instance_setting_float = set_instance_setting_float;
62 info->functions->set_instance_setting_string = set_instance_setting_string;
63 m_ifc.info = info;
64 m_ifc.functions = new KODI_ADDON_INSTANCE_FUNC();
67 IAddonInstanceHandler::~IAddonInstanceHandler()
69 CServiceBroker::GetBinaryAddonManager().ReleaseAddonBase(m_addonBase, this);
71 delete m_ifc.functions;
72 if (m_ifc.info)
73 delete m_ifc.info->functions;
74 delete m_ifc.info;
77 std::string IAddonInstanceHandler::ID() const
79 return m_addon ? m_addon->ID() : "";
82 std::string IAddonInstanceHandler::Name() const
84 return m_addon ? m_addon->Name() : "";
87 std::string IAddonInstanceHandler::Author() const
89 return m_addon ? m_addon->Author() : "";
92 std::string IAddonInstanceHandler::Icon() const
94 return m_addon ? m_addon->Icon() : "";
97 std::string IAddonInstanceHandler::Path() const
99 return m_addon ? m_addon->Path() : "";
102 std::string IAddonInstanceHandler::Profile() const
104 return m_addon ? m_addon->Profile() : "";
107 CAddonVersion IAddonInstanceHandler::Version() const
109 return m_addon ? m_addon->Version() : CAddonVersion();
112 ADDON_STATUS IAddonInstanceHandler::CreateInstance()
114 if (!m_addon)
115 return ADDON_STATUS_UNKNOWN;
117 std::unique_lock<CCriticalSection> lock(m_cdSec);
119 ADDON_STATUS status = m_addon->CreateInstance(&m_ifc);
120 if (status != ADDON_STATUS_OK)
122 CLog::Log(LOGERROR,
123 "IAddonInstanceHandler::{}: {} returned bad status \"{}\" during instance creation",
124 __func__, m_addon->ID(), kodi::addon::TranslateAddonStatus(status));
126 return status;
129 void IAddonInstanceHandler::DestroyInstance()
131 std::unique_lock<CCriticalSection> lock(m_cdSec);
132 if (m_addon)
133 m_addon->DestroyInstance(&m_ifc);
136 std::shared_ptr<CSetting> IAddonInstanceHandler::GetSetting(const std::string& setting)
138 if (!m_addon->HasSettings(m_instanceId))
140 CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - couldn't get settings for add-on '{}'",
141 __func__, Name());
142 return nullptr;
145 auto value = m_addon->GetSettings(m_instanceId)->GetSetting(setting);
146 if (value == nullptr)
148 CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - can't find setting '{}' in '{}'", __func__,
149 setting, Name());
150 return nullptr;
153 return value;
156 char* IAddonInstanceHandler::get_instance_user_path(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl)
158 IAddonInstanceHandler* instance = static_cast<IAddonInstanceHandler*>(hdl);
159 if (!instance)
160 return nullptr;
162 const std::string path = CSpecialProtocol::TranslatePath(instance->m_addon->Profile());
164 XFILE::CDirectory::Create(path);
165 return strdup(path.c_str());
168 bool IAddonInstanceHandler::is_instance_setting_using_default(
169 const KODI_ADDON_INSTANCE_BACKEND_HDL hdl, const char* id)
171 IAddonInstanceHandler* instance = static_cast<IAddonInstanceHandler*>(hdl);
172 if (!instance || !id)
173 return false;
175 auto setting = instance->GetSetting(id);
176 if (setting == nullptr)
177 return false;
179 return setting->IsDefault();
182 bool IAddonInstanceHandler::get_instance_setting_bool(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
183 const char* id,
184 bool* value)
186 IAddonInstanceHandler* instance = static_cast<IAddonInstanceHandler*>(hdl);
187 if (!instance || !id || !value)
188 return false;
190 auto setting = instance->GetSetting(id);
191 if (setting == nullptr)
192 return false;
194 if (setting->GetType() != SettingType::Boolean)
196 CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - setting '{}' is not a boolean in '{}'",
197 __func__, id, instance->Name());
198 return false;
201 *value = std::static_pointer_cast<CSettingBool>(setting)->GetValue();
202 return true;
205 bool IAddonInstanceHandler::get_instance_setting_int(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
206 const char* id,
207 int* value)
209 IAddonInstanceHandler* instance = static_cast<IAddonInstanceHandler*>(hdl);
210 if (!instance || !id || !value)
211 return false;
213 auto setting = instance->GetSetting(id);
214 if (setting == nullptr)
215 return false;
217 if (setting->GetType() != SettingType::Integer && setting->GetType() != SettingType::Number)
219 CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - setting '{}' is not a integer in '{}'",
220 __func__, id, instance->Name());
221 return false;
224 if (setting->GetType() == SettingType::Integer)
225 *value = std::static_pointer_cast<CSettingInt>(setting)->GetValue();
226 else
227 *value = static_cast<int>(std::static_pointer_cast<CSettingNumber>(setting)->GetValue());
228 return true;
231 bool IAddonInstanceHandler::get_instance_setting_float(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
232 const char* id,
233 float* value)
235 IAddonInstanceHandler* instance = static_cast<IAddonInstanceHandler*>(hdl);
236 if (!instance || !id || !value)
237 return false;
239 auto setting = instance->GetSetting(id);
240 if (setting == nullptr)
241 return false;
243 if (setting->GetType() != SettingType::Number)
245 CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - setting '{}' is not a number in '{}'",
246 __func__, id, instance->Name());
247 return false;
250 *value = static_cast<float>(std::static_pointer_cast<CSettingNumber>(setting)->GetValue());
251 return true;
254 bool IAddonInstanceHandler::get_instance_setting_string(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
255 const char* id,
256 char** value)
258 IAddonInstanceHandler* instance = static_cast<IAddonInstanceHandler*>(hdl);
259 if (!instance || !id || !value)
260 return false;
262 auto setting = instance->GetSetting(id);
263 if (setting == nullptr)
264 return false;
266 if (setting->GetType() != SettingType::String)
268 CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - setting '{}' is not a string in '{}'",
269 __func__, id, instance->Name());
270 return false;
273 *value = strdup(std::static_pointer_cast<CSettingString>(setting)->GetValue().c_str());
274 return true;
277 bool IAddonInstanceHandler::set_instance_setting_bool(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
278 const char* id,
279 bool value)
281 IAddonInstanceHandler* instance = static_cast<IAddonInstanceHandler*>(hdl);
282 if (!instance || !id)
283 return false;
285 if (Interface_Base::UpdateSettingInActiveDialog(instance->m_addon.get(), instance->m_instanceId,
286 id, value ? "true" : "false"))
287 return true;
289 if (!instance->m_addon->UpdateSettingBool(id, value, instance->m_instanceId))
291 CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - invalid setting type", __func__);
292 return false;
295 instance->m_addon->SaveSettings(instance->m_instanceId);
297 return true;
300 bool IAddonInstanceHandler::set_instance_setting_int(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
301 const char* id,
302 int value)
304 IAddonInstanceHandler* instance = static_cast<IAddonInstanceHandler*>(hdl);
305 if (!instance || !id)
307 CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - invalid data (instance='{}', id='{}')",
308 __func__, hdl, static_cast<const void*>(id));
310 return false;
313 if (Interface_Base::UpdateSettingInActiveDialog(instance->m_addon.get(), instance->m_instanceId,
314 id, std::to_string(value)))
315 return true;
317 if (!instance->m_addon->UpdateSettingInt(id, value, instance->m_instanceId))
319 CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - invalid setting type", __func__);
320 return false;
323 instance->m_addon->SaveSettings(instance->m_instanceId);
325 return true;
328 bool IAddonInstanceHandler::set_instance_setting_float(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
329 const char* id,
330 float value)
332 IAddonInstanceHandler* instance = static_cast<IAddonInstanceHandler*>(hdl);
333 if (!instance || !id)
335 CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - invalid data (instance='{}', id='{}')",
336 __func__, hdl, static_cast<const void*>(id));
338 return false;
341 if (Interface_Base::UpdateSettingInActiveDialog(instance->m_addon.get(), instance->m_instanceId,
342 id, StringUtils::Format("{:f}", value)))
343 return true;
345 if (!instance->m_addon->UpdateSettingNumber(id, static_cast<double>(value),
346 instance->m_instanceId))
348 CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - invalid setting type", __func__);
349 return false;
352 instance->m_addon->SaveSettings(instance->m_instanceId);
354 return true;
357 bool IAddonInstanceHandler::set_instance_setting_string(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
358 const char* id,
359 const char* value)
361 IAddonInstanceHandler* instance = static_cast<IAddonInstanceHandler*>(hdl);
362 if (!instance || !id || !value)
364 CLog::Log(LOGERROR,
365 "IAddonInstanceHandler::{} - invalid data (instance='{}', id='{}', value='{}')",
366 __func__, hdl, static_cast<const void*>(id), static_cast<const void*>(value));
368 return false;
371 if (Interface_Base::UpdateSettingInActiveDialog(instance->m_addon.get(), instance->m_instanceId,
372 id, value))
373 return true;
375 if (!instance->m_addon->UpdateSettingString(id, value, instance->m_instanceId))
377 CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - invalid setting type", __func__);
378 return false;
381 instance->m_addon->SaveSettings(instance->m_instanceId);
383 return true;
386 } /* namespace ADDON */