From 5f8335c1e49ce108ef3481863833c98efa00411b Mon Sep 17 00:00:00 2001 From: manuel Date: Thu, 2 Jul 2020 23:09:26 +0200 Subject: sync with upstream --- .../kodi-addon-dev-kit/include/kodi/AddonBase.h | 1374 ++++++++++++++------ 1 file changed, 981 insertions(+), 393 deletions(-) (limited to 'xbmc/addons/kodi-addon-dev-kit/include/kodi/AddonBase.h') diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/AddonBase.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/AddonBase.h index db39f86..b0fddda 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/AddonBase.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/AddonBase.h @@ -8,230 +8,137 @@ #pragma once -#include /* va_list, va_start, va_arg, va_end */ +#include "c-api/addon_base.h" +#include "versions.h" + +#include /* assert */ #include #include +#include +#include +#include /* va_list, va_start, va_arg, va_end */ #include #include #include -#ifndef TARGET_WINDOWS -#ifndef __cdecl -#define __cdecl -#endif -#ifndef __declspec -#define __declspec(X) -#endif -#endif - -#undef ATTRIBUTE_PACKED -#undef PRAGMA_PACK_BEGIN -#undef PRAGMA_PACK_END - -#if defined(__GNUC__) - #define ATTRIBUTE_PACKED __attribute__ ((packed)) - #define PRAGMA_PACK 0 - #define ATTRIBUTE_HIDDEN __attribute__ ((visibility ("hidden"))) -#endif - -#if !defined(ATTRIBUTE_PACKED) - #define ATTRIBUTE_PACKED - #define PRAGMA_PACK 1 -#endif - -#if !defined(ATTRIBUTE_HIDDEN) - #define ATTRIBUTE_HIDDEN -#endif - -#ifdef _MSC_VER - #define ATTRIBUTE_FORCEINLINE __forceinline -#elif defined(__GNUC__) - #define ATTRIBUTE_FORCEINLINE inline __attribute__((__always_inline__)) -#elif defined(__CLANG__) - #if __has_attribute(__always_inline__) - #define ATTRIBUTE_FORCEINLINE inline __attribute__((__always_inline__)) - #else - #define ATTRIBUTE_FORCEINLINE inline - #endif -#else - #define ATTRIBUTE_FORCEINLINE inline -#endif - -#include "versions.h" - -namespace kodi { namespace addon { class CAddonBase; }} -namespace kodi { namespace addon { class IAddonInstance; }} - -extern "C" { - -//============================================================================== -/// Standard undefined pointer handle -typedef void* KODI_HANDLE; -//------------------------------------------------------------------------------ - -//============================================================================== -/// -typedef enum ADDON_STATUS +namespace kodi { - /// - ADDON_STATUS_OK, - - /// - ADDON_STATUS_LOST_CONNECTION, - - /// - ADDON_STATUS_NEED_RESTART, - - /// - ADDON_STATUS_NEED_SETTINGS, - /// - ADDON_STATUS_UNKNOWN, - - /// permanent failure, like failing to resolve methods - ADDON_STATUS_PERMANENT_FAILURE, - - /* internal used return error if function becomes not used from child on - * addon */ - ADDON_STATUS_NOT_IMPLEMENTED -} ADDON_STATUS; -//------------------------------------------------------------------------------ +namespace gui +{ +struct IRenderHelper; +} // namespace gui //============================================================================== -/// @todo remove start with ADDON_* after old way on libXBMC_addon.h is removed +/// @ingroup cpp_kodi_addon_addonbase_Defs +/// @defgroup cpp_kodi_addon_addonbase_Defs_CSettingValue class CSettingValue +/// @brief Inside addon main instance used helper class to give settings value. +/// +/// This is used on @ref addon::CAddonBase::SetSetting() to inform addon about +/// settings change by used. This becomes then used to give the related value +/// name. +/// +/// ---------------------------------------------------------------------------- +/// +/// @copydetails cpp_kodi_addon_addonbase_Defs_CSettingValue_Help /// -typedef enum AddonLog +/// ---------------------------------------------------------------------------- +/// +/// **Here is a code example how this is used:** +/// +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// enum myEnumValue +/// { +/// valueA, +/// valueB, +/// valueC +/// }; +/// +/// std::string m_myStringValue; +/// int m_myIntegerValue; +/// bool m_myBooleanValue; +/// float m_myFloatingPointValue; +/// myEnumValue m_myEnumValue; +/// +/// +/// ADDON_STATUS CMyAddon::SetSetting(const std::string& settingName, const kodi::CSettingValue& settingValue) +/// { +/// if (settingName == "my_string_value") +/// m_myStringValue = settingValue.GetString(); +/// else if (settingName == "my_integer_value") +/// m_myIntegerValue = settingValue.GetInt(); +/// else if (settingName == "my_boolean_value") +/// m_myBooleanValue = settingValue.GetBoolean(); +/// else if (settingName == "my_float_value") +/// m_myFloatingPointValue = settingValue.GetFloat(); +/// else if (settingName == "my_enum_value") +/// m_myEnumValue = settingValue.GetEnum(); +/// } +/// ~~~~~~~~~~~~~ +/// +/// @note The asked type should match the type used on settings.xml. +/// +///@{ +class ATTRIBUTE_HIDDEN CSettingValue { - /// - ADDON_LOG_DEBUG = 0, - - /// - ADDON_LOG_INFO = 1, +public: + explicit CSettingValue(const void* settingValue) : m_settingValue(settingValue) {} - /// - ADDON_LOG_NOTICE = 2, + bool empty() const { return (m_settingValue == nullptr) ? true : false; } + /// @defgroup cpp_kodi_addon_addonbase_Defs_CSettingValue_Help Value Help + /// @ingroup cpp_kodi_addon_addonbase_Defs_CSettingValue /// - ADDON_LOG_WARNING = 3, + /// The following table contains values that can be set with @ref cpp_kodi_addon_addonbase_Defs_CSettingValue : + /// | Name | Type | Get call + /// |------|------|---------- + /// | **Settings value as string** | `std::string` | @ref CSettingValue::GetString "GetString" + /// | **Settings value as integer** | `int` | @ref CSettingValue::GetInt "GetInt" + /// | **Settings value as unsigned integer** | `unsigned int` | @ref CSettingValue::GetUInt "GetUInt" + /// | **Settings value as boolean** | `bool` | @ref CSettingValue::GetBoolean "GetBoolean" + /// | **Settings value as floating point** | `float` | @ref CSettingValue::GetFloat "GetFloat" + /// | **Settings value as enum** | `enum` | @ref CSettingValue::GetEnum "GetEnum" + + /// @addtogroup cpp_kodi_addon_addonbase_Defs_CSettingValue + ///@{ + + /// @brief To get settings value as string. + std::string GetString() const { return (const char*)m_settingValue; } - /// - ADDON_LOG_ERROR = 4, + /// @brief To get settings value as integer. + int GetInt() const { return *(const int*)m_settingValue; } - /// - ADDON_LOG_SEVERE = 5, + /// @brief To get settings value as unsigned integer. + unsigned int GetUInt() const { return *(const unsigned int*)m_settingValue; } - /// - ADDON_LOG_FATAL = 6 -} AddonLog; -//------------------------------------------------------------------------------ + /// @brief To get settings value as boolean. + bool GetBoolean() const { return *(const bool*)m_settingValue; } -/*! - * @brief Handle used to return data from the PVR add-on to CPVRClient - */ -struct ADDON_HANDLE_STRUCT -{ - void *callerAddress; /*!< address of the caller */ - void *dataAddress; /*!< address to store data in */ - int dataIdentifier; /*!< parameter to pass back when calling the callback */ -}; -typedef ADDON_HANDLE_STRUCT *ADDON_HANDLE; + /// @brief To get settings value as floating point. + float GetFloat() const { return *(const float*)m_settingValue; } -/* - * To have a on add-on and kodi itself handled string always on known size! - */ -#define ADDON_STANDARD_STRING_LENGTH 1024 -#define ADDON_STANDARD_STRING_LENGTH_SMALL 256 + /// @brief To get settings value as enum. + /// @note Inside settings.xml them stored as integer. + template + enumType GetEnum() const + { + return static_cast(*(const int*)m_settingValue); + } -/* - * Callback function tables from addon to Kodi - * Set complete from Kodi! - */ -struct AddonToKodiFuncTable_kodi; -struct AddonToKodiFuncTable_kodi_audioengine; -struct AddonToKodiFuncTable_kodi_filesystem; -struct AddonToKodiFuncTable_kodi_network; -struct AddonToKodiFuncTable_kodi_gui; -typedef struct AddonToKodiFuncTable_Addon -{ - // Pointer inside Kodi, used on callback functions to give related handle - // class, for this ADDON::CAddonDll inside Kodi. - KODI_HANDLE kodiBase; - - // Function addresses used for callbacks from addon to Kodi - void (*free_string)(void* kodiBase, char* str); - void (*free_string_array)(void* kodiBase, char** arr, int numElements); - char* (*get_addon_path)(void* kodiBase); - char* (*get_base_user_path)(void* kodiBase); - void (*addon_log_msg)(void* kodiBase, const int loglevel, const char *msg); - - bool (*get_setting_bool)(void* kodiBase, const char* id, bool* value); - bool (*get_setting_int)(void* kodiBase, const char* id, int* value); - bool (*get_setting_float)(void* kodiBase, const char* id, float* value); - bool (*get_setting_string)(void* kodiBase, const char* id, char** value); - - bool (*set_setting_bool)(void* kodiBase, const char* id, bool value); - bool (*set_setting_int)(void* kodiBase, const char* id, int value); - bool (*set_setting_float)(void* kodiBase, const char* id, float value); - bool (*set_setting_string)(void* kodiBase, const char* id, const char* value); - - AddonToKodiFuncTable_kodi* kodi; - AddonToKodiFuncTable_kodi_audioengine* kodi_audioengine; - AddonToKodiFuncTable_kodi_filesystem* kodi_filesystem; - AddonToKodiFuncTable_kodi_gui* kodi_gui; - AddonToKodiFuncTable_kodi_network *kodi_network; - - void* (*get_interface)(void* kodiBase, const char *name, const char *version); -} AddonToKodiFuncTable_Addon; + ///@} -/* - * Function tables from Kodi to addon - */ -typedef struct KodiToAddonFuncTable_Addon -{ - void (*destroy)(); - ADDON_STATUS (*get_status)(); - ADDON_STATUS (*create_instance)(int instanceType, const char* instanceID, KODI_HANDLE instance, KODI_HANDLE* addonInstance, KODI_HANDLE parent); - void (*destroy_instance)(int instanceType, KODI_HANDLE instance); - ADDON_STATUS (*set_setting)(const char *settingName, const void *settingValue); - ADDON_STATUS(*create_instance_ex)(int instanceType, const char* instanceID, KODI_HANDLE instance, KODI_HANDLE* addonInstance, KODI_HANDLE parent, const char* version); -} KodiToAddonFuncTable_Addon; +private: + const void* m_settingValue; +}; +///@} +//------------------------------------------------------------------------------ -/* - * Main structure passed from kodi to addon with basic information needed to - * create add-on. - */ -typedef struct AddonGlobalInterface +namespace addon { - // String with full path where add-on is installed (without his name on end) - // Set from Kodi! - const char* libBasePath; - - // Pointer of first created instance, used in case this add-on goes with single way - // Set from Kodi! - KODI_HANDLE firstKodiInstance; - - // Pointer to master base class inside add-on - // Set from addon header! - kodi::addon::CAddonBase* addonBase; - - // Pointer to a instance used on single way (together with this class) - // Set from addon header! - kodi::addon::IAddonInstance* globalSingleInstance; - - // Callback function tables from addon to Kodi - // Set from Kodi! - AddonToKodiFuncTable_Addon* toKodi; - - // Function tables from Kodi to addon - // Set from addon header! - KodiToAddonFuncTable_Addon* toAddon; -} AddonGlobalInterface; - -} /* extern "C" */ //============================================================================== -namespace kodi { -namespace addon { /* * Internal class to control various instance types with general parts defined * here. @@ -241,66 +148,147 @@ namespace addon { * @note This class is not need to know during add-on development thats why * commented with "*". */ -class IAddonInstance +class ATTRIBUTE_HIDDEN IAddonInstance { public: - explicit IAddonInstance(ADDON_TYPE type) : m_type(type) { } - virtual ~IAddonInstance() = default; - - virtual ADDON_STATUS CreateInstance(int instanceType, std::string instanceID, KODI_HANDLE instance, KODI_HANDLE& addonInstance) + explicit IAddonInstance(ADDON_TYPE type, const std::string& version) + : m_type(type), m_kodiVersion(version) { - return ADDON_STATUS_NOT_IMPLEMENTED; } + virtual ~IAddonInstance() = default; - virtual ADDON_STATUS CreateInstanceEx(int instanceType, std::string instanceID, KODI_HANDLE instance, KODI_HANDLE& addonInstance, const std::string &version) + virtual ADDON_STATUS CreateInstance(int instanceType, + const std::string& instanceID, + KODI_HANDLE instance, + const std::string& version, + KODI_HANDLE& addonInstance) { - return CreateInstance(instanceType, instanceID, instance, addonInstance); + return ADDON_STATUS_NOT_IMPLEMENTED; } const ADDON_TYPE m_type; + const std::string m_kodiVersion; + std::string m_id; }; -} /* namespace addon */ -} /* namespace kodi */ -//------------------------------------------------------------------------------ -//============================================================================== -namespace kodi { -/// -class CSettingValue +/* + * Internally used helper class to manage processing of a "C" structure in "CPP" + * class. + * + * At constant, the "C" structure is copied, otherwise the given pointer is + * superseded and is changeable. + * + * ----------------------------------------------------------------------------- + * + * Example: + * + * ~~~~~~~~~~~~~{.cpp} + * extern "C" typedef struct C_SAMPLE_DATA + * { + * unsigned int iUniqueId; + * } C_SAMPLE_DATA; + * + * class CPPSampleData : public CStructHdl + * { + * public: + * CPPSampleData() = default; + * CPPSampleData(const CPPSampleData& sample) : CStructHdl(sample) { } + * CPPSampleData(const C_SAMPLE_DATA* sample) : CStructHdl(sample) { } + * CPPSampleData(C_SAMPLE_DATA* sample) : CStructHdl(sample) { } + * + * void SetUniqueId(unsigned int uniqueId) { m_cStructure->iUniqueId = uniqueId; } + * unsigned int GetUniqueId() const { return m_cStructure->iUniqueId; } + * }; + * + * ~~~~~~~~~~~~~ + * + * It also works with the following example: + * + * ~~~~~~~~~~~~~{.cpp} + * CPPSampleData test; + * // Some work + * C_SAMPLE_DATA* data = test; + * // Give "data" to Kodi + * ~~~~~~~~~~~~~ + */ +template +class CStructHdl { public: - explicit CSettingValue(const void *settingValue) : m_settingValue(settingValue) {} + CStructHdl() : m_cStructure(new C_STRUCT()), m_owner(true) {} - bool empty() const { return (m_settingValue == nullptr) ? true : false; } - std::string GetString() const { return (const char*)m_settingValue; } - int GetInt() const { return *(const int*)m_settingValue; } - unsigned int GetUInt() const { return *(const unsigned int*)m_settingValue; } - bool GetBoolean() const { return *(const bool*)m_settingValue; } - float GetFloat() const { return *(const float*)m_settingValue; } + CStructHdl(const CPP_CLASS& cppClass) + : m_cStructure(new C_STRUCT(*cppClass.m_cStructure)), m_owner(true) + { + } + + CStructHdl(const C_STRUCT* cStructure) : m_cStructure(new C_STRUCT(*cStructure)), m_owner(true) {} + + CStructHdl(C_STRUCT* cStructure) : m_cStructure(cStructure) { assert(cStructure); } + + const CStructHdl& operator=(const CStructHdl& right) + { + assert(&right.m_cStructure); + if (m_cStructure && !m_owner) + { + memcpy(m_cStructure, right.m_cStructure, sizeof(C_STRUCT)); + } + else + { + if (m_owner) + delete m_cStructure; + m_owner = true; + m_cStructure = new C_STRUCT(*right.m_cStructure); + } + return *this; + } + + const CStructHdl& operator=(const C_STRUCT& right) + { + assert(&right); + if (m_cStructure && !m_owner) + { + memcpy(m_cStructure, &right, sizeof(C_STRUCT)); + } + else + { + if (m_owner) + delete m_cStructure; + m_owner = true; + m_cStructure = new C_STRUCT(*right); + } + return *this; + } + + virtual ~CStructHdl() + { + if (m_owner) + delete m_cStructure; + } + + operator C_STRUCT*() { return m_cStructure; } + operator const C_STRUCT*() const { return m_cStructure; } + + const C_STRUCT* GetCStructure() const { return m_cStructure; } + +protected: + C_STRUCT* m_cStructure = nullptr; private: - const void *m_settingValue; + bool m_owner = false; }; -} /* namespace kodi */ -//------------------------------------------------------------------------------ -//============================================================================== -namespace kodi { -namespace addon { /// Add-on main instance class. class ATTRIBUTE_HIDDEN CAddonBase { public: CAddonBase() { - CAddonBase::m_interface->toAddon->destroy = ADDONBASE_Destroy; - CAddonBase::m_interface->toAddon->get_status = ADDONBASE_GetStatus; - CAddonBase::m_interface->toAddon->create_instance = ADDONBASE_CreateInstance; - CAddonBase::m_interface->toAddon->destroy_instance = ADDONBASE_DestroyInstance; - CAddonBase::m_interface->toAddon->set_setting = ADDONBASE_SetSetting; - // If version is present, we know that kodi has create_instance_ex implemented - if (!CAddonBase::m_strGlobalApiVersion.empty()) - CAddonBase::m_interface->toAddon->create_instance_ex = ADDONBASE_CreateInstanceEx; + m_interface->toAddon->destroy = ADDONBASE_Destroy; + m_interface->toAddon->get_status = ADDONBASE_GetStatus; + m_interface->toAddon->create_instance = ADDONBASE_CreateInstance; + m_interface->toAddon->destroy_instance = ADDONBASE_DestroyInstance; + m_interface->toAddon->set_setting = ADDONBASE_SetSetting; } virtual ~CAddonBase() = default; @@ -309,97 +297,301 @@ public: virtual ADDON_STATUS GetStatus() { return ADDON_STATUS_OK; } - virtual ADDON_STATUS SetSetting(const std::string& settingName, const CSettingValue& settingValue) { return ADDON_STATUS_UNKNOWN; } - - virtual ADDON_STATUS CreateInstance(int instanceType, std::string instanceID, KODI_HANDLE instance, KODI_HANDLE& addonInstance) + //============================================================================ + /// @ingroup cpp_kodi_addon_addonbase + /// @brief To inform addon about changed settings values. + /// + /// This becomes called for every entry defined inside his settings.xml and + /// as **last** call the one where last in xml (to identify end of calls). + /// + /// -------------------------------------------------------------------------- + /// + /// @copydetails cpp_kodi_addon_addonbase_Defs_CSettingValue_Help + /// + /// + /// -------------------------------------------------------------------------- + /// + /// **Here is a code example how this is used:** + /// + /// ~~~~~~~~~~~~~{.cpp} + /// #include + /// + /// enum myEnumValue + /// { + /// valueA, + /// valueB, + /// valueC + /// }; + /// + /// std::string m_myStringValue; + /// int m_myIntegerValue; + /// bool m_myBooleanValue; + /// float m_myFloatingPointValue; + /// myEnumValue m_myEnumValue; + /// + /// + /// ADDON_STATUS CMyAddon::SetSetting(const std::string& settingName, const kodi::CSettingValue& settingValue) + /// { + /// if (settingName == "my_string_value") + /// m_myStringValue = settingValue.GetString(); + /// else if (settingName == "my_integer_value") + /// m_myIntegerValue = settingValue.GetInt(); + /// else if (settingName == "my_boolean_value") + /// m_myBooleanValue = settingValue.GetBoolean(); + /// else if (settingName == "my_float_value") + /// m_myFloatingPointValue = settingValue.GetFloat(); + /// else if (settingName == "my_enum_value") + /// m_myEnumValue = settingValue.GetEnum(); + /// } + /// ~~~~~~~~~~~~~ + /// + /// @note The asked type should match the type used on settings.xml. + /// + virtual ADDON_STATUS SetSetting(const std::string& settingName, + const kodi::CSettingValue& settingValue) { - /* The handling below is intended for the case of the add-on only one - * instance and this is integrated in the add-on base class. - */ - - /* Check about single instance usage */ - if (CAddonBase::m_interface->firstKodiInstance == instance && // the kodi side instance pointer must be equal to first one - CAddonBase::m_interface->globalSingleInstance && // the addon side instance pointer must be set - CAddonBase::m_interface->globalSingleInstance->m_type == instanceType) // and the requested type must be equal with used add-on class - { - addonInstance = CAddonBase::m_interface->globalSingleInstance; - return ADDON_STATUS_OK; - } - return ADDON_STATUS_UNKNOWN; } + //---------------------------------------------------------------------------- - virtual ADDON_STATUS CreateInstanceEx(int instanceType, std::string instanceID, KODI_HANDLE instance, KODI_HANDLE& addonInstance, const std::string &version) + //========================================================================== + /// @ingroup cpp_kodi_addon_addonbase + /// @brief Instance created + /// + /// @param[in] instanceType The requested type of required instance, see \ref ADDON_TYPE. + /// @param[in] instanceID An individual identification key string given by Kodi. + /// @param[in] instance The instance handler used by Kodi must be passed to + /// the classes created here. See in the example. + /// @param[in] version The from Kodi used version of instance. This can be + /// used to allow compatibility to older versions of + /// them. Further is this given to the parent instance + /// that it can handle differences. + /// @param[out] addonInstance The pointer to instance class created in addon. + /// Needed to be able to identify them on calls. + /// @return \ref ADDON_STATUS_OK if correct, for possible errors + /// see \ref ADDON_STATUS + /// + /// + /// -------------------------------------------------------------------------- + /// + /// **Here is a code example how this is used:** + /// + /// ~~~~~~~~~~~~~{.cpp} + /// #include + /// + /// ... + /// + /// /* If you use only one instance in your add-on, can be instanceType and + /// * instanceID ignored */ + /// ADDON_STATUS CMyAddon::CreateInstance(int instanceType, + /// const std::string& instanceID, + /// KODI_HANDLE instance, + /// const std::string& version, + /// KODI_HANDLE& addonInstance) + /// { + /// if (instanceType == ADDON_INSTANCE_SCREENSAVER) + /// { + /// kodi::Log(ADDON_LOG_NOTICE, "Creating my Screensaver"); + /// addonInstance = new CMyScreensaver(instance); + /// return ADDON_STATUS_OK; + /// } + /// else if (instanceType == ADDON_INSTANCE_VISUALIZATION) + /// { + /// kodi::Log(ADDON_LOG_NOTICE, "Creating my Visualization"); + /// addonInstance = new CMyVisualization(instance); + /// return ADDON_STATUS_OK; + /// } + /// else if (...) + /// { + /// ... + /// } + /// return ADDON_STATUS_UNKNOWN; + /// } + /// + /// ... + /// + /// ~~~~~~~~~~~~~ + /// + virtual ADDON_STATUS CreateInstance(int instanceType, + const std::string& instanceID, + KODI_HANDLE instance, + const std::string& version, + KODI_HANDLE& addonInstance) { - return CreateInstance(instanceType, instanceID, instance, addonInstance); + return ADDON_STATUS_NOT_IMPLEMENTED; } + //-------------------------------------------------------------------------- + + //========================================================================== + /// @ingroup cpp_kodi_addon_addonbase + /// @brief Instance destroy + /// + /// This function is optional and intended to notify addon that the instance + /// is terminating. + /// + /// @param[in] instanceType The requested type of required instance, see \ref ADDON_TYPE. + /// @param[in] instanceID An individual identification key string given by Kodi. + /// @param[in] addonInstance The pointer to instance class created in addon. + /// + /// @warning This call is only used to inform that the associated instance + /// is terminated. The deletion is carried out in the background. + /// + virtual void DestroyInstance(int instanceType, + const std::string& instanceID, + KODI_HANDLE addonInstance) + { + } + //-------------------------------------------------------------------------- + + /* Background helper for GUI render systems, e.g. Screensaver or Visualization */ + std::shared_ptr m_renderHelper; /* Global variables of class */ - static AddonGlobalInterface* m_interface; // Interface function table to hold addresses on add-on and from kodi - static std::string m_strGlobalApiVersion; + static AddonGlobalInterface* + m_interface; // Interface function table to hold addresses on add-on and from kodi -/*private:*/ /* Needed public as long the old call functions becomes used! */ + /*private:*/ /* Needed public as long the old call functions becomes used! */ static inline void ADDONBASE_Destroy() { - delete CAddonBase::m_interface->addonBase; - CAddonBase::m_interface->addonBase = nullptr; + delete static_cast(m_interface->addonBase); + m_interface->addonBase = nullptr; } - static inline ADDON_STATUS ADDONBASE_GetStatus() { return CAddonBase::m_interface->addonBase->GetStatus(); } - - static inline ADDON_STATUS ADDONBASE_SetSetting(const char *settingName, const void *settingValue) + static inline ADDON_STATUS ADDONBASE_GetStatus() { - return CAddonBase::m_interface->addonBase->SetSetting(settingName, CSettingValue(settingValue)); + return static_cast(m_interface->addonBase)->GetStatus(); } - static inline ADDON_STATUS ADDONBASE_CreateInstance(int instanceType, const char* instanceID, KODI_HANDLE instance, KODI_HANDLE* addonInstance, KODI_HANDLE parent) + static inline ADDON_STATUS ADDONBASE_SetSetting(const char* settingName, const void* settingValue) { - return ADDONBASE_CreateInstanceEx(instanceType, instanceID, instance, addonInstance, parent, ""); + return static_cast(m_interface->addonBase) + ->SetSetting(settingName, CSettingValue(settingValue)); } - static inline ADDON_STATUS ADDONBASE_CreateInstanceEx(int instanceType, const char* instanceID, KODI_HANDLE instance, KODI_HANDLE* addonInstance, KODI_HANDLE parent, const char* version) +private: + static inline ADDON_STATUS ADDONBASE_CreateInstance(int instanceType, + const char* instanceID, + KODI_HANDLE instance, + const char* version, + KODI_HANDLE* addonInstance, + KODI_HANDLE parent) { + CAddonBase* base = static_cast(m_interface->addonBase); + ADDON_STATUS status = ADDON_STATUS_NOT_IMPLEMENTED; - if (parent != nullptr) - status = static_cast(parent)->CreateInstanceEx(instanceType, instanceID, instance, *addonInstance, version); - if (status == ADDON_STATUS_NOT_IMPLEMENTED) - status = CAddonBase::m_interface->addonBase->CreateInstanceEx(instanceType, instanceID, instance, *addonInstance, version); + + /* Check about single instance usage: + * 1. The kodi side instance pointer must be equal to first one + * 2. The addon side instance pointer must be set + * 3. And the requested type must be equal with used add-on class + */ + if (m_interface->firstKodiInstance == instance && m_interface->globalSingleInstance && + static_cast(m_interface->globalSingleInstance)->m_type == instanceType) + { + /* The handling here is intended for the case of the add-on only one + * instance and this is integrated in the add-on base class. + */ + *addonInstance = m_interface->globalSingleInstance; + status = ADDON_STATUS_OK; + } + else + { + /* Here it should use the CreateInstance instance function to allow + * creation of several on one addon. + */ + + /* Check first a parent is defined about (e.g. Codec within inputstream) */ + if (parent != nullptr) + status = static_cast(parent)->CreateInstance( + instanceType, instanceID, instance, version, *addonInstance); + + /* if no parent call the main instance creation function to get it */ + if (status == ADDON_STATUS_NOT_IMPLEMENTED) + { + status = base->CreateInstance(instanceType, instanceID, instance, version, *addonInstance); + } + } + if (*addonInstance == nullptr) - throw std::logic_error("kodi::addon::CAddonBase CreateInstanceEx returns a empty instance pointer!"); + { + if (status == ADDON_STATUS_OK) + { + m_interface->toKodi->addon_log_msg(m_interface->toKodi->kodiBase, ADDON_LOG_FATAL, + "kodi::addon::CAddonBase CreateInstance returned an " + "empty instance pointer, but reported OK!"); + return ADDON_STATUS_PERMANENT_FAILURE; + } + else + { + return status; + } + } + + if (static_cast(*addonInstance)->m_type != instanceType) + { + m_interface->toKodi->addon_log_msg( + m_interface->toKodi->kodiBase, ADDON_LOG_FATAL, + "kodi::addon::CAddonBase CreateInstance difference between given and returned"); + delete static_cast(*addonInstance); + *addonInstance = nullptr; + return ADDON_STATUS_PERMANENT_FAILURE; + } - if (static_cast<::kodi::addon::IAddonInstance*>(*addonInstance)->m_type != instanceType) - throw std::logic_error("kodi::addon::CAddonBase CreateInstanceEx with difference on given and returned instance type!"); + // Store the used ID inside instance, to have on destroy calls by addon to identify + static_cast(*addonInstance)->m_id = instanceID; return status; } static inline void ADDONBASE_DestroyInstance(int instanceType, KODI_HANDLE instance) { - if (CAddonBase::m_interface->globalSingleInstance == nullptr && instance != CAddonBase::m_interface->addonBase) + CAddonBase* base = static_cast(m_interface->addonBase); + + if (m_interface->globalSingleInstance == nullptr && instance != base) { - if (static_cast<::kodi::addon::IAddonInstance*>(instance)->m_type == instanceType) - delete static_cast<::kodi::addon::IAddonInstance*>(instance); - else - throw std::logic_error("kodi::addon::CAddonBase DestroyInstance called with difference on given and present instance type!"); + base->DestroyInstance(instanceType, static_cast(instance)->m_id, instance); + delete static_cast(instance); } } }; + } /* namespace addon */ -} /* namespace kodi */ + +//============================================================================== +/// @ingroup cpp_kodi_addon +/// @brief To get used version inside Kodi itself about asked type. +/// +/// This thought to allow a addon a handling of newer addon versions within +/// older Kodi until the type min version not changed. +/// +/// @param[in] type The wanted type of @ref ADDON_TYPE to ask +/// @return The version string about type in MAJOR.MINOR.PATCH style. +/// +inline std::string ATTRIBUTE_HIDDEN GetKodiTypeVersion(int type) +{ + using namespace kodi::addon; + + char* str = CAddonBase::m_interface->toKodi->get_type_version( + CAddonBase::m_interface->toKodi->kodiBase, type); + std::string ret = str; + CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, str); + return ret; +} //------------------------------------------------------------------------------ //============================================================================== -namespace kodi { /// -inline std::string GetAddonPath(const std::string& append = "") +inline std::string ATTRIBUTE_HIDDEN GetAddonPath(const std::string& append = "") { - char* str = ::kodi::addon::CAddonBase::m_interface->toKodi->get_addon_path(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase); + using namespace kodi::addon; + + char* str = + CAddonBase::m_interface->toKodi->get_addon_path(CAddonBase::m_interface->toKodi->kodiBase); std::string ret = str; - ::kodi::addon::CAddonBase::m_interface->toKodi->free_string(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, str); + CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, str); if (!append.empty()) { - if (append.at(0) != '\\' && - append.at(0) != '/') + if (append.at(0) != '\\' && append.at(0) != '/') #ifdef TARGET_WINDOWS ret.append("\\"); #else @@ -409,21 +601,21 @@ inline std::string GetAddonPath(const std::string& append = "") } return ret; } -} /* namespace kodi */ //------------------------------------------------------------------------------ //============================================================================== -namespace kodi { /// -inline std::string GetBaseUserPath(const std::string& append = "") +inline std::string ATTRIBUTE_HIDDEN GetBaseUserPath(const std::string& append = "") { - char* str = ::kodi::addon::CAddonBase::m_interface->toKodi->get_base_user_path(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase); + using namespace kodi::addon; + + char* str = CAddonBase::m_interface->toKodi->get_base_user_path( + CAddonBase::m_interface->toKodi->kodiBase); std::string ret = str; - ::kodi::addon::CAddonBase::m_interface->toKodi->free_string(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, str); + CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, str); if (!append.empty()) { - if (append.at(0) != '\\' && - append.at(0) != '/') + if (append.at(0) != '\\' && append.at(0) != '/') #ifdef TARGET_WINDOWS ret.append("\\"); #else @@ -433,174 +625,574 @@ inline std::string GetBaseUserPath(const std::string& append = "") } return ret; } -} /* namespace kodi */ //------------------------------------------------------------------------------ //============================================================================== -namespace kodi { /// -inline std::string GetLibPath() +inline std::string ATTRIBUTE_HIDDEN GetLibPath() { - return ::kodi::addon::CAddonBase::m_interface->libBasePath; + using namespace kodi::addon; + + return CAddonBase::m_interface->libBasePath; } -} /* namespace kodi */ //------------------------------------------------------------------------------ //============================================================================== -namespace kodi { +/// @ingroup cpp_kodi +/// @brief Add a message to Kodi's log. +/// +/// @param[in] loglevel The log level of the message. +/// @param[in] format The format of the message to pass to Kodi. +/// @param[in] ... Additional text to insert in format text +/// +/// +/// @note This method uses limited buffer (16k) for the formatted output. +/// So data, which will not fit into it, will be silently discarded. /// -inline void Log(const AddonLog loglevel, const char* format, ...) +/// +/// ---------------------------------------------------------------------------- +/// +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// kodi::Log(ADDON_LOG_ERROR, "%s: There is an error occurred!", __func__); +/// +/// ~~~~~~~~~~~~~ +/// +inline void ATTRIBUTE_HIDDEN Log(const AddonLog loglevel, const char* format, ...) { + using namespace kodi::addon; + char buffer[16384]; va_list args; va_start(args, format); - vsprintf(buffer, format, args); + vsnprintf(buffer, sizeof(buffer), format, args); va_end(args); - ::kodi::addon::CAddonBase::m_interface->toKodi->addon_log_msg(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, loglevel, buffer); + CAddonBase::m_interface->toKodi->addon_log_msg(CAddonBase::m_interface->toKodi->kodiBase, + loglevel, buffer); } -} /* namespace kodi */ //------------------------------------------------------------------------------ -//============================================================================ -namespace kodi { +//############################################################################## +/// @ingroup cpp_kodi +/// @defgroup cpp_kodi_settings 1. Setting control +/// @brief **Functions to handle settings access**\n +/// This can be used to get and set the addon related values inside his +/// settings.xml. +/// +/// The settings style is given with installed part on e.g. +/// `$HOME/.kodi/addons/myspecial.addon/resources/settings.xml`. The +/// related edit becomes then stored inside +/// `$HOME/.kodi/userdata/addon_data/myspecial.addon/settings.xml`. +/// +/*!@{*/ + +//============================================================================== +/// @brief Check the given setting name is set to default value. /// -inline bool CheckSettingString(const std::string& settingName, std::string& settingValue) +/// The setting name relate to names used in his settings.xml file. +/// +/// @param[in] settingName The name of asked setting +/// @return true if setting is the default +/// +inline bool ATTRIBUTE_HIDDEN IsSettingUsingDefault(const std::string& settingName) { + using namespace kodi::addon; + return CAddonBase::m_interface->toKodi->is_setting_using_default( + CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str()); +} +//------------------------------------------------------------------------------ + +//============================================================================== +/// @brief Check and get a string setting value. +/// +/// The setting name relate to names used in his settings.xml file. +/// +/// @param[in] settingName The name of asked setting +/// @param[out] settingValue The given setting value +/// @return true if setting was successfully found and "settingValue" is set +/// +/// @note If returns false, the "settingValue" is not changed. +/// +/// +/// ---------------------------------------------------------------------------- +/// +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// std::string value; +/// if (!kodi::CheckSettingString("my_string_value", value)) +/// value = "my_default_if_setting_not_work"; +/// ~~~~~~~~~~~~~ +/// +inline bool ATTRIBUTE_HIDDEN CheckSettingString(const std::string& settingName, + std::string& settingValue) +{ + using namespace kodi::addon; + char* buffer = nullptr; - bool ret = ::kodi::addon::CAddonBase::m_interface->toKodi->get_setting_string(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str(), &buffer); + bool ret = CAddonBase::m_interface->toKodi->get_setting_string( + CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str(), &buffer); if (buffer) { if (ret) settingValue = buffer; - ::kodi::addon::CAddonBase::m_interface->toKodi->free_string(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, buffer); + CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, buffer); } return ret; } -} /* namespace kodi */ -//---------------------------------------------------------------------------- +//------------------------------------------------------------------------------ -//============================================================================ -namespace kodi { +//============================================================================== +/// @brief Get string setting value. +/// +/// The setting name relate to names used in his settings.xml file. +/// +/// @param[in] settingName The name of asked setting +/// @param[in] defaultValue [opt] Default value if not found +/// @return The value of setting, empty if not found; +/// +/// +/// ---------------------------------------------------------------------------- +/// +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// std::string value = kodi::GetSettingString("my_string_value"); +/// ~~~~~~~~~~~~~ /// -inline std::string GetSettingString(const std::string& settingName) +inline std::string ATTRIBUTE_HIDDEN GetSettingString(const std::string& settingName, + const std::string& defaultValue = "") { - std::string settingValue; + std::string settingValue = defaultValue; CheckSettingString(settingName, settingValue); return settingValue; } -} /* namespace kodi */ -//---------------------------------------------------------------------------- +//------------------------------------------------------------------------------ -//============================================================================ -namespace kodi { +//============================================================================== +/// @brief Set string setting of addon. +/// +/// The setting name relate to names used in his settings.xml file. +/// +/// @param[in] settingName The name of setting +/// @param[in] settingValue The setting value to write +/// /// -inline void SetSettingString(const std::string& settingName, const std::string& settingValue) +/// ---------------------------------------------------------------------------- +/// +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// std::string value = "my_new_name for"; +/// kodi::SetSettingString("my_string_value", value); +/// ~~~~~~~~~~~~~ +/// +inline void ATTRIBUTE_HIDDEN SetSettingString(const std::string& settingName, + const std::string& settingValue) { - ::kodi::addon::CAddonBase::m_interface->toKodi->set_setting_string(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str(), settingValue.c_str()); + using namespace kodi::addon; + + CAddonBase::m_interface->toKodi->set_setting_string(CAddonBase::m_interface->toKodi->kodiBase, + settingName.c_str(), settingValue.c_str()); } -} /* namespace kodi */ -//---------------------------------------------------------------------------- +//------------------------------------------------------------------------------ -//============================================================================ -namespace kodi { +//============================================================================== +/// @brief Check and get a integer setting value. +/// +/// The setting name relate to names used in his settings.xml file. +/// +/// @param[in] settingName The name of asked setting +/// @param[out] settingValue The given setting value +/// @return true if setting was successfully found and "settingValue" is set +/// +/// @note If returns false, the "settingValue" is not changed. /// -inline bool CheckSettingInt(const std::string& settingName, int& settingValue) +/// +/// ---------------------------------------------------------------------------- +/// +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// int value = 0; +/// if (!kodi::CheckSettingInt("my_integer_value", value)) +/// value = 123; // My default of them +/// ~~~~~~~~~~~~~ +/// +inline bool ATTRIBUTE_HIDDEN CheckSettingInt(const std::string& settingName, int& settingValue) { - return ::kodi::addon::CAddonBase::m_interface->toKodi->get_setting_int(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str(), &settingValue); + using namespace kodi::addon; + + return CAddonBase::m_interface->toKodi->get_setting_int(CAddonBase::m_interface->toKodi->kodiBase, + settingName.c_str(), &settingValue); } -} /* namespace kodi */ -//---------------------------------------------------------------------------- +//------------------------------------------------------------------------------ -//============================================================================ -namespace kodi { +//============================================================================== +/// @brief Get integer setting value. +/// +/// The setting name relate to names used in his settings.xml file. +/// +/// @param[in] settingName The name of asked setting +/// @param[in] defaultValue [opt] Default value if not found +/// @return The value of setting, `0` or defaultValue if not found /// -inline int GetSettingInt(const std::string& settingName) +/// +/// ---------------------------------------------------------------------------- +/// +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// int value = kodi::GetSettingInt("my_integer_value"); +/// ~~~~~~~~~~~~~ +/// +inline int ATTRIBUTE_HIDDEN GetSettingInt(const std::string& settingName, int defaultValue = 0) { - int settingValue = 0; + int settingValue = defaultValue; CheckSettingInt(settingName, settingValue); return settingValue; } -} /* namespace kodi */ -//---------------------------------------------------------------------------- +//------------------------------------------------------------------------------ -//============================================================================ -namespace kodi { +//============================================================================== +/// @brief Set integer setting of addon. +/// +/// The setting name relate to names used in his settings.xml file. +/// +/// @param[in] settingName The name of setting +/// @param[in] settingValue The setting value to write /// -inline void SetSettingInt(const std::string& settingName, int settingValue) +/// +/// ---------------------------------------------------------------------------- +/// +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// int value = 123; +/// kodi::SetSettingInt("my_integer_value", value); +/// ~~~~~~~~~~~~~ +/// +inline void ATTRIBUTE_HIDDEN SetSettingInt(const std::string& settingName, int settingValue) { - ::kodi::addon::CAddonBase::m_interface->toKodi->set_setting_int(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str(), settingValue); + using namespace kodi::addon; + + CAddonBase::m_interface->toKodi->set_setting_int(CAddonBase::m_interface->toKodi->kodiBase, + settingName.c_str(), settingValue); } -} /* namespace kodi */ -//---------------------------------------------------------------------------- +//------------------------------------------------------------------------------ -//============================================================================ -namespace kodi { +//============================================================================== +/// @brief Check and get a boolean setting value. +/// +/// The setting name relate to names used in his settings.xml file. +/// +/// @param[in] settingName The name of asked setting +/// @param[out] settingValue The given setting value +/// @return true if setting was successfully found and "settingValue" is set +/// +/// @note If returns false, the "settingValue" is not changed. +/// +/// +/// ---------------------------------------------------------------------------- /// -inline bool CheckSettingBoolean(const std::string& settingName, bool& settingValue) +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// bool value = false; +/// if (!kodi::CheckSettingBoolean("my_boolean_value", value)) +/// value = true; // My default of them +/// ~~~~~~~~~~~~~ +/// +inline bool ATTRIBUTE_HIDDEN CheckSettingBoolean(const std::string& settingName, bool& settingValue) { - return ::kodi::addon::CAddonBase::m_interface->toKodi->get_setting_bool(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str(), &settingValue); + using namespace kodi::addon; + + return CAddonBase::m_interface->toKodi->get_setting_bool( + CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str(), &settingValue); } -} /* namespace kodi */ -//---------------------------------------------------------------------------- +//------------------------------------------------------------------------------ -//============================================================================ -namespace kodi { +//============================================================================== +/// @brief Get boolean setting value. +/// +/// The setting name relate to names used in his settings.xml file. +/// +/// @param[in] settingName The name of asked setting +/// @param[in] defaultValue [opt] Default value if not found +/// @return The value of setting, `false` or defaultValue if not found +/// +/// +/// ---------------------------------------------------------------------------- /// -inline bool GetSettingBoolean(const std::string& settingName) +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// bool value = kodi::GetSettingBoolean("my_boolean_value"); +/// ~~~~~~~~~~~~~ +/// +inline bool ATTRIBUTE_HIDDEN GetSettingBoolean(const std::string& settingName, + bool defaultValue = false) { - bool settingValue = false; + bool settingValue = defaultValue; CheckSettingBoolean(settingName, settingValue); return settingValue; } -} /* namespace kodi */ -//---------------------------------------------------------------------------- +//------------------------------------------------------------------------------ -//============================================================================ -namespace kodi { +//============================================================================== +/// @brief Set boolean setting of addon. +/// +/// The setting name relate to names used in his settings.xml file. +/// +/// @param[in] settingName The name of setting +/// @param[in] settingValue The setting value to write +/// +/// +/// ---------------------------------------------------------------------------- /// -inline void SetSettingBoolean(const std::string& settingName, bool settingValue) +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// bool value = true; +/// kodi::SetSettingBoolean("my_boolean_value", value); +/// ~~~~~~~~~~~~~ +/// +inline void ATTRIBUTE_HIDDEN SetSettingBoolean(const std::string& settingName, bool settingValue) { - ::kodi::addon::CAddonBase::m_interface->toKodi->set_setting_bool(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str(), settingValue); + using namespace kodi::addon; + + CAddonBase::m_interface->toKodi->set_setting_bool(CAddonBase::m_interface->toKodi->kodiBase, + settingName.c_str(), settingValue); } -} /* namespace kodi */ -//---------------------------------------------------------------------------- +//------------------------------------------------------------------------------ -//============================================================================ -namespace kodi { +//============================================================================== +/// @brief Check and get a floating point setting value. +/// +/// The setting name relate to names used in his settings.xml file. +/// +/// @param[in] settingName The name of asked setting +/// @param[out] settingValue The given setting value +/// @return true if setting was successfully found and "settingValue" is set +/// +/// @note If returns false, the "settingValue" is not changed. +/// /// -inline bool CheckSettingFloat(const std::string& settingName, float& settingValue) +/// ---------------------------------------------------------------------------- +/// +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// float value = 0.0f; +/// if (!kodi::CheckSettingBoolean("my_float_value", value)) +/// value = 1.0f; // My default of them +/// ~~~~~~~~~~~~~ +/// +inline bool ATTRIBUTE_HIDDEN CheckSettingFloat(const std::string& settingName, float& settingValue) { - return ::kodi::addon::CAddonBase::m_interface->toKodi->get_setting_float(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str(), &settingValue); + using namespace kodi::addon; + + return CAddonBase::m_interface->toKodi->get_setting_float( + CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str(), &settingValue); } -} /* namespace kodi */ -//---------------------------------------------------------------------------- +//------------------------------------------------------------------------------ -//============================================================================ -namespace kodi { +//============================================================================== +/// @brief Get floating point setting value. +/// +/// The setting name relate to names used in his settings.xml file. +/// +/// @param[in] settingName The name of asked setting +/// @param[in] defaultValue [opt] Default value if not found +/// @return The value of setting, `0.0` or defaultValue if not found +/// /// -inline float GetSettingFloat(const std::string& settingName) +/// ---------------------------------------------------------------------------- +/// +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// float value = kodi::GetSettingFloat("my_float_value"); +/// ~~~~~~~~~~~~~ +/// +inline float ATTRIBUTE_HIDDEN GetSettingFloat(const std::string& settingName, + float defaultValue = 0.0f) { - float settingValue = 0.0f; + float settingValue = defaultValue; CheckSettingFloat(settingName, settingValue); return settingValue; } -} /* namespace kodi */ -//---------------------------------------------------------------------------- +//------------------------------------------------------------------------------ -//============================================================================ -namespace kodi { +//============================================================================== +/// @brief Set floating point setting of addon. +/// +/// The setting name relate to names used in his settings.xml file. +/// +/// @param[in] settingName The name of setting +/// @param[in] settingValue The setting value to write +/// +/// +/// ---------------------------------------------------------------------------- /// -inline void SetSettingFloat(const std::string& settingName, float settingValue) +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// float value = 1.0f; +/// kodi::SetSettingFloat("my_float_value", value); +/// ~~~~~~~~~~~~~ +/// +inline void ATTRIBUTE_HIDDEN SetSettingFloat(const std::string& settingName, float settingValue) { - ::kodi::addon::CAddonBase::m_interface->toKodi->set_setting_float(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str(), settingValue); + using namespace kodi::addon; + + CAddonBase::m_interface->toKodi->set_setting_float(CAddonBase::m_interface->toKodi->kodiBase, + settingName.c_str(), settingValue); } -} /* namespace kodi */ -//---------------------------------------------------------------------------- +//------------------------------------------------------------------------------ + +//============================================================================== +/// @brief Check and get a enum setting value. +/// +/// The setting name relate to names used in his settings.xml file. +/// +/// @param[in] settingName The name of asked setting +/// @param[out] settingValue The given setting value +/// @return true if setting was successfully found and "settingValue" is set +/// +/// @remark The enums are used as integer inside settings.xml. +/// @note If returns false, the "settingValue" is not changed. +/// +/// +/// ---------------------------------------------------------------------------- +/// +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// enum myEnumValue +/// { +/// valueA, +/// valueB, +/// valueC +/// }; +/// +/// myEnumValue value; +/// if (!kodi::CheckSettingEnum("my_enum_value", value)) +/// value = valueA; // My default of them +/// ~~~~~~~~~~~~~ +/// +template +inline bool ATTRIBUTE_HIDDEN CheckSettingEnum(const std::string& settingName, + enumType& settingValue) +{ + using namespace kodi::addon; + + int settingValueInt = static_cast(settingValue); + bool ret = CAddonBase::m_interface->toKodi->get_setting_int( + CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str(), &settingValueInt); + if (ret) + settingValue = static_cast(settingValueInt); + return ret; +} +//------------------------------------------------------------------------------ + +//============================================================================== +/// @brief Get enum setting value. +/// +/// The setting name relate to names used in his settings.xml file. +/// +/// @param[in] settingName The name of asked setting +/// @param[in] defaultValue [opt] Default value if not found +/// @return The value of setting, forced to `0` or defaultValue if not found +/// +/// @remark The enums are used as integer inside settings.xml. +/// +/// +/// ---------------------------------------------------------------------------- +/// +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// enum myEnumValue +/// { +/// valueA, +/// valueB, +/// valueC +/// }; +/// +/// myEnumValue value = kodi::GetSettingEnum("my_enum_value"); +/// ~~~~~~~~~~~~~ +/// +template +inline enumType ATTRIBUTE_HIDDEN GetSettingEnum(const std::string& settingName, + enumType defaultValue = static_cast(0)) +{ + enumType settingValue = defaultValue; + CheckSettingEnum(settingName, settingValue); + return settingValue; +} +//------------------------------------------------------------------------------ + +//============================================================================== +/// @brief Set enum setting of addon. +/// +/// The setting name relate to names used in his settings.xml file. +/// +/// @param[in] settingName The name of setting +/// @param[in] settingValue The setting value to write +/// +/// @remark The enums are used as integer inside settings.xml. +/// +/// +/// ---------------------------------------------------------------------------- +/// +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// enum myEnumValue +/// { +/// valueA, +/// valueB, +/// valueC +/// }; +/// +/// myEnumValue value = valueA; +/// kodi::SetSettingEnum("my_enum_value", value); +/// ~~~~~~~~~~~~~ +/// +template +inline void ATTRIBUTE_HIDDEN SetSettingEnum(const std::string& settingName, enumType settingValue) +{ + using namespace kodi::addon; + + CAddonBase::m_interface->toKodi->set_setting_int(CAddonBase::m_interface->toKodi->kodiBase, + settingName.c_str(), + static_cast(settingValue)); +} +//------------------------------------------------------------------------------ + +/*!@}*/ //============================================================================ -namespace kodi { /// -inline std::string TranslateAddonStatus(ADDON_STATUS status) +inline std::string ATTRIBUTE_HIDDEN TranslateAddonStatus(ADDON_STATUS status) { switch (status) { @@ -623,13 +1215,10 @@ inline std::string TranslateAddonStatus(ADDON_STATUS status) } return "Unknown"; } -} /* namespace kodi */ //---------------------------------------------------------------------------- //============================================================================== -namespace kodi { -/// -/// \ingroup cpp_kodi +/// @ingroup cpp_kodi /// @brief Returns a function table to a named interface /// /// @return pointer to struct containing interface functions @@ -646,12 +1235,16 @@ namespace kodi { /// ... /// ~~~~~~~~~~~~~ /// -inline void* GetInterface(const std::string &name, const std::string &version) +inline void* GetInterface(const std::string& name, const std::string& version) { - AddonToKodiFuncTable_Addon* toKodi = ::kodi::addon::CAddonBase::m_interface->toKodi; + using namespace kodi::addon; + + AddonToKodiFuncTable_Addon* toKodi = CAddonBase::m_interface->toKodi; return toKodi->get_interface(toKodi->kodiBase, name.c_str(), version.c_str()); } +//---------------------------------------------------------------------------- + } /* namespace kodi */ /*! addon creation macro @@ -663,17 +1256,13 @@ inline void* GetInterface(const std::string &name, const std::string &version) * Becomes really cleaned up soon :D */ #define ADDONCREATOR(AddonClass) \ - extern "C" __declspec(dllexport) void get_addon(void* pAddon) {} \ - extern "C" __declspec(dllexport) ADDON_STATUS ADDON_Create(KODI_HANDLE addonInterface, void *unused) \ + extern "C" __declspec(dllexport) ADDON_STATUS ADDON_Create( \ + KODI_HANDLE addonInterface, const char* /*globalApiVersion*/, void* /*unused*/) \ { \ kodi::addon::CAddonBase::m_interface = static_cast(addonInterface); \ kodi::addon::CAddonBase::m_interface->addonBase = new AddonClass; \ - return kodi::addon::CAddonBase::m_interface->addonBase->Create(); \ - } \ - extern "C" __declspec(dllexport) ADDON_STATUS ADDON_CreateEx(KODI_HANDLE addonInterface, const char* globalApiVersion, void *unused) \ - { \ - kodi::addon::CAddonBase::m_strGlobalApiVersion = globalApiVersion; \ - return ADDON_Create(addonInterface, unused); \ + return static_cast(kodi::addon::CAddonBase::m_interface->addonBase) \ + ->Create(); \ } \ extern "C" __declspec(dllexport) void ADDON_Destroy() \ { \ @@ -683,7 +1272,8 @@ inline void* GetInterface(const std::string &name, const std::string &version) { \ return kodi::addon::CAddonBase::ADDONBASE_GetStatus(); \ } \ - extern "C" __declspec(dllexport) ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue) \ + extern "C" __declspec(dllexport) ADDON_STATUS ADDON_SetSetting(const char* settingName, \ + const void* settingValue) \ { \ return kodi::addon::CAddonBase::ADDONBASE_SetSetting(settingName, settingValue); \ } \ @@ -695,6 +1285,4 @@ inline void* GetInterface(const std::string &name, const std::string &version) { \ return kodi::addon::GetTypeMinVersion(type); \ } \ - AddonGlobalInterface* kodi::addon::CAddonBase::m_interface = nullptr; \ - std::string kodi::addon::CAddonBase::m_strGlobalApiVersion; - + AddonGlobalInterface* kodi::addon::CAddonBase::m_interface = nullptr; -- cgit v1.2.3