From be933ef2241d79558f91796cc5b3a161f72ebf9c Mon Sep 17 00:00:00 2001 From: manuel Date: Mon, 19 Oct 2020 00:52:24 +0200 Subject: sync with upstream --- xbmc/addons/kodi-dev-kit/include/kodi/AddonBase.h | 1322 +++++++++++++++++++++ 1 file changed, 1322 insertions(+) create mode 100644 xbmc/addons/kodi-dev-kit/include/kodi/AddonBase.h (limited to 'xbmc/addons/kodi-dev-kit/include/kodi/AddonBase.h') 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 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#pragma once + +#include "c-api/addon_base.h" +#include "versions.h" + +#include /* assert */ +#include /* va_list, va_start, va_arg, va_end */ + +#ifdef __cplusplus + +#include +#include +#include +#include +#include +#include +#include + +#include "tools/StringUtils.h" + +namespace kodi +{ + +namespace gui +{ +struct IRenderHelper; +} // namespace gui + +//============================================================================== +/// @ingroup cpp_kodi_Defs +/// @defgroup cpp_kodi_Defs_HardwareContext using HardwareContext +/// @brief **Hardware specific device context**\n +/// This defines an independent value which is used for hardware and OS specific +/// values. +/// +/// This is basically a simple pointer which has to be changed to the desired +/// format at the corresponding places using `static_cast<...>(...)`. +/// +/// +///------------------------------------------------------------------------- +/// +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// .. +/// // Note: Device() there is used inside addon child class about +/// // kodi::addon::CInstanceVisualization +/// ID3D11DeviceContext1* context = static_cast(kodi::addon::CInstanceVisualization::Device()); +/// .. +/// ~~~~~~~~~~~~~ +/// +///@{ +using HardwareContext = ADDON_HARDWARE_CONTEXT; +///@} +//------------------------------------------------------------------------------ + +//============================================================================== +/// @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 +/// +/// ---------------------------------------------------------------------------- +/// +/// **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 +{ +public: + explicit CSettingValue(const void* settingValue) : m_settingValue(settingValue) {} + + 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 + /// + /// 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; } + + /// @brief To get settings value as integer. + int GetInt() const { return *(const int*)m_settingValue; } + + /// @brief To get settings value as unsigned integer. + unsigned int GetUInt() const { return *(const unsigned int*)m_settingValue; } + + /// @brief To get settings value as boolean. + bool GetBoolean() const { return *(const bool*)m_settingValue; } + + /// @brief To get settings value as floating point. + float GetFloat() const { return *(const float*)m_settingValue; } + + /// @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); + } + + ///@} + +private: + const void* m_settingValue; +}; +///@} +//------------------------------------------------------------------------------ + +namespace addon +{ + +//============================================================================== +/* + * Internal class to control various instance types with general parts defined + * here. + * + * Mainly is this currently used to identify requested instance types. + * + * @note This class is not need to know during add-on development thats why + * commented with "*". + */ +class ATTRIBUTE_HIDDEN IAddonInstance +{ +public: + explicit IAddonInstance(ADDON_TYPE type, const std::string& version) + : m_type(type), m_kodiVersion(version) + { + } + virtual ~IAddonInstance() = default; + + virtual ADDON_STATUS CreateInstance(int instanceType, + const std::string& instanceID, + KODI_HANDLE instance, + const std::string& version, + KODI_HANDLE& addonInstance) + { + return ADDON_STATUS_NOT_IMPLEMENTED; + } + + const ADDON_TYPE m_type; + const std::string m_kodiVersion; + std::string m_id; +}; + +/* + * 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: + CStructHdl() : m_cStructure(new C_STRUCT()), m_owner(true) {} + + 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: + bool m_owner = false; +}; + +/// Add-on main instance class. +class ATTRIBUTE_HIDDEN CAddonBase +{ +public: + CAddonBase() + { + 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; + + virtual ADDON_STATUS Create() { return ADDON_STATUS_OK; } + + virtual ADDON_STATUS GetStatus() { return ADDON_STATUS_OK; } + + //============================================================================ + /// @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) + { + return ADDON_STATUS_UNKNOWN; + } + //---------------------------------------------------------------------------- + + //========================================================================== + /// @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_INFO, "Creating my Screensaver"); + /// addonInstance = new CMyScreensaver(instance); + /// return ADDON_STATUS_OK; + /// } + /// else if (instanceType == ADDON_INSTANCE_VISUALIZATION) + /// { + /// kodi::Log(ADDON_LOG_INFO, "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 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 + + /*private:*/ /* Needed public as long the old call functions becomes used! */ + static inline void ADDONBASE_Destroy() + { + delete static_cast(m_interface->addonBase); + m_interface->addonBase = nullptr; + } + + static inline ADDON_STATUS ADDONBASE_GetStatus() + { + return static_cast(m_interface->addonBase)->GetStatus(); + } + + static inline ADDON_STATUS ADDONBASE_SetSetting(const char* settingName, const void* settingValue) + { + return static_cast(m_interface->addonBase) + ->SetSetting(settingName, CSettingValue(settingValue)); + } + +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; + + /* 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) + { + 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; + } + + // 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) + { + CAddonBase* base = static_cast(m_interface->addonBase); + + if (m_interface->globalSingleInstance == nullptr && instance != base) + { + base->DestroyInstance(instanceType, static_cast(instance)->m_id, instance); + delete static_cast(instance); + } + } +}; + +} /* namespace addon */ + +//============================================================================== +/// @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; +} +//------------------------------------------------------------------------------ + +//============================================================================== +/// +inline std::string ATTRIBUTE_HIDDEN GetAddonPath(const std::string& append = "") +{ + using namespace kodi::addon; + + char* str = + CAddonBase::m_interface->toKodi->get_addon_path(CAddonBase::m_interface->toKodi->kodiBase); + std::string ret = str; + CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, str); + if (!append.empty()) + { + if (append.at(0) != '\\' && append.at(0) != '/') +#ifdef TARGET_WINDOWS + ret.append("\\"); +#else + ret.append("/"); +#endif + ret.append(append); + } + return ret; +} +//------------------------------------------------------------------------------ + +//============================================================================== +/// +inline std::string ATTRIBUTE_HIDDEN GetBaseUserPath(const std::string& append = "") +{ + using namespace kodi::addon; + + char* str = CAddonBase::m_interface->toKodi->get_base_user_path( + CAddonBase::m_interface->toKodi->kodiBase); + std::string ret = str; + CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, str); + if (!append.empty()) + { + if (append.at(0) != '\\' && append.at(0) != '/') +#ifdef TARGET_WINDOWS + ret.append("\\"); +#else + ret.append("/"); +#endif + ret.append(append); + } + return ret; +} +//------------------------------------------------------------------------------ + +//============================================================================== +/// +inline std::string ATTRIBUTE_HIDDEN GetLibPath() +{ + using namespace kodi::addon; + + return CAddonBase::m_interface->libBasePath; +} +//------------------------------------------------------------------------------ + +//============================================================================== +/// @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. +/// +/// +/// ---------------------------------------------------------------------------- +/// +/// **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; + + va_list args; + va_start(args, format); + const std::string str = kodi::tools::StringUtils::FormatV(format, args); + va_end(args); + CAddonBase::m_interface->toKodi->addon_log_msg(CAddonBase::m_interface->toKodi->kodiBase, + loglevel, str.c_str()); +} +//------------------------------------------------------------------------------ + +//############################################################################## +/// @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. +/// +/// 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 = CAddonBase::m_interface->toKodi->get_setting_string( + CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str(), &buffer); + if (buffer) + { + if (ret) + settingValue = buffer; + CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, buffer); + } + return ret; +} +//------------------------------------------------------------------------------ + +//============================================================================== +/// @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 ATTRIBUTE_HIDDEN GetSettingString(const std::string& settingName, + const std::string& defaultValue = "") +{ + std::string settingValue = defaultValue; + CheckSettingString(settingName, settingValue); + return settingValue; +} +//------------------------------------------------------------------------------ + +//============================================================================== +/// @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 +/// +/// +/// ---------------------------------------------------------------------------- +/// +/// **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) +{ + using namespace kodi::addon; + + CAddonBase::m_interface->toKodi->set_setting_string(CAddonBase::m_interface->toKodi->kodiBase, + settingName.c_str(), settingValue.c_str()); +} +//------------------------------------------------------------------------------ + +//============================================================================== +/// @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. +/// +/// +/// ---------------------------------------------------------------------------- +/// +/// **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) +{ + using namespace kodi::addon; + + return CAddonBase::m_interface->toKodi->get_setting_int(CAddonBase::m_interface->toKodi->kodiBase, + settingName.c_str(), &settingValue); +} +//------------------------------------------------------------------------------ + +//============================================================================== +/// @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 +/// +/// +/// ---------------------------------------------------------------------------- +/// +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// int value = kodi::GetSettingInt("my_integer_value"); +/// ~~~~~~~~~~~~~ +/// +inline int ATTRIBUTE_HIDDEN GetSettingInt(const std::string& settingName, int defaultValue = 0) +{ + int settingValue = defaultValue; + CheckSettingInt(settingName, settingValue); + return settingValue; +} +//------------------------------------------------------------------------------ + +//============================================================================== +/// @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 +/// +/// +/// ---------------------------------------------------------------------------- +/// +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// int value = 123; +/// kodi::SetSettingInt("my_integer_value", value); +/// ~~~~~~~~~~~~~ +/// +inline void ATTRIBUTE_HIDDEN SetSettingInt(const std::string& settingName, int settingValue) +{ + using namespace kodi::addon; + + CAddonBase::m_interface->toKodi->set_setting_int(CAddonBase::m_interface->toKodi->kodiBase, + settingName.c_str(), settingValue); +} +//------------------------------------------------------------------------------ + +//============================================================================== +/// @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. +/// +/// +/// ---------------------------------------------------------------------------- +/// +/// **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) +{ + using namespace kodi::addon; + + return CAddonBase::m_interface->toKodi->get_setting_bool( + CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str(), &settingValue); +} +//------------------------------------------------------------------------------ + +//============================================================================== +/// @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 +/// +/// +/// ---------------------------------------------------------------------------- +/// +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// bool value = kodi::GetSettingBoolean("my_boolean_value"); +/// ~~~~~~~~~~~~~ +/// +inline bool ATTRIBUTE_HIDDEN GetSettingBoolean(const std::string& settingName, + bool defaultValue = false) +{ + bool settingValue = defaultValue; + CheckSettingBoolean(settingName, settingValue); + return settingValue; +} +//------------------------------------------------------------------------------ + +//============================================================================== +/// @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 +/// +/// +/// ---------------------------------------------------------------------------- +/// +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// bool value = true; +/// kodi::SetSettingBoolean("my_boolean_value", value); +/// ~~~~~~~~~~~~~ +/// +inline void ATTRIBUTE_HIDDEN SetSettingBoolean(const std::string& settingName, bool settingValue) +{ + using namespace kodi::addon; + + CAddonBase::m_interface->toKodi->set_setting_bool(CAddonBase::m_interface->toKodi->kodiBase, + settingName.c_str(), settingValue); +} +//------------------------------------------------------------------------------ + +//============================================================================== +/// @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. +/// +/// +/// ---------------------------------------------------------------------------- +/// +/// **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) +{ + using namespace kodi::addon; + + return CAddonBase::m_interface->toKodi->get_setting_float( + CAddonBase::m_interface->toKodi->kodiBase, settingName.c_str(), &settingValue); +} +//------------------------------------------------------------------------------ + +//============================================================================== +/// @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 +/// +/// +/// ---------------------------------------------------------------------------- +/// +/// **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 = defaultValue; + CheckSettingFloat(settingName, settingValue); + return settingValue; +} +//------------------------------------------------------------------------------ + +//============================================================================== +/// @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 +/// +/// +/// ---------------------------------------------------------------------------- +/// +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// +/// float value = 1.0f; +/// kodi::SetSettingFloat("my_float_value", value); +/// ~~~~~~~~~~~~~ +/// +inline void ATTRIBUTE_HIDDEN SetSettingFloat(const std::string& settingName, float settingValue) +{ + using namespace kodi::addon; + + CAddonBase::m_interface->toKodi->set_setting_float(CAddonBase::m_interface->toKodi->kodiBase, + settingName.c_str(), settingValue); +} +//------------------------------------------------------------------------------ + +//============================================================================== +/// @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)); +} +//------------------------------------------------------------------------------ + +/*!@}*/ + +//============================================================================ +/// +inline std::string ATTRIBUTE_HIDDEN TranslateAddonStatus(ADDON_STATUS status) +{ + switch (status) + { + case ADDON_STATUS_OK: + return "OK"; + case ADDON_STATUS_LOST_CONNECTION: + return "Lost Connection"; + case ADDON_STATUS_NEED_RESTART: + return "Need Restart"; + case ADDON_STATUS_NEED_SETTINGS: + return "Need Settings"; + case ADDON_STATUS_UNKNOWN: + return "Unknown error"; + case ADDON_STATUS_PERMANENT_FAILURE: + return "Permanent failure"; + case ADDON_STATUS_NOT_IMPLEMENTED: + return "Not implemented"; + default: + break; + } + return "Unknown"; +} +//---------------------------------------------------------------------------- + +//============================================================================== +/// @ingroup cpp_kodi +/// @brief Returns a function table to a named interface +/// +/// @return pointer to struct containing interface functions +/// +/// +/// ------------------------------------------------------------------------ +/// +/// **Example:** +/// ~~~~~~~~~~~~~{.cpp} +/// #include +/// #include +/// ... +/// FuncTable_foo *table = kodi::GetPlatformInfo(foo_name, foo_version); +/// ... +/// ~~~~~~~~~~~~~ +/// +inline void* GetInterface(const std::string& name, const std::string& version) +{ + 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 + * @todo cleanup this stupid big macro + * This macro includes now all for add-on's needed functions. This becomes a bigger + * rework after everything is done on Kodi itself, currently is this way needed + * to have compatibility with not reworked interfaces. + * + * Becomes really cleaned up soon :D + */ +#define ADDONCREATOR(AddonClass) \ + 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 static_cast(kodi::addon::CAddonBase::m_interface->addonBase) \ + ->Create(); \ + } \ + extern "C" __declspec(dllexport) void ADDON_Destroy() \ + { \ + kodi::addon::CAddonBase::ADDONBASE_Destroy(); \ + } \ + extern "C" __declspec(dllexport) ADDON_STATUS ADDON_GetStatus() \ + { \ + return kodi::addon::CAddonBase::ADDONBASE_GetStatus(); \ + } \ + extern "C" __declspec(dllexport) ADDON_STATUS ADDON_SetSetting(const char* settingName, \ + const void* settingValue) \ + { \ + return kodi::addon::CAddonBase::ADDONBASE_SetSetting(settingName, settingValue); \ + } \ + extern "C" __declspec(dllexport) const char* ADDON_GetTypeVersion(int type) \ + { \ + return kodi::addon::GetTypeVersion(type); \ + } \ + extern "C" __declspec(dllexport) const char* ADDON_GetTypeMinVersion(int type) \ + { \ + return kodi::addon::GetTypeMinVersion(type); \ + } \ + AddonGlobalInterface* kodi::addon::CAddonBase::m_interface = nullptr; + +#endif /* __cplusplus */ -- cgit v1.2.3