summaryrefslogtreecommitdiffstats
path: root/xbmc/addons/kodi-dev-kit/include/kodi/AddonBase.h
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2020-10-19 00:52:24 +0200
committermanuel <manuel@mausz.at>2020-10-19 00:52:24 +0200
commitbe933ef2241d79558f91796cc5b3a161f72ebf9c (patch)
treefe3ab2f130e20c99001f2d7a81d610c78c96a3f4 /xbmc/addons/kodi-dev-kit/include/kodi/AddonBase.h
parent5f8335c1e49ce108ef3481863833c98efa00411b (diff)
downloadkodi-pvr-build-be933ef2241d79558f91796cc5b3a161f72ebf9c.tar.gz
kodi-pvr-build-be933ef2241d79558f91796cc5b3a161f72ebf9c.tar.bz2
kodi-pvr-build-be933ef2241d79558f91796cc5b3a161f72ebf9c.zip
sync with upstream
Diffstat (limited to 'xbmc/addons/kodi-dev-kit/include/kodi/AddonBase.h')
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/AddonBase.h1322
1 files changed, 1322 insertions, 0 deletions
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/AddonBase.h b/xbmc/addons/kodi-dev-kit/include/kodi/AddonBase.h
new file mode 100644
index 0000000..6ab4159
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/AddonBase.h
@@ -0,0 +1,1322 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#pragma once
10
11#include "c-api/addon_base.h"
12#include "versions.h"
13
14#include <assert.h> /* assert */
15#include <stdarg.h> /* va_list, va_start, va_arg, va_end */
16
17#ifdef __cplusplus
18
19#include <cstdlib>
20#include <cstring>
21#include <ctime>
22#include <memory>
23#include <stdexcept>
24#include <string>
25#include <vector>
26
27#include "tools/StringUtils.h"
28
29namespace kodi
30{
31
32namespace gui
33{
34struct IRenderHelper;
35} // namespace gui
36
37//==============================================================================
38/// @ingroup cpp_kodi_Defs
39/// @defgroup cpp_kodi_Defs_HardwareContext using HardwareContext
40/// @brief **Hardware specific device context**\n
41/// This defines an independent value which is used for hardware and OS specific
42/// values.
43///
44/// This is basically a simple pointer which has to be changed to the desired
45/// format at the corresponding places using <b>`static_cast<...>(...)`</b>.
46///
47///
48///-------------------------------------------------------------------------
49///
50/// **Example:**
51/// ~~~~~~~~~~~~~{.cpp}
52/// #include <d3d11_1.h>
53/// ..
54/// // Note: Device() there is used inside addon child class about
55/// // kodi::addon::CInstanceVisualization
56/// ID3D11DeviceContext1* context = static_cast<ID3D11DeviceContext1*>(kodi::addon::CInstanceVisualization::Device());
57/// ..
58/// ~~~~~~~~~~~~~
59///
60///@{
61using HardwareContext = ADDON_HARDWARE_CONTEXT;
62///@}
63//------------------------------------------------------------------------------
64
65//==============================================================================
66/// @ingroup cpp_kodi_addon_addonbase_Defs
67/// @defgroup cpp_kodi_addon_addonbase_Defs_CSettingValue class CSettingValue
68/// @brief Inside addon main instance used helper class to give settings value.
69///
70/// This is used on @ref addon::CAddonBase::SetSetting() to inform addon about
71/// settings change by used. This becomes then used to give the related value
72/// name.
73///
74/// ----------------------------------------------------------------------------
75///
76/// @copydetails cpp_kodi_addon_addonbase_Defs_CSettingValue_Help
77///
78/// ----------------------------------------------------------------------------
79///
80/// **Here is a code example how this is used:**
81///
82/// ~~~~~~~~~~~~~{.cpp}
83/// #include <kodi/AddonBase.h>
84///
85/// enum myEnumValue
86/// {
87/// valueA,
88/// valueB,
89/// valueC
90/// };
91///
92/// std::string m_myStringValue;
93/// int m_myIntegerValue;
94/// bool m_myBooleanValue;
95/// float m_myFloatingPointValue;
96/// myEnumValue m_myEnumValue;
97///
98///
99/// ADDON_STATUS CMyAddon::SetSetting(const std::string& settingName, const kodi::CSettingValue& settingValue)
100/// {
101/// if (settingName == "my_string_value")
102/// m_myStringValue = settingValue.GetString();
103/// else if (settingName == "my_integer_value")
104/// m_myIntegerValue = settingValue.GetInt();
105/// else if (settingName == "my_boolean_value")
106/// m_myBooleanValue = settingValue.GetBoolean();
107/// else if (settingName == "my_float_value")
108/// m_myFloatingPointValue = settingValue.GetFloat();
109/// else if (settingName == "my_enum_value")
110/// m_myEnumValue = settingValue.GetEnum<myEnumValue>();
111/// }
112/// ~~~~~~~~~~~~~
113///
114/// @note The asked type should match the type used on settings.xml.
115///
116///@{
117class ATTRIBUTE_HIDDEN CSettingValue
118{
119public:
120 explicit CSettingValue(const void* settingValue) : m_settingValue(settingValue) {}
121
122 bool empty() const { return (m_settingValue == nullptr) ? true : false; }
123
124 /// @defgroup cpp_kodi_addon_addonbase_Defs_CSettingValue_Help Value Help
125 /// @ingroup cpp_kodi_addon_addonbase_Defs_CSettingValue
126 ///
127 /// <b>The following table contains values that can be set with @ref cpp_kodi_addon_addonbase_Defs_CSettingValue :</b>
128 /// | Name | Type | Get call
129 /// |------|------|----------
130 /// | **Settings value as string** | `std::string` | @ref CSettingValue::GetString "GetString"
131 /// | **Settings value as integer** | `int` | @ref CSettingValue::GetInt "GetInt"
132 /// | **Settings value as unsigned integer** | `unsigned int` | @ref CSettingValue::GetUInt "GetUInt"
133 /// | **Settings value as boolean** | `bool` | @ref CSettingValue::GetBoolean "GetBoolean"
134 /// | **Settings value as floating point** | `float` | @ref CSettingValue::GetFloat "GetFloat"
135 /// | **Settings value as enum** | `enum` | @ref CSettingValue::GetEnum "GetEnum"
136
137 /// @addtogroup cpp_kodi_addon_addonbase_Defs_CSettingValue
138 ///@{
139
140 /// @brief To get settings value as string.
141 std::string GetString() const { return (const char*)m_settingValue; }
142
143 /// @brief To get settings value as integer.
144 int GetInt() const { return *(const int*)m_settingValue; }
145
146 /// @brief To get settings value as unsigned integer.
147 unsigned int GetUInt() const { return *(const unsigned int*)m_settingValue; }
148
149 /// @brief To get settings value as boolean.
150 bool GetBoolean() const { return *(const bool*)m_settingValue; }
151
152 /// @brief To get settings value as floating point.
153 float GetFloat() const { return *(const float*)m_settingValue; }
154
155 /// @brief To get settings value as enum.
156 /// @note Inside settings.xml them stored as integer.
157 template<typename enumType>
158 enumType GetEnum() const
159 {
160 return static_cast<enumType>(*(const int*)m_settingValue);
161 }
162
163 ///@}
164
165private:
166 const void* m_settingValue;
167};
168///@}
169//------------------------------------------------------------------------------
170
171namespace addon
172{
173
174//==============================================================================
175/*
176 * Internal class to control various instance types with general parts defined
177 * here.
178 *
179 * Mainly is this currently used to identify requested instance types.
180 *
181 * @note This class is not need to know during add-on development thats why
182 * commented with "*".
183 */
184class ATTRIBUTE_HIDDEN IAddonInstance
185{
186public:
187 explicit IAddonInstance(ADDON_TYPE type, const std::string& version)
188 : m_type(type), m_kodiVersion(version)
189 {
190 }
191 virtual ~IAddonInstance() = default;
192
193 virtual ADDON_STATUS CreateInstance(int instanceType,
194 const std::string& instanceID,
195 KODI_HANDLE instance,
196 const std::string& version,
197 KODI_HANDLE& addonInstance)
198 {
199 return ADDON_STATUS_NOT_IMPLEMENTED;
200 }
201
202 const ADDON_TYPE m_type;
203 const std::string m_kodiVersion;
204 std::string m_id;
205};
206
207/*
208 * Internally used helper class to manage processing of a "C" structure in "CPP"
209 * class.
210 *
211 * At constant, the "C" structure is copied, otherwise the given pointer is
212 * superseded and is changeable.
213 *
214 * -----------------------------------------------------------------------------
215 *
216 * Example:
217 *
218 * ~~~~~~~~~~~~~{.cpp}
219 * extern "C" typedef struct C_SAMPLE_DATA
220 * {
221 * unsigned int iUniqueId;
222 * } C_SAMPLE_DATA;
223 *
224 * class CPPSampleData : public CStructHdl<CPPSampleData, C_SAMPLE_DATA>
225 * {
226 * public:
227 * CPPSampleData() = default;
228 * CPPSampleData(const CPPSampleData& sample) : CStructHdl(sample) { }
229 * CPPSampleData(const C_SAMPLE_DATA* sample) : CStructHdl(sample) { }
230 * CPPSampleData(C_SAMPLE_DATA* sample) : CStructHdl(sample) { }
231 *
232 * void SetUniqueId(unsigned int uniqueId) { m_cStructure->iUniqueId = uniqueId; }
233 * unsigned int GetUniqueId() const { return m_cStructure->iUniqueId; }
234 * };
235 *
236 * ~~~~~~~~~~~~~
237 *
238 * It also works with the following example:
239 *
240 * ~~~~~~~~~~~~~{.cpp}
241 * CPPSampleData test;
242 * // Some work
243 * C_SAMPLE_DATA* data = test;
244 * // Give "data" to Kodi
245 * ~~~~~~~~~~~~~
246 */
247template<class CPP_CLASS, typename C_STRUCT>
248class CStructHdl
249{
250public:
251 CStructHdl() : m_cStructure(new C_STRUCT()), m_owner(true) {}
252
253 CStructHdl(const CPP_CLASS& cppClass)
254 : m_cStructure(new C_STRUCT(*cppClass.m_cStructure)), m_owner(true)
255 {
256 }
257
258 CStructHdl(const C_STRUCT* cStructure) : m_cStructure(new C_STRUCT(*cStructure)), m_owner(true) {}
259
260 CStructHdl(C_STRUCT* cStructure) : m_cStructure(cStructure) { assert(cStructure); }
261
262 const CStructHdl& operator=(const CStructHdl& right)
263 {
264 assert(&right.m_cStructure);
265 if (m_cStructure && !m_owner)
266 {
267 memcpy(m_cStructure, right.m_cStructure, sizeof(C_STRUCT));
268 }
269 else
270 {
271 if (m_owner)
272 delete m_cStructure;
273 m_owner = true;
274 m_cStructure = new C_STRUCT(*right.m_cStructure);
275 }
276 return *this;
277 }
278
279 const CStructHdl& operator=(const C_STRUCT& right)
280 {
281 assert(&right);
282 if (m_cStructure && !m_owner)
283 {
284 memcpy(m_cStructure, &right, sizeof(C_STRUCT));
285 }
286 else
287 {
288 if (m_owner)
289 delete m_cStructure;
290 m_owner = true;
291 m_cStructure = new C_STRUCT(*right);
292 }
293 return *this;
294 }
295
296 virtual ~CStructHdl()
297 {
298 if (m_owner)
299 delete m_cStructure;
300 }
301
302 operator C_STRUCT*() { return m_cStructure; }
303 operator const C_STRUCT*() const { return m_cStructure; }
304
305 const C_STRUCT* GetCStructure() const { return m_cStructure; }
306
307protected:
308 C_STRUCT* m_cStructure = nullptr;
309
310private:
311 bool m_owner = false;
312};
313
314/// Add-on main instance class.
315class ATTRIBUTE_HIDDEN CAddonBase
316{
317public:
318 CAddonBase()
319 {
320 m_interface->toAddon->destroy = ADDONBASE_Destroy;
321 m_interface->toAddon->get_status = ADDONBASE_GetStatus;
322 m_interface->toAddon->create_instance = ADDONBASE_CreateInstance;
323 m_interface->toAddon->destroy_instance = ADDONBASE_DestroyInstance;
324 m_interface->toAddon->set_setting = ADDONBASE_SetSetting;
325 }
326
327 virtual ~CAddonBase() = default;
328
329 virtual ADDON_STATUS Create() { return ADDON_STATUS_OK; }
330
331 virtual ADDON_STATUS GetStatus() { return ADDON_STATUS_OK; }
332
333 //============================================================================
334 /// @ingroup cpp_kodi_addon_addonbase
335 /// @brief To inform addon about changed settings values.
336 ///
337 /// This becomes called for every entry defined inside his settings.xml and
338 /// as **last** call the one where last in xml (to identify end of calls).
339 ///
340 /// --------------------------------------------------------------------------
341 ///
342 /// @copydetails cpp_kodi_addon_addonbase_Defs_CSettingValue_Help
343 ///
344 ///
345 /// --------------------------------------------------------------------------
346 ///
347 /// **Here is a code example how this is used:**
348 ///
349 /// ~~~~~~~~~~~~~{.cpp}
350 /// #include <kodi/AddonBase.h>
351 ///
352 /// enum myEnumValue
353 /// {
354 /// valueA,
355 /// valueB,
356 /// valueC
357 /// };
358 ///
359 /// std::string m_myStringValue;
360 /// int m_myIntegerValue;
361 /// bool m_myBooleanValue;
362 /// float m_myFloatingPointValue;
363 /// myEnumValue m_myEnumValue;
364 ///
365 ///
366 /// ADDON_STATUS CMyAddon::SetSetting(const std::string& settingName, const kodi::CSettingValue& settingValue)
367 /// {
368 /// if (settingName == "my_string_value")
369 /// m_myStringValue = settingValue.GetString();
370 /// else if (settingName == "my_integer_value")
371 /// m_myIntegerValue = settingValue.GetInt();
372 /// else if (settingName == "my_boolean_value")
373 /// m_myBooleanValue = settingValue.GetBoolean();
374 /// else if (settingName == "my_float_value")
375 /// m_myFloatingPointValue = settingValue.GetFloat();
376 /// else if (settingName == "my_enum_value")
377 /// m_myEnumValue = settingValue.GetEnum<myEnumValue>();
378 /// }
379 /// ~~~~~~~~~~~~~
380 ///
381 /// @note The asked type should match the type used on settings.xml.
382 ///
383 virtual ADDON_STATUS SetSetting(const std::string& settingName,
384 const kodi::CSettingValue& settingValue)
385 {
386 return ADDON_STATUS_UNKNOWN;
387 }
388 //----------------------------------------------------------------------------
389
390 //==========================================================================
391 /// @ingroup cpp_kodi_addon_addonbase
392 /// @brief Instance created
393 ///
394 /// @param[in] instanceType The requested type of required instance, see \ref ADDON_TYPE.
395 /// @param[in] instanceID An individual identification key string given by Kodi.
396 /// @param[in] instance The instance handler used by Kodi must be passed to
397 /// the classes created here. See in the example.
398 /// @param[in] version The from Kodi used version of instance. This can be
399 /// used to allow compatibility to older versions of
400 /// them. Further is this given to the parent instance
401 /// that it can handle differences.
402 /// @param[out] addonInstance The pointer to instance class created in addon.
403 /// Needed to be able to identify them on calls.
404 /// @return \ref ADDON_STATUS_OK if correct, for possible errors
405 /// see \ref ADDON_STATUS
406 ///
407 ///
408 /// --------------------------------------------------------------------------
409 ///
410 /// **Here is a code example how this is used:**
411 ///
412 /// ~~~~~~~~~~~~~{.cpp}
413 /// #include <kodi/AddonBase.h>
414 ///
415 /// ...
416 ///
417 /// /* If you use only one instance in your add-on, can be instanceType and
418 /// * instanceID ignored */
419 /// ADDON_STATUS CMyAddon::CreateInstance(int instanceType,
420 /// const std::string& instanceID,
421 /// KODI_HANDLE instance,
422 /// const std::string& version,
423 /// KODI_HANDLE& addonInstance)
424 /// {
425 /// if (instanceType == ADDON_INSTANCE_SCREENSAVER)
426 /// {
427 /// kodi::Log(ADDON_LOG_INFO, "Creating my Screensaver");
428 /// addonInstance = new CMyScreensaver(instance);
429 /// return ADDON_STATUS_OK;
430 /// }
431 /// else if (instanceType == ADDON_INSTANCE_VISUALIZATION)
432 /// {
433 /// kodi::Log(ADDON_LOG_INFO, "Creating my Visualization");
434 /// addonInstance = new CMyVisualization(instance);
435 /// return ADDON_STATUS_OK;
436 /// }
437 /// else if (...)
438 /// {
439 /// ...
440 /// }
441 /// return ADDON_STATUS_UNKNOWN;
442 /// }
443 ///
444 /// ...
445 ///
446 /// ~~~~~~~~~~~~~
447 ///
448 virtual ADDON_STATUS CreateInstance(int instanceType,
449 const std::string& instanceID,
450 KODI_HANDLE instance,
451 const std::string& version,
452 KODI_HANDLE& addonInstance)
453 {
454 return ADDON_STATUS_NOT_IMPLEMENTED;
455 }
456 //--------------------------------------------------------------------------
457
458 //==========================================================================
459 /// @ingroup cpp_kodi_addon_addonbase
460 /// @brief Instance destroy
461 ///
462 /// This function is optional and intended to notify addon that the instance
463 /// is terminating.
464 ///
465 /// @param[in] instanceType The requested type of required instance, see \ref ADDON_TYPE.
466 /// @param[in] instanceID An individual identification key string given by Kodi.
467 /// @param[in] addonInstance The pointer to instance class created in addon.
468 ///
469 /// @warning This call is only used to inform that the associated instance
470 /// is terminated. The deletion is carried out in the background.
471 ///
472 virtual void DestroyInstance(int instanceType,
473 const std::string& instanceID,
474 KODI_HANDLE addonInstance)
475 {
476 }
477 //--------------------------------------------------------------------------
478
479 /* Background helper for GUI render systems, e.g. Screensaver or Visualization */
480 std::shared_ptr<kodi::gui::IRenderHelper> m_renderHelper;
481
482 /* Global variables of class */
483 static AddonGlobalInterface*
484 m_interface; // Interface function table to hold addresses on add-on and from kodi
485
486 /*private:*/ /* Needed public as long the old call functions becomes used! */
487 static inline void ADDONBASE_Destroy()
488 {
489 delete static_cast<CAddonBase*>(m_interface->addonBase);
490 m_interface->addonBase = nullptr;
491 }
492
493 static inline ADDON_STATUS ADDONBASE_GetStatus()
494 {
495 return static_cast<CAddonBase*>(m_interface->addonBase)->GetStatus();
496 }
497
498 static inline ADDON_STATUS ADDONBASE_SetSetting(const char* settingName, const void* settingValue)
499 {
500 return static_cast<CAddonBase*>(m_interface->addonBase)
501 ->SetSetting(settingName, CSettingValue(settingValue));
502 }
503
504private:
505 static inline ADDON_STATUS ADDONBASE_CreateInstance(int instanceType,
506 const char* instanceID,
507 KODI_HANDLE instance,
508 const char* version,
509 KODI_HANDLE* addonInstance,
510 KODI_HANDLE parent)
511 {
512 CAddonBase* base = static_cast<CAddonBase*>(m_interface->addonBase);
513
514 ADDON_STATUS status = ADDON_STATUS_NOT_IMPLEMENTED;
515
516 /* Check about single instance usage:
517 * 1. The kodi side instance pointer must be equal to first one
518 * 2. The addon side instance pointer must be set
519 * 3. And the requested type must be equal with used add-on class
520 */
521 if (m_interface->firstKodiInstance == instance && m_interface->globalSingleInstance &&
522 static_cast<IAddonInstance*>(m_interface->globalSingleInstance)->m_type == instanceType)
523 {
524 /* The handling here is intended for the case of the add-on only one
525 * instance and this is integrated in the add-on base class.
526 */
527 *addonInstance = m_interface->globalSingleInstance;
528 status = ADDON_STATUS_OK;
529 }
530 else
531 {
532 /* Here it should use the CreateInstance instance function to allow
533 * creation of several on one addon.
534 */
535
536 /* Check first a parent is defined about (e.g. Codec within inputstream) */
537 if (parent != nullptr)
538 status = static_cast<IAddonInstance*>(parent)->CreateInstance(
539 instanceType, instanceID, instance, version, *addonInstance);
540
541 /* if no parent call the main instance creation function to get it */
542 if (status == ADDON_STATUS_NOT_IMPLEMENTED)
543 {
544 status = base->CreateInstance(instanceType, instanceID, instance, version, *addonInstance);
545 }
546 }
547
548 if (*addonInstance == nullptr)
549 {
550 if (status == ADDON_STATUS_OK)
551 {
552 m_interface->toKodi->addon_log_msg(m_interface->toKodi->kodiBase, ADDON_LOG_FATAL,
553 "kodi::addon::CAddonBase CreateInstance returned an "
554 "empty instance pointer, but reported OK!");
555 return ADDON_STATUS_PERMANENT_FAILURE;
556 }
557 else
558 {
559 return status;
560 }
561 }
562
563 if (static_cast<IAddonInstance*>(*addonInstance)->m_type != instanceType)
564 {
565 m_interface->toKodi->addon_log_msg(
566 m_interface->toKodi->kodiBase, ADDON_LOG_FATAL,
567 "kodi::addon::CAddonBase CreateInstance difference between given and returned");
568 delete static_cast<IAddonInstance*>(*addonInstance);
569 *addonInstance = nullptr;
570 return ADDON_STATUS_PERMANENT_FAILURE;
571 }
572
573 // Store the used ID inside instance, to have on destroy calls by addon to identify
574 static_cast<IAddonInstance*>(*addonInstance)->m_id = instanceID;
575
576 return status;
577 }
578
579 static inline void ADDONBASE_DestroyInstance(int instanceType, KODI_HANDLE instance)
580 {
581 CAddonBase* base = static_cast<CAddonBase*>(m_interface->addonBase);
582
583 if (m_interface->globalSingleInstance == nullptr && instance != base)
584 {
585 base->DestroyInstance(instanceType, static_cast<IAddonInstance*>(instance)->m_id, instance);
586 delete static_cast<IAddonInstance*>(instance);
587 }
588 }
589};
590
591} /* namespace addon */
592
593//==============================================================================
594/// @ingroup cpp_kodi_addon
595/// @brief To get used version inside Kodi itself about asked type.
596///
597/// This thought to allow a addon a handling of newer addon versions within
598/// older Kodi until the type min version not changed.
599///
600/// @param[in] type The wanted type of @ref ADDON_TYPE to ask
601/// @return The version string about type in MAJOR.MINOR.PATCH style.
602///
603inline std::string ATTRIBUTE_HIDDEN GetKodiTypeVersion(int type)
604{
605 using namespace kodi::addon;
606
607 char* str = CAddonBase::m_interface->toKodi->get_type_version(
608 CAddonBase::m_interface->toKodi->kodiBase, type);
609 std::string ret = str;
610 CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, str);
611 return ret;
612}
613//------------------------------------------------------------------------------
614
615//==============================================================================
616///
617inline std::string ATTRIBUTE_HIDDEN GetAddonPath(const std::string& append = "")
618{
619 using namespace kodi::addon;
620
621 char* str =
622 CAddonBase::m_interface->toKodi->get_addon_path(CAddonBase::m_interface->toKodi->kodiBase);
623 std::string ret = str;
624 CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, str);
625 if (!append.empty())
626 {
627 if (append.at(0) != '\\' && append.at(0) != '/')
628#ifdef TARGET_WINDOWS
629 ret.append("\\");
630#else
631 ret.append("/");
632#endif
633 ret.append(append);
634 }
635 return ret;
636}
637//------------------------------------------------------------------------------
638
639//==============================================================================
640///
641inline std::string ATTRIBUTE_HIDDEN GetBaseUserPath(const std::string& append = "")
642{
643 using namespace kodi::addon;
644
645 char* str = CAddonBase::m_interface->toKodi->get_base_user_path(
646 CAddonBase::m_interface->toKodi->kodiBase);
647 std::string ret = str;
648 CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, str);
649 if (!append.empty())
650 {
651 if (append.at(0) != '\\' && append.at(0) != '/')
652#ifdef TARGET_WINDOWS
653 ret.append("\\");
654#else
655 ret.append("/");
656#endif
657 ret.append(append);
658 }
659 return ret;
660}
661//------------------------------------------------------------------------------
662
663//==============================================================================
664///
665inline std::string ATTRIBUTE_HIDDEN GetLibPath()
666{
667 using namespace kodi::addon;
668
669 return CAddonBase::m_interface->libBasePath;
670}
671//------------------------------------------------------------------------------
672
673//==============================================================================
674/// @ingroup cpp_kodi
675/// @brief Add a message to Kodi's log.
676///
677/// @param[in] loglevel The log level of the message.
678/// @param[in] format The format of the message to pass to Kodi.
679/// @param[in] ... Additional text to insert in format text
680///
681///
682/// @note This method uses limited buffer (16k) for the formatted output.
683/// So data, which will not fit into it, will be silently discarded.
684///
685///
686/// ----------------------------------------------------------------------------
687///
688/// **Example:**
689/// ~~~~~~~~~~~~~{.cpp}
690/// #include <kodi/General.h>
691///
692/// kodi::Log(ADDON_LOG_ERROR, "%s: There is an error occurred!", __func__);
693///
694/// ~~~~~~~~~~~~~
695///
696inline void ATTRIBUTE_HIDDEN Log(const AddonLog loglevel, const char* format, ...)
697{
698 using namespace kodi::addon;
699
700 va_list args;
701 va_start(args, format);
702 const std::string str = kodi::tools::StringUtils::FormatV(format, args);
703 va_end(args);
704 CAddonBase::m_interface->toKodi->addon_log_msg(CAddonBase::m_interface->toKodi->kodiBase,
705 loglevel, str.c_str());
706}
707//------------------------------------------------------------------------------
708
709//##############################################################################
710/// @ingroup cpp_kodi
711/// @defgroup cpp_kodi_settings 1. Setting control
712/// @brief **Functions to handle settings access**\n
713/// This can be used to get and set the addon related values inside his
714/// settings.xml.
715///
716/// The settings style is given with installed part on e.g.
717/// <b>`$HOME/.kodi/addons/myspecial.addon/resources/settings.xml`</b>. The
718/// related edit becomes then stored inside
719/// <b>`$HOME/.kodi/userdata/addon_data/myspecial.addon/settings.xml`</b>.
720///
721/*!@{*/
722
723//==============================================================================
724/// @brief Check the given setting name is set to default value.
725///
726/// The setting name relate to names used in his <b>settings.xml</b> file.
727///
728/// @param[in] settingName The name of asked setting
729/// @return true if setting is the default
730///
731inline bool ATTRIBUTE_HIDDEN IsSettingUsingDefault(const std::string& settingName)
732{
733 using namespace kodi::addon;
734 return CAddonBase::m_interface->toKodi->is_setting_using_default(
735 CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str());
736}
737//------------------------------------------------------------------------------
738
739//==============================================================================
740/// @brief Check and get a string setting value.
741///
742/// The setting name relate to names used in his <b>settings.xml</b> file.
743///
744/// @param[in] settingName The name of asked setting
745/// @param[out] settingValue The given setting value
746/// @return true if setting was successfully found and "settingValue" is set
747///
748/// @note If returns false, the "settingValue" is not changed.
749///
750///
751/// ----------------------------------------------------------------------------
752///
753/// **Example:**
754/// ~~~~~~~~~~~~~{.cpp}
755/// #include <kodi/General.h>
756///
757/// std::string value;
758/// if (!kodi::CheckSettingString("my_string_value", value))
759/// value = "my_default_if_setting_not_work";
760/// ~~~~~~~~~~~~~
761///
762inline bool ATTRIBUTE_HIDDEN CheckSettingString(const std::string& settingName,
763 std::string& settingValue)
764{
765 using namespace kodi::addon;
766
767 char* buffer = nullptr;
768 bool ret = CAddonBase::m_interface->toKodi->get_setting_string(
769 CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str(), &buffer);
770 if (buffer)
771 {
772 if (ret)
773 settingValue = buffer;
774 CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, buffer);
775 }
776 return ret;
777}
778//------------------------------------------------------------------------------
779
780//==============================================================================
781/// @brief Get string setting value.
782///
783/// The setting name relate to names used in his <b>settings.xml</b> file.
784///
785/// @param[in] settingName The name of asked setting
786/// @param[in] defaultValue [opt] Default value if not found
787/// @return The value of setting, empty if not found;
788///
789///
790/// ----------------------------------------------------------------------------
791///
792/// **Example:**
793/// ~~~~~~~~~~~~~{.cpp}
794/// #include <kodi/General.h>
795///
796/// std::string value = kodi::GetSettingString("my_string_value");
797/// ~~~~~~~~~~~~~
798///
799inline std::string ATTRIBUTE_HIDDEN GetSettingString(const std::string& settingName,
800 const std::string& defaultValue = "")
801{
802 std::string settingValue = defaultValue;
803 CheckSettingString(settingName, settingValue);
804 return settingValue;
805}
806//------------------------------------------------------------------------------
807
808//==============================================================================
809/// @brief Set string setting of addon.
810///
811/// The setting name relate to names used in his <b>settings.xml</b> file.
812///
813/// @param[in] settingName The name of setting
814/// @param[in] settingValue The setting value to write
815///
816///
817/// ----------------------------------------------------------------------------
818///
819/// **Example:**
820/// ~~~~~~~~~~~~~{.cpp}
821/// #include <kodi/General.h>
822///
823/// std::string value = "my_new_name for";
824/// kodi::SetSettingString("my_string_value", value);
825/// ~~~~~~~~~~~~~
826///
827inline void ATTRIBUTE_HIDDEN SetSettingString(const std::string& settingName,
828 const std::string& settingValue)
829{
830 using namespace kodi::addon;
831
832 CAddonBase::m_interface->toKodi->set_setting_string(CAddonBase::m_interface->toKodi->kodiBase,
833 settingName.c_str(), settingValue.c_str());
834}
835//------------------------------------------------------------------------------
836
837//==============================================================================
838/// @brief Check and get a integer setting value.
839///
840/// The setting name relate to names used in his <b>settings.xml</b> file.
841///
842/// @param[in] settingName The name of asked setting
843/// @param[out] settingValue The given setting value
844/// @return true if setting was successfully found and "settingValue" is set
845///
846/// @note If returns false, the "settingValue" is not changed.
847///
848///
849/// ----------------------------------------------------------------------------
850///
851/// **Example:**
852/// ~~~~~~~~~~~~~{.cpp}
853/// #include <kodi/General.h>
854///
855/// int value = 0;
856/// if (!kodi::CheckSettingInt("my_integer_value", value))
857/// value = 123; // My default of them
858/// ~~~~~~~~~~~~~
859///
860inline bool ATTRIBUTE_HIDDEN CheckSettingInt(const std::string& settingName, int& settingValue)
861{
862 using namespace kodi::addon;
863
864 return CAddonBase::m_interface->toKodi->get_setting_int(CAddonBase::m_interface->toKodi->kodiBase,
865 settingName.c_str(), &settingValue);
866}
867//------------------------------------------------------------------------------
868
869//==============================================================================
870/// @brief Get integer setting value.
871///
872/// The setting name relate to names used in his <b>settings.xml</b> file.
873///
874/// @param[in] settingName The name of asked setting
875/// @param[in] defaultValue [opt] Default value if not found
876/// @return The value of setting, <b>`0`</b> or defaultValue if not found
877///
878///
879/// ----------------------------------------------------------------------------
880///
881/// **Example:**
882/// ~~~~~~~~~~~~~{.cpp}
883/// #include <kodi/General.h>
884///
885/// int value = kodi::GetSettingInt("my_integer_value");
886/// ~~~~~~~~~~~~~
887///
888inline int ATTRIBUTE_HIDDEN GetSettingInt(const std::string& settingName, int defaultValue = 0)
889{
890 int settingValue = defaultValue;
891 CheckSettingInt(settingName, settingValue);
892 return settingValue;
893}
894//------------------------------------------------------------------------------
895
896//==============================================================================
897/// @brief Set integer setting of addon.
898///
899/// The setting name relate to names used in his <b>settings.xml</b> file.
900///
901/// @param[in] settingName The name of setting
902/// @param[in] settingValue The setting value to write
903///
904///
905/// ----------------------------------------------------------------------------
906///
907/// **Example:**
908/// ~~~~~~~~~~~~~{.cpp}
909/// #include <kodi/General.h>
910///
911/// int value = 123;
912/// kodi::SetSettingInt("my_integer_value", value);
913/// ~~~~~~~~~~~~~
914///
915inline void ATTRIBUTE_HIDDEN SetSettingInt(const std::string& settingName, int settingValue)
916{
917 using namespace kodi::addon;
918
919 CAddonBase::m_interface->toKodi->set_setting_int(CAddonBase::m_interface->toKodi->kodiBase,
920 settingName.c_str(), settingValue);
921}
922//------------------------------------------------------------------------------
923
924//==============================================================================
925/// @brief Check and get a boolean setting value.
926///
927/// The setting name relate to names used in his <b>settings.xml</b> file.
928///
929/// @param[in] settingName The name of asked setting
930/// @param[out] settingValue The given setting value
931/// @return true if setting was successfully found and "settingValue" is set
932///
933/// @note If returns false, the "settingValue" is not changed.
934///
935///
936/// ----------------------------------------------------------------------------
937///
938/// **Example:**
939/// ~~~~~~~~~~~~~{.cpp}
940/// #include <kodi/General.h>
941///
942/// bool value = false;
943/// if (!kodi::CheckSettingBoolean("my_boolean_value", value))
944/// value = true; // My default of them
945/// ~~~~~~~~~~~~~
946///
947inline bool ATTRIBUTE_HIDDEN CheckSettingBoolean(const std::string& settingName, bool& settingValue)
948{
949 using namespace kodi::addon;
950
951 return CAddonBase::m_interface->toKodi->get_setting_bool(
952 CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str(), &settingValue);
953}
954//------------------------------------------------------------------------------
955
956//==============================================================================
957/// @brief Get boolean setting value.
958///
959/// The setting name relate to names used in his <b>settings.xml</b> file.
960///
961/// @param[in] settingName The name of asked setting
962/// @param[in] defaultValue [opt] Default value if not found
963/// @return The value of setting, <b>`false`</b> or defaultValue if not found
964///
965///
966/// ----------------------------------------------------------------------------
967///
968/// **Example:**
969/// ~~~~~~~~~~~~~{.cpp}
970/// #include <kodi/General.h>
971///
972/// bool value = kodi::GetSettingBoolean("my_boolean_value");
973/// ~~~~~~~~~~~~~
974///
975inline bool ATTRIBUTE_HIDDEN GetSettingBoolean(const std::string& settingName,
976 bool defaultValue = false)
977{
978 bool settingValue = defaultValue;
979 CheckSettingBoolean(settingName, settingValue);
980 return settingValue;
981}
982//------------------------------------------------------------------------------
983
984//==============================================================================
985/// @brief Set boolean setting of addon.
986///
987/// The setting name relate to names used in his <b>settings.xml</b> file.
988///
989/// @param[in] settingName The name of setting
990/// @param[in] settingValue The setting value to write
991///
992///
993/// ----------------------------------------------------------------------------
994///
995/// **Example:**
996/// ~~~~~~~~~~~~~{.cpp}
997/// #include <kodi/General.h>
998///
999/// bool value = true;
1000/// kodi::SetSettingBoolean("my_boolean_value", value);
1001/// ~~~~~~~~~~~~~
1002///
1003inline void ATTRIBUTE_HIDDEN SetSettingBoolean(const std::string& settingName, bool settingValue)
1004{
1005 using namespace kodi::addon;
1006
1007 CAddonBase::m_interface->toKodi->set_setting_bool(CAddonBase::m_interface->toKodi->kodiBase,
1008 settingName.c_str(), settingValue);
1009}
1010//------------------------------------------------------------------------------
1011
1012//==============================================================================
1013/// @brief Check and get a floating point setting value.
1014///
1015/// The setting name relate to names used in his <b>settings.xml</b> file.
1016///
1017/// @param[in] settingName The name of asked setting
1018/// @param[out] settingValue The given setting value
1019/// @return true if setting was successfully found and "settingValue" is set
1020///
1021/// @note If returns false, the "settingValue" is not changed.
1022///
1023///
1024/// ----------------------------------------------------------------------------
1025///
1026/// **Example:**
1027/// ~~~~~~~~~~~~~{.cpp}
1028/// #include <kodi/General.h>
1029///
1030/// float value = 0.0f;
1031/// if (!kodi::CheckSettingBoolean("my_float_value", value))
1032/// value = 1.0f; // My default of them
1033/// ~~~~~~~~~~~~~
1034///
1035inline bool ATTRIBUTE_HIDDEN CheckSettingFloat(const std::string& settingName, float& settingValue)
1036{
1037 using namespace kodi::addon;
1038
1039 return CAddonBase::m_interface->toKodi->get_setting_float(
1040 CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str(), &settingValue);
1041}
1042//------------------------------------------------------------------------------
1043
1044//==============================================================================
1045/// @brief Get floating point setting value.
1046///
1047/// The setting name relate to names used in his <b>settings.xml</b> file.
1048///
1049/// @param[in] settingName The name of asked setting
1050/// @param[in] defaultValue [opt] Default value if not found
1051/// @return The value of setting, <b>`0.0`</b> or defaultValue if not found
1052///
1053///
1054/// ----------------------------------------------------------------------------
1055///
1056/// **Example:**
1057/// ~~~~~~~~~~~~~{.cpp}
1058/// #include <kodi/General.h>
1059///
1060/// float value = kodi::GetSettingFloat("my_float_value");
1061/// ~~~~~~~~~~~~~
1062///
1063inline float ATTRIBUTE_HIDDEN GetSettingFloat(const std::string& settingName,
1064 float defaultValue = 0.0f)
1065{
1066 float settingValue = defaultValue;
1067 CheckSettingFloat(settingName, settingValue);
1068 return settingValue;
1069}
1070//------------------------------------------------------------------------------
1071
1072//==============================================================================
1073/// @brief Set floating point setting of addon.
1074///
1075/// The setting name relate to names used in his <b>settings.xml</b> file.
1076///
1077/// @param[in] settingName The name of setting
1078/// @param[in] settingValue The setting value to write
1079///
1080///
1081/// ----------------------------------------------------------------------------
1082///
1083/// **Example:**
1084/// ~~~~~~~~~~~~~{.cpp}
1085/// #include <kodi/General.h>
1086///
1087/// float value = 1.0f;
1088/// kodi::SetSettingFloat("my_float_value", value);
1089/// ~~~~~~~~~~~~~
1090///
1091inline void ATTRIBUTE_HIDDEN SetSettingFloat(const std::string& settingName, float settingValue)
1092{
1093 using namespace kodi::addon;
1094
1095 CAddonBase::m_interface->toKodi->set_setting_float(CAddonBase::m_interface->toKodi->kodiBase,
1096 settingName.c_str(), settingValue);
1097}
1098//------------------------------------------------------------------------------
1099
1100//==============================================================================
1101/// @brief Check and get a enum setting value.
1102///
1103/// The setting name relate to names used in his <b>settings.xml</b> file.
1104///
1105/// @param[in] settingName The name of asked setting
1106/// @param[out] settingValue The given setting value
1107/// @return true if setting was successfully found and "settingValue" is set
1108///
1109/// @remark The enums are used as integer inside settings.xml.
1110/// @note If returns false, the "settingValue" is not changed.
1111///
1112///
1113/// ----------------------------------------------------------------------------
1114///
1115/// **Example:**
1116/// ~~~~~~~~~~~~~{.cpp}
1117/// #include <kodi/General.h>
1118///
1119/// enum myEnumValue
1120/// {
1121/// valueA,
1122/// valueB,
1123/// valueC
1124/// };
1125///
1126/// myEnumValue value;
1127/// if (!kodi::CheckSettingEnum<myEnumValue>("my_enum_value", value))
1128/// value = valueA; // My default of them
1129/// ~~~~~~~~~~~~~
1130///
1131template<typename enumType>
1132inline bool ATTRIBUTE_HIDDEN CheckSettingEnum(const std::string& settingName,
1133 enumType& settingValue)
1134{
1135 using namespace kodi::addon;
1136
1137 int settingValueInt = static_cast<int>(settingValue);
1138 bool ret = CAddonBase::m_interface->toKodi->get_setting_int(
1139 CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str(), &settingValueInt);
1140 if (ret)
1141 settingValue = static_cast<enumType>(settingValueInt);
1142 return ret;
1143}
1144//------------------------------------------------------------------------------
1145
1146//==============================================================================
1147/// @brief Get enum setting value.
1148///
1149/// The setting name relate to names used in his <b>settings.xml</b> file.
1150///
1151/// @param[in] settingName The name of asked setting
1152/// @param[in] defaultValue [opt] Default value if not found
1153/// @return The value of setting, forced to <b>`0`</b> or defaultValue if not found
1154///
1155/// @remark The enums are used as integer inside settings.xml.
1156///
1157///
1158/// ----------------------------------------------------------------------------
1159///
1160/// **Example:**
1161/// ~~~~~~~~~~~~~{.cpp}
1162/// #include <kodi/General.h>
1163///
1164/// enum myEnumValue
1165/// {
1166/// valueA,
1167/// valueB,
1168/// valueC
1169/// };
1170///
1171/// myEnumValue value = kodi::GetSettingEnum<myEnumValue>("my_enum_value");
1172/// ~~~~~~~~~~~~~
1173///
1174template<typename enumType>
1175inline enumType ATTRIBUTE_HIDDEN GetSettingEnum(const std::string& settingName,
1176 enumType defaultValue = static_cast<enumType>(0))
1177{
1178 enumType settingValue = defaultValue;
1179 CheckSettingEnum(settingName, settingValue);
1180 return settingValue;
1181}
1182//------------------------------------------------------------------------------
1183
1184//==============================================================================
1185/// @brief Set enum setting of addon.
1186///
1187/// The setting name relate to names used in his <b>settings.xml</b> file.
1188///
1189/// @param[in] settingName The name of setting
1190/// @param[in] settingValue The setting value to write
1191///
1192/// @remark The enums are used as integer inside settings.xml.
1193///
1194///
1195/// ----------------------------------------------------------------------------
1196///
1197/// **Example:**
1198/// ~~~~~~~~~~~~~{.cpp}
1199/// #include <kodi/General.h>
1200///
1201/// enum myEnumValue
1202/// {
1203/// valueA,
1204/// valueB,
1205/// valueC
1206/// };
1207///
1208/// myEnumValue value = valueA;
1209/// kodi::SetSettingEnum<myEnumValue>("my_enum_value", value);
1210/// ~~~~~~~~~~~~~
1211///
1212template<typename enumType>
1213inline void ATTRIBUTE_HIDDEN SetSettingEnum(const std::string& settingName, enumType settingValue)
1214{
1215 using namespace kodi::addon;
1216
1217 CAddonBase::m_interface->toKodi->set_setting_int(CAddonBase::m_interface->toKodi->kodiBase,
1218 settingName.c_str(),
1219 static_cast<int>(settingValue));
1220}
1221//------------------------------------------------------------------------------
1222
1223/*!@}*/
1224
1225//============================================================================
1226///
1227inline std::string ATTRIBUTE_HIDDEN TranslateAddonStatus(ADDON_STATUS status)
1228{
1229 switch (status)
1230 {
1231 case ADDON_STATUS_OK:
1232 return "OK";
1233 case ADDON_STATUS_LOST_CONNECTION:
1234 return "Lost Connection";
1235 case ADDON_STATUS_NEED_RESTART:
1236 return "Need Restart";
1237 case ADDON_STATUS_NEED_SETTINGS:
1238 return "Need Settings";
1239 case ADDON_STATUS_UNKNOWN:
1240 return "Unknown error";
1241 case ADDON_STATUS_PERMANENT_FAILURE:
1242 return "Permanent failure";
1243 case ADDON_STATUS_NOT_IMPLEMENTED:
1244 return "Not implemented";
1245 default:
1246 break;
1247 }
1248 return "Unknown";
1249}
1250//----------------------------------------------------------------------------
1251
1252//==============================================================================
1253/// @ingroup cpp_kodi
1254/// @brief Returns a function table to a named interface
1255///
1256/// @return pointer to struct containing interface functions
1257///
1258///
1259/// ------------------------------------------------------------------------
1260///
1261/// **Example:**
1262/// ~~~~~~~~~~~~~{.cpp}
1263/// #include <kodi/General.h>
1264/// #include <kodi/platform/foo.h>
1265/// ...
1266/// FuncTable_foo *table = kodi::GetPlatformInfo(foo_name, foo_version);
1267/// ...
1268/// ~~~~~~~~~~~~~
1269///
1270inline void* GetInterface(const std::string& name, const std::string& version)
1271{
1272 using namespace kodi::addon;
1273
1274 AddonToKodiFuncTable_Addon* toKodi = CAddonBase::m_interface->toKodi;
1275
1276 return toKodi->get_interface(toKodi->kodiBase, name.c_str(), version.c_str());
1277}
1278//----------------------------------------------------------------------------
1279
1280} /* namespace kodi */
1281
1282/*! addon creation macro
1283 * @todo cleanup this stupid big macro
1284 * This macro includes now all for add-on's needed functions. This becomes a bigger
1285 * rework after everything is done on Kodi itself, currently is this way needed
1286 * to have compatibility with not reworked interfaces.
1287 *
1288 * Becomes really cleaned up soon :D
1289 */
1290#define ADDONCREATOR(AddonClass) \
1291 extern "C" __declspec(dllexport) ADDON_STATUS ADDON_Create( \
1292 KODI_HANDLE addonInterface, const char* /*globalApiVersion*/, void* /*unused*/) \
1293 { \
1294 kodi::addon::CAddonBase::m_interface = static_cast<AddonGlobalInterface*>(addonInterface); \
1295 kodi::addon::CAddonBase::m_interface->addonBase = new AddonClass; \
1296 return static_cast<kodi::addon::CAddonBase*>(kodi::addon::CAddonBase::m_interface->addonBase) \
1297 ->Create(); \
1298 } \
1299 extern "C" __declspec(dllexport) void ADDON_Destroy() \
1300 { \
1301 kodi::addon::CAddonBase::ADDONBASE_Destroy(); \
1302 } \
1303 extern "C" __declspec(dllexport) ADDON_STATUS ADDON_GetStatus() \
1304 { \
1305 return kodi::addon::CAddonBase::ADDONBASE_GetStatus(); \
1306 } \
1307 extern "C" __declspec(dllexport) ADDON_STATUS ADDON_SetSetting(const char* settingName, \
1308 const void* settingValue) \
1309 { \
1310 return kodi::addon::CAddonBase::ADDONBASE_SetSetting(settingName, settingValue); \
1311 } \
1312 extern "C" __declspec(dllexport) const char* ADDON_GetTypeVersion(int type) \
1313 { \
1314 return kodi::addon::GetTypeVersion(type); \
1315 } \
1316 extern "C" __declspec(dllexport) const char* ADDON_GetTypeMinVersion(int type) \
1317 { \
1318 return kodi::addon::GetTypeMinVersion(type); \
1319 } \
1320 AddonGlobalInterface* kodi::addon::CAddonBase::m_interface = nullptr;
1321
1322#endif /* __cplusplus */