From b58a697c63c6926c24dd00b64e8bd013531de79b Mon Sep 17 00:00:00 2001 From: AchimTuran Date: Sat, 9 May 2015 13:42:12 +0200 Subject: [PATCH 1/3] [template] Initial commit of adsp.template framework --- src/template/ADSPAddonHandler.cpp | 441 ++++++++++++ src/template/ADSPHelpers.cpp | 456 ++++++++++++ src/template/ADSPHelpers.h | 55 ++ src/template/ADSPProcessorHandle.cpp | 44 ++ .../AddonExceptions/IAddonException.h | 49 ++ .../AddonExceptions/TAddonException.h | 52 ++ src/template/AddonHelpers.cpp | 24 + src/template/AddonHelpers.h | 30 + src/template/GUIDialogBase.cpp | 85 +++ src/template/IADDONOptional.cpp | 29 + src/template/IADSPProcessor.cpp | 88 +++ src/template/Messages/ADSPModeMessage.cpp | 193 ++++++ src/template/Settings/ISettingsElement.h | 64 ++ src/template/Settings/SettingsHelpers.cpp | 104 +++ src/template/Settings/SettingsHelpers.h | 35 + src/template/Settings/SettingsManager.cpp | 617 +++++++++++++++++ src/template/Settings/SettingsManager.h | 83 +++ src/template/Settings/TSettingsElement.h | 44 ++ src/template/client.cpp | 651 ++++++++++++++++++ .../configuration/templateConfiguration.cpp | 122 ++++ .../configuration/templateConfiguration.h | 150 ++++ src/template/doxygenDocu.h | 90 +++ src/template/include/ADSPAddonHandler.h | 115 ++++ src/template/include/ADSPModeMessage.h | 74 ++ src/template/include/ADSPProcessorHandle.h | 40 ++ src/template/include/GUIDialogBase.h | 51 ++ src/template/include/IADDONOptional.h | 56 ++ src/template/include/IADSPProcessor.h | 305 ++++++++ src/template/include/MACROHelper.h | 125 ++++ src/template/include/checkTemplateConfig.h | 39 ++ src/template/include/client.h | 32 + src/template/include/typedefs.h | 91 +++ 32 files changed, 4434 insertions(+) create mode 100644 src/template/ADSPAddonHandler.cpp create mode 100644 src/template/ADSPHelpers.cpp create mode 100644 src/template/ADSPHelpers.h create mode 100644 src/template/ADSPProcessorHandle.cpp create mode 100644 src/template/AddonExceptions/IAddonException.h create mode 100644 src/template/AddonExceptions/TAddonException.h create mode 100644 src/template/AddonHelpers.cpp create mode 100644 src/template/AddonHelpers.h create mode 100644 src/template/GUIDialogBase.cpp create mode 100644 src/template/IADDONOptional.cpp create mode 100644 src/template/IADSPProcessor.cpp create mode 100644 src/template/Messages/ADSPModeMessage.cpp create mode 100644 src/template/Settings/ISettingsElement.h create mode 100644 src/template/Settings/SettingsHelpers.cpp create mode 100644 src/template/Settings/SettingsHelpers.h create mode 100644 src/template/Settings/SettingsManager.cpp create mode 100644 src/template/Settings/SettingsManager.h create mode 100644 src/template/Settings/TSettingsElement.h create mode 100644 src/template/client.cpp create mode 100644 src/template/configuration/templateConfiguration.cpp create mode 100644 src/template/configuration/templateConfiguration.h create mode 100644 src/template/doxygenDocu.h create mode 100644 src/template/include/ADSPAddonHandler.h create mode 100644 src/template/include/ADSPModeMessage.h create mode 100644 src/template/include/ADSPProcessorHandle.h create mode 100644 src/template/include/GUIDialogBase.h create mode 100644 src/template/include/IADDONOptional.h create mode 100644 src/template/include/IADSPProcessor.h create mode 100644 src/template/include/MACROHelper.h create mode 100644 src/template/include/checkTemplateConfig.h create mode 100644 src/template/include/client.h create mode 100644 src/template/include/typedefs.h diff --git a/src/template/ADSPAddonHandler.cpp b/src/template/ADSPAddonHandler.cpp new file mode 100644 index 0000000..f1d582b --- /dev/null +++ b/src/template/ADSPAddonHandler.cpp @@ -0,0 +1,441 @@ +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#include +#include + +#include "include/client.h" + +#include "include/ADSPAddonHandler.h" +#include "configuration/templateConfiguration.h" +#include "template/include/MACROHelper.h" +#include "template/AddonExceptions/TAddonException.h" + +#ifndef strcpy_s +#define strcpy_s(dest, size, src) (strncpy((dest), (src), (size))) +#endif + +using namespace std; +using namespace ADDON; + +extern std::string adspImageUserPath; + +//Helper function prototypes +string GetSettingsFile(); + +CADSPAddonHandler::CADSPAddonHandler() +{ + for( unsigned int ii = 0; ii < AE_DSP_STREAM_MAX_STREAMS; ii++ ) + { + m_ADSPProcessor[ii] = NULL; + } +} + +CADSPAddonHandler::~CADSPAddonHandler() +{ + PLATFORM::CLockObject modeLock(m_ADSPModeLock); + + for( unsigned int ii = 0; ii < AE_DSP_STREAM_MAX_STREAMS; ii++ ) + { + if(m_ADSPProcessor[ii]) + { + delete m_ADSPProcessor[ii]; + } + } +} + +bool CADSPAddonHandler::Init() +{ + AE_DSP_MODES::AE_DSP_MODE modeSettings; + string imagePath = g_strAddonPath + "\\"; + if(adspImageUserPath != "" || !adspImageUserPath.empty()) + { + imagePath += adspImageUserPath + "\\"; + } + string temp; + +#ifdef ADSP_ADDON_USE_INPUTRESAMPLE + modeSettings.iUniqueDBModeId = adspInResampleUniqueDdId; + modeSettings.iModeType = AE_DSP_MODE_TYPE_INPUT_RESAMPLE; + strcpy(modeSettings.strModeName, adspInResampleStrNames); + + modeSettings.iModeNumber = adspInResampleModeNum; + modeSettings.iModeSupportTypeFlags = adspInResampleTypeFlags; + modeSettings.bHasSettingsDialog = adspInResampleSettings; + modeSettings.bIsDisabled = adspInResampleDisabled; + + modeSettings.iModeName = adspInResampleName; + modeSettings.iModeSetupName = adspInResampleSetupName; + modeSettings.iModeDescription = adspInResampleDescription; + modeSettings.iModeHelp = adspInResampleHelp; + + temp = imagePath + adspInResampleOwnImage; + strcpy(modeSettings.strOwnModeImage, temp.c_str()); + temp = imagePath + adspInResampleOverrideImage; + strcpy(modeSettings.strOverrideModeImage, temp.c_str()); + + ADSP->RegisterMode(&modeSettings); +#endif + +#ifdef ADSP_ADDON_USE_PREPROCESSING + for(unsigned int ii = 0; ii < ADSP_MAX_PRE_MODES; ii++) + { + modeSettings.iUniqueDBModeId = adspPreUniqueDbId[ii]; + modeSettings.iModeType = AE_DSP_MODE_TYPE_PRE_PROCESS; + strcpy_s(modeSettings.strModeName, AE_DSP_ADDON_STRING_LENGTH, adspPreStrNames[ii]); + + modeSettings.iModeNumber = adspPreModeNum[ii]; + modeSettings.iModeSupportTypeFlags = adspPreTypeFlags[ii]; + modeSettings.bHasSettingsDialog = adspPreSettings[ii]; + modeSettings.bIsDisabled = adspPreDisabled[ii]; + + modeSettings.iModeName = adspPreName[ii]; + modeSettings.iModeSetupName = adspPreSetupName[ii]; + modeSettings.iModeDescription = adspPreDescription[ii]; + modeSettings.iModeHelp = adspPreHelp[ii]; + + temp = imagePath + adspPreOwnImage[ii]; + strcpy_s(modeSettings.strOwnModeImage, AE_DSP_ADDON_STRING_LENGTH, temp.c_str()); + strcpy_s(modeSettings.strOverrideModeImage, AE_DSP_ADDON_STRING_LENGTH, "");//adspPreOverrideImage[ii]); + + ADSP->RegisterMode(&modeSettings); + } +#endif + +#ifdef ADSP_ADDON_USE_MASTERPROCESS + for(unsigned int ii = 0; ii < ADSP_MAX_MASTER_MODES; ii++) + { + modeSettings.iUniqueDBModeId = adspMaUniqueDdId[ii]; + modeSettings.iModeType = AE_DSP_MODE_TYPE_MASTER_PROCESS; + strcpy_s(modeSettings.strModeName, AE_DSP_ADDON_STRING_LENGTH, adspMaStrNames[ii]); + + modeSettings.iModeNumber = adspMaModeNum[ii]; + modeSettings.iModeSupportTypeFlags = adspMaTypeFlags[ii]; + modeSettings.bHasSettingsDialog = adspMasterSettings[ii]; + modeSettings.bIsDisabled = adspMaDisabled[ii]; + + modeSettings.iModeName = adspMaName[ii]; + modeSettings.iModeSetupName = adspMaSetupName[ii]; + modeSettings.iModeDescription = adspMaDescription[ii]; + modeSettings.iModeHelp = adspMaHelp[ii]; + + temp = imagePath + adspMaOwnImage[ii]; + strcpy_s(modeSettings.strOwnModeImage, AE_DSP_ADDON_STRING_LENGTH, temp.c_str()); + temp = imagePath + adspMaOverrideImage[ii]; + strcpy_s(modeSettings.strOverrideModeImage, AE_DSP_ADDON_STRING_LENGTH, temp.c_str()); + + ADSP->RegisterMode(&modeSettings); + } +#endif + +#ifdef ADSP_ADDON_USE_POSTPROCESS + for(unsigned int ii = 0; ii < ADSP_MAX_POST_MODES; ii++) + { + modeSettings.iUniqueDBModeId = adspPostUniqueDbId[ii]; + modeSettings.iModeType = AE_DSP_MODE_TYPE_POST_PROCESS; + strcpy_s(modeSettings.strModeName, AE_DSP_ADDON_STRING_LENGTH, adspPostStrNames[ii]); + + modeSettings.iModeNumber = adspPostModeNum[ii]; + modeSettings.iModeSupportTypeFlags = adspPostTypeFlags[ii]; + modeSettings.bHasSettingsDialog = adspPostSettings[ii]; + modeSettings.bIsDisabled = adspPostDisabled[ii]; + + modeSettings.iModeName = adspPostName[ii]; + modeSettings.iModeSetupName = adspPostSetupName[ii]; + modeSettings.iModeDescription = adspPostDescription[ii]; + modeSettings.iModeHelp = adspPostHelp[ii]; + + temp = imagePath + adspPostOwnImage[ii]; + strcpy_s(modeSettings.strOwnModeImage, AE_DSP_ADDON_STRING_LENGTH, temp.c_str()); + temp = imagePath + adspPostOverrideImage[ii]; + strcpy_s(modeSettings.strOverrideModeImage, AE_DSP_ADDON_STRING_LENGTH, temp.c_str()); + + ADSP->RegisterMode(&modeSettings); + } +#endif + +#ifdef ADSP_ADDON_USE_OUTPUTRESAMPLE + modeSettings.iUniqueDBModeId = adspOutResampleUniqueDdId; + modeSettings.iModeType = AE_DSP_MODE_TYPE_OUTPUT_RESAMPLE; + strcpy_s(modeSettings.strModeName, AE_DSP_ADDON_STRING_LENGTH, adspOutResampleStrNames); + + modeSettings.iModeNumber = adspOutResampleModeNum; + modeSettings.iModeSupportTypeFlags = adspOutResampleTypeFlags; + modeSettings.bHasSettingsDialog = adspOutResampleSettings; + modeSettings.bIsDisabled = adspOutResampleDisabled; + + modeSettings.iModeName = adspOutResampleName; + modeSettings.iModeSetupName = adspOutResampleSetupName; + modeSettings.iModeDescription = adspOutResampleDescription; + modeSettings.iModeHelp = adspOutResampleHelp; + + temp = imagePath + adspOutResampleOwnImage; + strcpy_s(modeSettings.strOwnModeImage, AE_DSP_ADDON_STRING_LENGTH, temp.c_str()); + temp = imagePath + adspOutResampleOverrideImage; + strcpy_s(modeSettings.strOverrideModeImage, AE_DSP_ADDON_STRING_LENGTH, temp.c_str()); + + ADSP->RegisterMode(&modeSettings); +#endif + + //now we try to initialize the addon processor class +#ifdef ADSP_ADDON_USE_OPTIONAL_INIT + return OptionalInit(); +#else + return true; +#endif +} + + +void CADSPAddonHandler::Destroy() +{ + PLATFORM::CLockObject modeLock(m_ADSPModeLock); + + for(int ii = 0; ii < AE_DSP_STREAM_MAX_STREAMS; ii++) + { + SAFE_DELETE(m_ADSPProcessor[ii]); + } + + Stop(); +} + + +AE_DSP_ERROR CADSPAddonHandler::StreamCreate(const AE_DSP_SETTINGS *addonSettings, const AE_DSP_STREAM_PROPERTIES* pProperties, ADDON_HANDLE handle) +{ + const unsigned int iStreamID = addonSettings->iStreamID; + if(iStreamID >= AE_DSP_STREAM_MAX_STREAMS) + { + KODI->Log(LOG_ERROR, "StreamID was equal or greater than AE_DSP_STREAM_MAX_STREAMS!"); + return AE_DSP_ERROR_UNKNOWN; + } + + PLATFORM::CLockObject modeLock(m_ADSPModeLock); + if(m_ADSPProcessor[iStreamID]) + { + delete m_ADSPProcessor[iStreamID]; + m_ADSPProcessor[iStreamID] = NULL; + } + + m_ADSPProcessor[iStreamID] = new CADSPProcessorHandle(addonSettings, pProperties); + if(m_ADSPProcessor[iStreamID]) + { + handle->dataIdentifier = iStreamID; + handle->dataAddress = NULL; + handle->callerAddress = m_ADSPProcessor[iStreamID]; + + return m_ADSPProcessor[iStreamID]->Create(); + } + else + { + KODI->Log(LOG_ERROR, "Couldn't create new ADSP-Stream! Not enough free memory?"); + return AE_DSP_ERROR_FAILED; + } +} + + +AE_DSP_ERROR CADSPAddonHandler::StreamDestroy(unsigned int Id) +{ + if(Id >= AE_DSP_STREAM_MAX_STREAMS) + { + KODI->Log(LOG_ERROR, "StreamID was equal or greater than AE_DSP_STREAM_MAX_STREAMS!"); + return AE_DSP_ERROR_UNKNOWN; + } + + PLATFORM::CLockObject modeLock(m_ADSPModeLock); + if(m_ADSPProcessor[Id]) + { + delete m_ADSPProcessor[Id]; + m_ADSPProcessor[Id] = NULL; + } + else + { + KODI->Log(LOG_ERROR, "Couldn't destroy Stream: %i! It was not created!", Id); + return AE_DSP_ERROR_UNKNOWN; + } + + return AE_DSP_ERROR_NO_ERROR; +} + +// ToDo: Reimplement mode handling with AddonHandler. +// Add methods: register/deregister mode (type, Id) +// process modes +// add base mode class +// add std::map for each processing mode +// prevent access to this std::map with a CLockObject +CADSPProcessorHandle *CADSPAddonHandler::GetStream(AE_DSP_STREAM_ID Id) +{ + if(Id >= AE_DSP_STREAM_MAX_STREAMS) + { + KODI->Log(LOG_ERROR, "StreamID was equal or greater than AE_DSP_STREAM_MAX_STREAMS!"); + return NULL; + } + + return m_ADSPProcessor[Id]; +} + +AE_DSP_ERROR CADSPAddonHandler::GetStreamInfos(AE_DSP_STREAM_ID Id, const AE_DSP_SETTINGS *pSettings, const AE_DSP_STREAM_PROPERTIES* pProperties, void *CustomStreamInfos) +{ + if(!pSettings || !pProperties || Id >= AE_DSP_STREAM_MAX_STREAMS) + { + return AE_DSP_ERROR_INVALID_PARAMETERS; + } + + PLATFORM::CLockObject modeLock(m_ADSPModeLock); + if(!m_ADSPProcessor[Id]) + { + return AE_DSP_ERROR_REJECTED; + } + + return m_ADSPProcessor[Id]->GetStreamInfos(pSettings, pProperties, CustomStreamInfos); +} + +AE_DSP_ERROR CADSPAddonHandler::SendMessageToStream(CADSPModeMessage &Message) +{ + if( Message.get_MessageDataSize() <= 0|| + Message.get_AudioChannel() <= AE_DSP_CH_INVALID || + Message.get_AudioChannel() > AE_DSP_CH_MAX || + !Message.get_ProcessingModeId() || + Message.get_StreamId() > AE_DSP_STREAM_MAX_STREAMS || + !Message.get_MessageType()) + { + return AE_DSP_ERROR_REJECTED; + } + + if(Message.get_StreamId() == AE_DSP_STREAM_MAX_STREAMS) + { + uint failedMessages = 0; + for(uint stream = 0; stream < AE_DSP_STREAM_MAX_STREAMS; stream++) + { + PLATFORM::CLockObject modeLock(m_ADSPModeLock); + if(m_ADSPProcessor[stream]) + { + AE_DSP_ERROR err = m_ADSPProcessor[stream]->send_Message(Message); + if(err != AE_DSP_ERROR_NO_ERROR) + { + KODI->Log(ADDON::LOG_ERROR, "%s line %i: ModeMessage in stream id: %i produced error code: %i. AudioChannel: %s, MessageSize: %i, MessageType: %i, ProcessingModeId: %i, StreamId: %i", + __func__, __LINE__, stream, err, CADSPHelpers::Translate_ChID_TO_String(Message.get_AudioChannel()).c_str(), + Message.get_MessageDataSize(), Message.get_MessageType(), Message.get_ProcessingModeId(), Message.get_StreamId()); + failedMessages++; + } + } + } + + if(failedMessages >= AE_DSP_STREAM_MAX_STREAMS) + { // If all messages produced an error an AE_DSP_ERROR_FAILED error is returned + return AE_DSP_ERROR_FAILED; + } + } + else + { + if(Message.get_StreamId() > AE_DSP_STREAM_MAX_STREAMS) + { + return AE_DSP_ERROR_INVALID_PARAMETERS; + } + + PLATFORM::CLockObject modeLock(m_ADSPModeLock); + if(!m_ADSPProcessor[Message.get_StreamId()]) + { + return AE_DSP_ERROR_IGNORE_ME; + } + + return m_ADSPProcessor[Message.get_StreamId()]->send_Message(Message); + } + + return AE_DSP_ERROR_NO_ERROR; +} + +AE_DSP_ERROR CADSPAddonHandler::StreamInitialize(const ADDON_HANDLE handle, const AE_DSP_SETTINGS *Settings) +{ + return AE_DSP_ERROR_NO_ERROR; +} + +/* + * ADSP-Addon support functions + */ +bool CADSPAddonHandler::SupportsInputProcess() +{ +#ifdef ADSP_ADDON_USE_INPUTPROCESS + return true; +#else + return false; +#endif +} + +bool CADSPAddonHandler::SupportsPreProcess() +{ +#ifdef ADSP_ADDON_USE_PREPROCESSING + return true; +#else + return false; +#endif +} + +bool CADSPAddonHandler::SupportsMasterProcess() +{ +#ifdef ADSP_ADDON_USE_MASTERPROCESS + return true; +#else + return false; +#endif +} + +bool CADSPAddonHandler::SupportsPostProcess() +{ +#ifdef ADSP_ADDON_USE_POSTPROCESS + return true; +#else + return false; +#endif +} + +bool CADSPAddonHandler::SupportsInputResample() +{ +#ifdef ADSP_ADDON_USE_INPUTRESAMPLE + return true; +#else + return false; +#endif +} + +bool CADSPAddonHandler::SupportsOutputResample() +{ +#ifdef ADSP_ADDON_USE_OUTPUTRESAMPLE + return true; +#else + return false; +#endif +} + + +//Helper function +string GetSettingsFile() +{ + string settingFile = g_strAddonPath; + if (settingFile.at(settingFile.size() - 1) == '\\' || settingFile.at(settingFile.size() - 1) == '/') + { + settingFile.append(ADSP_SETTINGS_FILE); + } + else + { + settingFile.append(string("/") + string(ADSP_SETTINGS_FILE)); + } + + return settingFile; +} + diff --git a/src/template/ADSPHelpers.cpp b/src/template/ADSPHelpers.cpp new file mode 100644 index 0000000..5aa6a7d --- /dev/null +++ b/src/template/ADSPHelpers.cpp @@ -0,0 +1,456 @@ +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + + +#include "ADSPHelpers.h" +#include +using namespace std; + +#if !defined(TARGET_WINDOWS) + inline float abs(float Val) + { + if(Val >= 0.0f) + { + return Val; + } + else + { + return -1.0f*Val; + } + } +#endif + +// Channel Layouts and channel names are from: https://trac.ffmpeg.org/wiki/AudioChannelManipulation +AE_DSP_CHANNEL CADSPHelpers::Translate_ChFlag_TO_ChID(AE_DSP_CHANNEL_PRESENT ChFlag) +{ + switch(ChFlag) + { + case AE_DSP_PRSNT_CH_FL: + return AE_DSP_CH_FL; + break; + + case AE_DSP_PRSNT_CH_FR: + return AE_DSP_CH_FR; + break; + + case AE_DSP_PRSNT_CH_FC: + return AE_DSP_CH_FC; + break; + + case AE_DSP_PRSNT_CH_LFE: + return AE_DSP_CH_LFE; + break; + + case AE_DSP_PRSNT_CH_BL: + return AE_DSP_CH_BL; + break; + + case AE_DSP_PRSNT_CH_BR: + return AE_DSP_CH_BR; + break; + + case AE_DSP_PRSNT_CH_FLOC: + return AE_DSP_CH_FLOC; + break; + + case AE_DSP_PRSNT_CH_FROC: + return AE_DSP_CH_FROC; + break; + + case AE_DSP_PRSNT_CH_BC: + return AE_DSP_CH_BC; + break; + + case AE_DSP_PRSNT_CH_SL: + return AE_DSP_CH_SL; + break; + + case AE_DSP_PRSNT_CH_SR: + return AE_DSP_CH_SR; + break; + + case AE_DSP_PRSNT_CH_TFL: + return AE_DSP_CH_TFL; + break; + + case AE_DSP_PRSNT_CH_TFR: + return AE_DSP_CH_TFR; + break; + + case AE_DSP_PRSNT_CH_TFC: + return AE_DSP_CH_TFC; + break; + + case AE_DSP_PRSNT_CH_TC: + return AE_DSP_CH_TC; + break; + + case AE_DSP_PRSNT_CH_TBL: + return AE_DSP_CH_TBL; + break; + + case AE_DSP_PRSNT_CH_TBR: + return AE_DSP_CH_TBR; + break; + + case AE_DSP_PRSNT_CH_TBC: + return AE_DSP_CH_TBC; + break; + + case AE_DSP_PRSNT_CH_BLOC: + return AE_DSP_CH_BLOC; + break; + + case AE_DSP_PRSNT_CH_BROC: + return AE_DSP_CH_BROC; + break; + + default: + return AE_DSP_CH_INVALID; + break; + } +} + +AE_DSP_CHANNEL_PRESENT CADSPHelpers::Translate_ChID_TO_ChFlag(AE_DSP_CHANNEL ChID) +{ + switch(ChID) + { + case AE_DSP_CH_FL: + return AE_DSP_PRSNT_CH_FL; + break; + + case AE_DSP_CH_FR: + return AE_DSP_PRSNT_CH_FR; + break; + + case AE_DSP_CH_FC: + return AE_DSP_PRSNT_CH_FC; + break; + + case AE_DSP_CH_LFE: + return AE_DSP_PRSNT_CH_LFE; + break; + + case AE_DSP_CH_BL: + return AE_DSP_PRSNT_CH_BL; + break; + + case AE_DSP_CH_BR: + return AE_DSP_PRSNT_CH_BR; + break; + + case AE_DSP_CH_FLOC: + return AE_DSP_PRSNT_CH_FLOC; + break; + + case AE_DSP_CH_FROC: + return AE_DSP_PRSNT_CH_FROC; + break; + + case AE_DSP_CH_BC: + return AE_DSP_PRSNT_CH_BC; + break; + + case AE_DSP_CH_SL: + return AE_DSP_PRSNT_CH_SL; + break; + + case AE_DSP_CH_SR: + return AE_DSP_PRSNT_CH_SR; + break; + + case AE_DSP_CH_TFL: + return AE_DSP_PRSNT_CH_TFL; + break; + + case AE_DSP_CH_TFR: + return AE_DSP_PRSNT_CH_TFR; + break; + + case AE_DSP_CH_TFC: + return AE_DSP_PRSNT_CH_TFC; + break; + + case AE_DSP_CH_TC: + return AE_DSP_PRSNT_CH_TC; + break; + + case AE_DSP_CH_TBL: + return AE_DSP_PRSNT_CH_TBL; + break; + + case AE_DSP_CH_TBR: + return AE_DSP_PRSNT_CH_TBR; + break; + + case AE_DSP_CH_TBC: + return AE_DSP_PRSNT_CH_TBC; + break; + + case AE_DSP_CH_BLOC: + return AE_DSP_PRSNT_CH_BLOC; + break; + + case AE_DSP_CH_BROC: + return AE_DSP_PRSNT_CH_BROC; + break; + + default: + return AE_DSP_PRSNT_CH_UNDEFINED; + break; + } +} + +string CADSPHelpers::Translate_ChFlag_TO_String(AE_DSP_CHANNEL_PRESENT ChFlag) +{ + string chStr = ""; + switch(ChFlag) + { + case AE_DSP_PRSNT_CH_FL: + chStr = "front left"; + break; + + case AE_DSP_PRSNT_CH_FR: + chStr = "front right"; + break; + + case AE_DSP_PRSNT_CH_FC: + chStr = "front center"; + break; + + case AE_DSP_PRSNT_CH_LFE: + chStr = "low frequency"; + break; + + case AE_DSP_PRSNT_CH_BL: + chStr = "back left"; + break; + + case AE_DSP_PRSNT_CH_BR: + chStr = "back right"; + break; + + case AE_DSP_PRSNT_CH_FLOC: + chStr = "front left-of-center"; + break; + + case AE_DSP_PRSNT_CH_FROC: + chStr = "front right-of-center"; + break; + + case AE_DSP_PRSNT_CH_BC: + chStr = "back center"; + break; + + case AE_DSP_PRSNT_CH_SL: + chStr = "side left"; + break; + + case AE_DSP_PRSNT_CH_SR: + chStr = "side right"; + break; + + case AE_DSP_PRSNT_CH_TFL: + chStr = "top front left"; + break; + + case AE_DSP_PRSNT_CH_TFR: + chStr = "top front right"; + break; + + case AE_DSP_PRSNT_CH_TFC: + chStr = "top front center"; + break; + + case AE_DSP_PRSNT_CH_TC: + chStr = "top center"; + break; + + case AE_DSP_PRSNT_CH_TBL: + chStr = "top back left"; + break; + + case AE_DSP_PRSNT_CH_TBR: + chStr = "top back right"; + break; + + case AE_DSP_PRSNT_CH_TBC: + chStr = "top back center"; + break; + + case AE_DSP_PRSNT_CH_BLOC: + chStr = "back left of center"; + break; + + case AE_DSP_PRSNT_CH_BROC: + chStr = "back right of center"; + break; + + default: + chStr = "undefined"; + break; + } + + return chStr; +} + +string CADSPHelpers::Translate_ChID_TO_String(AE_DSP_CHANNEL ChID) +{ + string chStr = ""; + switch(ChID) + { + case AE_DSP_CH_FL: + chStr = "front left"; + break; + + case AE_DSP_CH_FR: + chStr = "front right"; + break; + + case AE_DSP_CH_FC: + chStr = "front center"; + break; + + case AE_DSP_CH_LFE: + chStr = "low frequency"; + break; + + case AE_DSP_CH_BL: + chStr = "back left"; + break; + + case AE_DSP_CH_BR: + chStr = "back right"; + break; + + case AE_DSP_CH_FLOC: + chStr = "front left-of-center"; + break; + + case AE_DSP_CH_FROC: + chStr = "front right-of-center"; + break; + + case AE_DSP_CH_BC: + chStr = "back center"; + break; + + case AE_DSP_CH_SL: + chStr = "side left"; + break; + + case AE_DSP_CH_SR: + chStr = "side right"; + break; + + case AE_DSP_CH_TFL: + chStr = "top front left"; + break; + + case AE_DSP_CH_TFR: + chStr = "top front right"; + break; + + case AE_DSP_CH_TFC: + chStr = "top front center"; + break; + + case AE_DSP_CH_TC: + chStr = "top center"; + break; + + case AE_DSP_CH_TBL: + chStr = "top back left"; + break; + + case AE_DSP_CH_TBR: + chStr = "top back right"; + break; + + case AE_DSP_CH_TBC: + chStr = "top back center"; + break; + + case AE_DSP_CH_BLOC: + chStr = "back left of center"; + break; + + case AE_DSP_CH_BROC: + chStr = "back right of center"; + break; + + default: + chStr = "undefined"; + break; + } + + return chStr; +} + +bool CADSPHelpers::IsChannelFlag_Present(AE_DSP_CHANNEL_FLAGS AvailableFlags, AE_DSP_CHANNEL_PRESENT ChFlag) +{ + return (bool)(AvailableFlags & (ChFlag)); +} + +bool CADSPHelpers::IsChannelID_Present(AE_DSP_CHANNEL_FLAGS AvailableFlags, AE_DSP_CHANNEL ChID) +{ + return (bool)(AvailableFlags & (1<. + * + */ + + + +#include +// reserved for future implementation +//#include +#include +#include "AddonHelpers.h" + +typedef unsigned long AE_DSP_CHANNEL_FLAGS; + +class CADSPHelpers +{ +public: + static AE_DSP_CHANNEL Translate_ChFlag_TO_ChID(AE_DSP_CHANNEL_PRESENT ChFlag); + static AE_DSP_CHANNEL_PRESENT Translate_ChID_TO_ChFlag(AE_DSP_CHANNEL ChID); + static std::string Translate_ChFlag_TO_String(AE_DSP_CHANNEL_PRESENT ChFlag); + static std::string Translate_ChID_TO_String(AE_DSP_CHANNEL ChID); + static bool IsChannelFlag_Present(AE_DSP_CHANNEL_FLAGS AvailableFlags, AE_DSP_CHANNEL_PRESENT ChFlag); + static bool IsChannelID_Present(AE_DSP_CHANNEL_FLAGS AvailableFlags, AE_DSP_CHANNEL ChID); + static AE_DSP_CHANNEL_PRESENT GetNextChFlag(AE_DSP_CHANNEL_FLAGS AvailableFlags, AE_DSP_CHANNEL_PRESENT ChFlag); + static AE_DSP_CHANNEL GetNextChID(AE_DSP_CHANNEL_FLAGS AvailableFlags, AE_DSP_CHANNEL ChID); + static float Convert_dB_TO_Value(float dB); + static float Convert_Value_TO_dB(float Scale); + + // reserved for future implementation + //static std::string GetAddonHomePath(); + //static std::string GetAddonSettingsFile(); +}; + +// reserved for future implementation +//class CADSPException : public CAddonException +//{ +// +//}; diff --git a/src/template/ADSPProcessorHandle.cpp b/src/template/ADSPProcessorHandle.cpp new file mode 100644 index 0000000..9a5f95d --- /dev/null +++ b/src/template/ADSPProcessorHandle.cpp @@ -0,0 +1,44 @@ +#include "include/ADSPProcessorHandle.h" +#include + +CADSPProcessorHandle::CADSPProcessorHandle(const AE_DSP_SETTINGS *Settings, const AE_DSP_STREAM_PROPERTIES *pProperties) +{ + memcpy(&m_StreamSettings, Settings, sizeof(AE_DSP_SETTINGS)); + memcpy(&m_StreamProperties, pProperties, sizeof(AE_DSP_SETTINGS)); +} + +CADSPProcessorHandle::~CADSPProcessorHandle() +{ +} + +AE_DSP_ERROR CADSPProcessorHandle::StreamInitialize(const AE_DSP_SETTINGS *Settings) +{ + memcpy(&m_StreamSettings, Settings, sizeof(AE_DSP_SETTINGS)); + + return AE_DSP_ERROR_NO_ERROR; +} + +float CADSPProcessorHandle::OutputResampleGetDelay() +{ + return (float)m_StreamSettings.iInFrames / (float)m_StreamSettings.iInSamplerate; +} + +float CADSPProcessorHandle::PostProcessGetDelay(unsigned int Mode_id) +{ + return (float)m_StreamSettings.iInFrames / (float)m_StreamSettings.iInSamplerate; +} + +float CADSPProcessorHandle::MasterProcessGetDelay() +{ + return (float)m_StreamSettings.iInFrames / (float)m_StreamSettings.iInSamplerate; +} + +float CADSPProcessorHandle::PreProcessGetDelay(unsigned int Mode_id) +{ + return (float)m_StreamSettings.iInFrames / (float)m_StreamSettings.iInSamplerate; +} + +float CADSPProcessorHandle::InputResampleGetDelay() +{ + return (float)m_StreamSettings.iInFrames / (float)m_StreamSettings.iInSamplerate; +} diff --git a/src/template/AddonExceptions/IAddonException.h b/src/template/AddonExceptions/IAddonException.h new file mode 100644 index 0000000..b8330d4 --- /dev/null +++ b/src/template/AddonExceptions/IAddonException.h @@ -0,0 +1,49 @@ +#pragma once +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + + + +#include + +template +class IAddonException +{ + public: + IAddonException(std::string Function="", std::string Filename="", int Line=-1, std::string Module="") + { + m_Function = Function; + m_Filename = Filename; + m_Line = Line; + m_Module = Module; + m_Line = Line; + } + + virtual ~IAddonException() {} + + virtual T &what() = 0; + + protected: + T m_Exception; + std::string m_Function; + std::string m_Filename; + std::string m_Module; + int m_Line; +}; diff --git a/src/template/AddonExceptions/TAddonException.h b/src/template/AddonExceptions/TAddonException.h new file mode 100644 index 0000000..53d6f0d --- /dev/null +++ b/src/template/AddonExceptions/TAddonException.h @@ -0,0 +1,52 @@ +#pragma once +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + + + +#include +#include "IAddonException.h" + +template +class TAddonException : public IAddonException +{ + public: + TAddonException(T Exception, std::string Function="", std::string Filename="", int Line=-1, std::string Module="") + : IAddonException(Function, Filename, Line, Module) + { + IAddonException::m_Exception = Exception; + } + + virtual ~TAddonException() {} + + virtual T &what() { return IAddonException::m_Exception; } +}; + +// type definitions +typedef TAddonException CAddonStringException; + +#if defined (TARGET_WINDOWS) + #ifndef __func__ + #define __func__ __FUNCTION__ + #endif +#endif + +#define ADDON_STRING_EXCEPTION_HANDLER(ErrorStr) CAddonStringException(ErrorStr, __func__, __FILE__, __LINE__) +#define ADDON_STRING_MODULE_EXCEPTION_HANDLER(ErrorStr, Module) CAddonStringException(ErrorStr, __func__, __FILE__, __LINE__, Module) diff --git a/src/template/AddonHelpers.cpp b/src/template/AddonHelpers.cpp new file mode 100644 index 0000000..7abd519 --- /dev/null +++ b/src/template/AddonHelpers.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + + + +// reserved for future implementation +//#include "AddonHelpers.h" diff --git a/src/template/AddonHelpers.h b/src/template/AddonHelpers.h new file mode 100644 index 0000000..4132151 --- /dev/null +++ b/src/template/AddonHelpers.h @@ -0,0 +1,30 @@ +#pragma once +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + + + +// reserved for future implementation +//#include +//#include +// +//class CAddonException +//{ +//}; diff --git a/src/template/GUIDialogBase.cpp b/src/template/GUIDialogBase.cpp new file mode 100644 index 0000000..84412da --- /dev/null +++ b/src/template/GUIDialogBase.cpp @@ -0,0 +1,85 @@ +#include "include/GUIDialogBase.h" +using namespace std; +using namespace ADDON; + +CGUIDialogBase::CGUIDialogBase( std::string xmlFilename, bool ForceFallback, bool AsDialog, std::string DefaultSkin ) +{ + m_window = GUI->Window_create( xmlFilename.c_str(), + DefaultSkin.c_str(), + ForceFallback, + AsDialog ); + if(m_window) + { + m_window->m_cbhdl = this; + m_window->CBOnInit = OnInitCB; + m_window->CBOnFocus = OnFocusCB; + m_window->CBOnClick = OnClickCB; + m_window->CBOnAction = OnActionCB; + } + else + { + KODI->Log( LOG_ERROR, "Couldn't create m_window! Not enough free memory?" ); + } +} + +CGUIDialogBase::~CGUIDialogBase() +{ + if(m_window) + { + GUI->Window_destroy(m_window); + } +} + +bool CGUIDialogBase::OnInitCB(GUIHANDLE cbhdl) +{ + CGUIDialogBase *dialog = static_cast(cbhdl); + return dialog->OnInit(); +} + +bool CGUIDialogBase::OnClickCB(GUIHANDLE cbhdl, int controlId) +{ + CGUIDialogBase *dialog = static_cast(cbhdl); + return dialog->OnClick(controlId); +} + +bool CGUIDialogBase::OnFocusCB(GUIHANDLE cbhdl, int controlId) +{ + CGUIDialogBase *dialog = static_cast(cbhdl); + return dialog->OnFocus(controlId); +} + +bool CGUIDialogBase::OnActionCB(GUIHANDLE cbhdl, int actionId) +{ + CGUIDialogBase *dialog = static_cast(cbhdl); + return dialog->OnAction(actionId); +} + +bool CGUIDialogBase::Show() +{ + if (m_window) + { + return m_window->Show(); + } + else + { + return false; + } +} + +void CGUIDialogBase::Close() +{ + if (m_window) + { + m_window->Close(); + } + + OnClose(); +} + +void CGUIDialogBase::DoModal() +{ + if (m_window) + { + m_window->DoModal(); + } +} diff --git a/src/template/IADDONOptional.cpp b/src/template/IADDONOptional.cpp new file mode 100644 index 0000000..bc41e6c --- /dev/null +++ b/src/template/IADDONOptional.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#include "include/IADDONOptional.h" + +IADDONOptional::IADDONOptional() +{ +} + +IADDONOptional::~IADDONOptional() +{ +} \ No newline at end of file diff --git a/src/template/IADSPProcessor.cpp b/src/template/IADSPProcessor.cpp new file mode 100644 index 0000000..cab296c --- /dev/null +++ b/src/template/IADSPProcessor.cpp @@ -0,0 +1,88 @@ +#include "include/IADSPProcessor.h" +#include + +IADSPProcessor::IADSPProcessor() +{ +} + +IADSPProcessor::~IADSPProcessor() +{ +} + +unsigned int IADSPProcessor::PreProcessNeededSamplesize(unsigned int Mode_id) +{ + return 0; +} + +unsigned int IADSPProcessor::InputResampleProcessNeededSamplesize() +{ + return 1024; +} + +int IADSPProcessor::InputResampleSampleRate() +{ + return m_StreamSettings.iProcessSamplerate; +} + +AE_DSP_ERROR IADSPProcessor::MasterProcessSetMode(AE_DSP_STREAMTYPE Type, unsigned int Mode_id, int Unique_db_mode_id) +{ + return AE_DSP_ERROR_NO_ERROR; +} + +unsigned int IADSPProcessor::MasterProcessNeededSamplesize() +{ + return 1024; +} + +int IADSPProcessor::MasterProcessGetOutChannels(unsigned long &Out_channel_present_flags) +{ + return -1; +} + +const char *IADSPProcessor::MasterProcessGetStreamInfoString() +{ + return ""; +} + +unsigned int IADSPProcessor::PostProcessNeededSamplesize(unsigned int Mode_id) +{ + return 0; +} + +unsigned int IADSPProcessor::OutputResampleProcessNeededSamplesize() +{ + return 0; +} + +int IADSPProcessor::OutputResampleSampleRate() +{ + return m_StreamSettings.iProcessSamplerate; +} + +AE_DSP_ERROR IADSPProcessor::StreamIsModeSupported(AE_DSP_MODE_TYPE Type, unsigned int Mode_id, int Unique_db_mode_id) +{ + return AE_DSP_ERROR_NO_ERROR; +} + +AE_DSP_ERROR IADSPProcessor::GetStreamInfos(const AE_DSP_SETTINGS *pSettings, const AE_DSP_STREAM_PROPERTIES* pProperties, void *CustomStreamInfos) +{ + if(!pSettings || !pProperties) + { + return AE_DSP_ERROR_INVALID_PARAMETERS; + } + + memcpy((void*)pSettings, &m_StreamSettings, sizeof(AE_DSP_SETTINGS)); + memcpy((void*)pProperties, &m_StreamProperties, sizeof(AE_DSP_STREAM_PROPERTIES)); + + if(CustomStreamInfos) + { + return GetCustomStreamInfos(CustomStreamInfos); + } + + return AE_DSP_ERROR_NO_ERROR; +} + +AE_DSP_ERROR IADSPProcessor::GetCustomStreamInfos(void *CustomStreamSettings) +{ + return AE_DSP_ERROR_NO_ERROR; +} diff --git a/src/template/Messages/ADSPModeMessage.cpp b/src/template/Messages/ADSPModeMessage.cpp new file mode 100644 index 0000000..e7dea14 --- /dev/null +++ b/src/template/Messages/ADSPModeMessage.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2014-2015 Team KODI + * http://kodi.tv + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + */ + + + +#include "template/include/client.h" +#include "template/include/ADSPModeMessage.h" +#include "template/AddonExceptions/TAddonException.h" + +CADSPModeMessage::CADSPModeMessage() +{ + m_ProcessingModeId = 0; + m_StreamId = AE_DSP_STREAM_MAX_STREAMS; + m_MessageType = 0; + m_AudioChannel = AE_DSP_CH_MAX; + m_MessageDataSize = 0; + m_MessageData = NULL; +} + +CADSPModeMessage::~CADSPModeMessage() +{ + if(m_MessageData) + { + delete m_MessageData; + m_MessageData = NULL; + } +} + +unsigned int CADSPModeMessage::get_ProcessingModeId() +{ + return m_ProcessingModeId; +} + +AE_DSP_ERROR CADSPModeMessage::set_ProcessingModeId(unsigned int ModeId) +{ + if(!ModeId) + { + return AE_DSP_ERROR_INVALID_PARAMETERS; + } + m_ProcessingModeId = ModeId; + + return AE_DSP_ERROR_NO_ERROR; +} + +unsigned int CADSPModeMessage::get_StreamId() +{ + return m_StreamId; +} + +AE_DSP_ERROR CADSPModeMessage::set_StreamId(unsigned int StreamId) +{ + if(StreamId >= AE_DSP_STREAM_MAX_STREAMS) + { + return AE_DSP_ERROR_INVALID_PARAMETERS; + } + m_StreamId = StreamId; + + return AE_DSP_ERROR_NO_ERROR; +} + +unsigned int CADSPModeMessage::get_MessageType() +{ + return m_MessageType; +} + +AE_DSP_ERROR CADSPModeMessage::set_MessageType(unsigned int Type) +{ + if(!Type) + { + return AE_DSP_ERROR_INVALID_PARAMETERS; + } + m_MessageType = Type; + + return AE_DSP_ERROR_NO_ERROR; +} + +AE_DSP_CHANNEL CADSPModeMessage::get_AudioChannel() +{ + return m_AudioChannel; +} + +AE_DSP_ERROR CADSPModeMessage::set_AudioChannel(AE_DSP_CHANNEL AudioChannel) +{ + if(AudioChannel <= AE_DSP_CH_INVALID || AudioChannel >= AE_DSP_CH_MAX) + { + return AE_DSP_ERROR_INVALID_PARAMETERS; + } + m_AudioChannel = AudioChannel; + + return AE_DSP_ERROR_NO_ERROR; +} + +AE_DSP_ERROR CADSPModeMessage::get_MessageData(void *Data) +{ + if(!Data) + { + return AE_DSP_ERROR_INVALID_PARAMETERS; + } + + if(!m_MessageData || !m_MessageDataSize) + { + KODI->Log(ADDON::LOG_ERROR, "%s line %i: Invalid internal MessageData pointer! Not enough free dynamic memory available?", __func__, __LINE__); + return AE_DSP_ERROR_FAILED; + } + + memcpy(Data, m_MessageData, m_MessageDataSize); + + return AE_DSP_ERROR_NO_ERROR; +} + +AE_DSP_ERROR CADSPModeMessage::set_MessageData(void *Data, size_t DataSize) +{ + if(!Data) + { + return AE_DSP_ERROR_INVALID_PARAMETERS; + } + + if(DataSize > 0) + { + if(DataSize > m_MessageDataSize) + { + if(m_MessageData) + { + delete [] m_MessageData; + } + + m_MessageDataSize = DataSize; + m_MessageData = new uint8_t[m_MessageDataSize]; + } + + if(!m_MessageData) + { + KODI->Log(ADDON::LOG_ERROR, "%s line %i: Invalid internal MessageData pointer! Not enough free dynamic memory available?", __func__, __LINE__); + m_MessageDataSize = 0; + return AE_DSP_ERROR_FAILED; + } + } + + memcpy(m_MessageData, Data, m_MessageDataSize); + return AE_DSP_ERROR_NO_ERROR; +} + +size_t CADSPModeMessage::get_MessageDataSize() +{ + return m_MessageDataSize; +} + +AE_DSP_ERROR CADSPModeMessage::set_MessageDataSize(size_t DataSize) +{ + if(DataSize <= 0) + { + return AE_DSP_ERROR_INVALID_PARAMETERS; + } + + if(m_MessageDataSize == DataSize) + { // delete old data + memset(m_MessageData, 0, m_MessageDataSize); + return AE_DSP_ERROR_NO_ERROR; + } + + if(m_MessageData) + { + delete [] m_MessageData; + m_MessageData = NULL; + } + + m_MessageDataSize = DataSize; + m_MessageData = new uint8_t[m_MessageDataSize]; + if(!m_MessageData) + { + KODI->Log(ADDON::LOG_ERROR, "%s line %i: Invalid internal MessageData pointer! Not enough free dynamic memory available?", __func__, __LINE__); + return AE_DSP_ERROR_FAILED; + } + memset(m_MessageData, 0, m_MessageDataSize); + + return AE_DSP_ERROR_NO_ERROR; +} diff --git a/src/template/Settings/ISettingsElement.h b/src/template/Settings/ISettingsElement.h new file mode 100644 index 0000000..1fc8186 --- /dev/null +++ b/src/template/Settings/ISettingsElement.h @@ -0,0 +1,64 @@ +#pragma once +/* Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + + + +#include "../AddonExceptions/TAddonException.h" + +class ISettingsElement +{ +public: + typedef enum + { + UNKNOWN_SETTING = -1, + STRING_SETTING, + UNSIGNED_INT_SETTING, + INT_SETTING, + FLOAT_SETTING, + DOUBLE_SETTING, + BOOL_SETTING, + MAX_SETTING + }SettingsTypes; + + ISettingsElement(std::string Key, SettingsTypes Type) + { + if(Type <= UNKNOWN_SETTING || Type >= MAX_SETTING) + { + throw ADDON_STRING_EXCEPTION_HANDLER("Requested unsupported settings type!"); + } + + if(Key.empty() || Key == "") + { + throw ADDON_STRING_EXCEPTION_HANDLER("Invalid Key used!"); + } + + m_Type = Type; + m_Key = Key; + } + + virtual ~ISettingsElement() {} + + SettingsTypes get_Type() { return m_Type; } + std::string get_Key() { return m_Key; } + +private: + SettingsTypes m_Type; + std::string m_Key; +}; diff --git a/src/template/Settings/SettingsHelpers.cpp b/src/template/Settings/SettingsHelpers.cpp new file mode 100644 index 0000000..48d1659 --- /dev/null +++ b/src/template/Settings/SettingsHelpers.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + + + +#include "SettingsHelpers.h" + +using namespace std; + + +CSettingsHelpers::CSettingsHelpers() +{ +} + +CSettingsHelpers::~CSettingsHelpers() +{ +} + +string CSettingsHelpers::TranslateTypeEnumToStr(ISettingsElement::SettingsTypes eType) +{ + string type = "Unknown"; + + switch(eType) + { + case ISettingsElement::STRING_SETTING: + type = "string"; + break; + + case ISettingsElement::UNSIGNED_INT_SETTING: + type = "unsigned int"; + break; + + case ISettingsElement::INT_SETTING: + type = "int"; + break; + + case ISettingsElement::FLOAT_SETTING: + type = "float"; + break; + + case ISettingsElement::DOUBLE_SETTING: + type = "double"; + break; + + case ISettingsElement::BOOL_SETTING: + type = "bool"; + break; + + default: + type = "Unknown"; + break; + } + + return type; +} + +ISettingsElement::SettingsTypes CSettingsHelpers::TranslateTypeStrToEnum(string strType) +{ + ISettingsElement::SettingsTypes eType = ISettingsElement::UNKNOWN_SETTING; + + if(strType == "string") + { + eType = ISettingsElement::STRING_SETTING; + } + else if(strType == "unsigned int") + { + eType = ISettingsElement::UNSIGNED_INT_SETTING; + } + else if(strType == "int") + { + eType = ISettingsElement::INT_SETTING; + } + else if(strType == "float") + { + eType = ISettingsElement::FLOAT_SETTING; + } + else if(strType == "double") + { + eType = ISettingsElement::DOUBLE_SETTING; + } + else if(strType == "bool") + { + eType = ISettingsElement::BOOL_SETTING; + } + + return eType; +} diff --git a/src/template/Settings/SettingsHelpers.h b/src/template/Settings/SettingsHelpers.h new file mode 100644 index 0000000..3dd1a73 --- /dev/null +++ b/src/template/Settings/SettingsHelpers.h @@ -0,0 +1,35 @@ +#pragma once +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + + + +#include +#include "ISettingsElement.h" + +class CSettingsHelpers +{ +public: + CSettingsHelpers(); + ~CSettingsHelpers(); + + static std::string TranslateTypeEnumToStr(ISettingsElement::SettingsTypes eType); + static ISettingsElement::SettingsTypes TranslateTypeStrToEnum(std::string strType); +}; diff --git a/src/template/Settings/SettingsManager.cpp b/src/template/Settings/SettingsManager.cpp new file mode 100644 index 0000000..b65e364 --- /dev/null +++ b/src/template/Settings/SettingsManager.cpp @@ -0,0 +1,617 @@ +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + + + +#include +#include +#include "utils/stdStringUtils.h" +#include "SettingsHelpers.h" +#include "SettingsManager.h" +#include "../AddonExceptions/TAddonException.h" +#include "kodi/libXBMC_addon.h" +#include "exception" + +using namespace ADDON; +using namespace std; + +// helpers for XML-Files +#include +#include +typedef std::pair ATTRIBUTE_PAIR; +typedef std::list ATTRIBUTES_LIST; + +int getAttributesAsList(TiXmlElement* pElement, ATTRIBUTES_LIST &AttributesList); + + +CSettingsManager::CSettingsManager(string XMLFilename, string Path) +{ + if(XMLFilename == "" || XMLFilename.empty()) + { + throw ADDON_STRING_EXCEPTION_HANDLER("Invalid XML filename!"); + } + m_XMLFilename = generateFilePath(Path, XMLFilename); + KODI->Log(LOG_DEBUG, "CSettingsManager will save it's XML file to: %s", m_XMLFilename.c_str()); + + m_IsSettingsXMLLoaded = false; + + m_Settings.clear(); +} + +CSettingsManager::~CSettingsManager() +{ + destroy(); +} + +void CSettingsManager::Init() +{ + if(!m_IsSettingsXMLLoaded) + { + m_IsSettingsXMLLoaded = true; + read_SettingsXML(); + } +} + +void CSettingsManager::destroy() +{ + write_SettingsXML(); + + // delete settings map and its elements + for(SettingsMap::iterator mapIter = m_Settings.begin(); mapIter != m_Settings.end(); mapIter++) + { + for(CSettingsList::iterator listIter = mapIter->second.begin(); listIter != mapIter->second.end(); listIter++) + { + ISettingsElement *settingsElement = *listIter; + if(settingsElement) + { + delete settingsElement; + *listIter = NULL; + } + } + } + + // all dynamic memory is deallocated, so we can delete the settings map + m_Settings.clear(); +} + +void CSettingsManager::write_SettingsXML() +{ + try + { + if(m_Settings.size() > 0) + { + TiXmlDocument doc; + // ToDo: check all TiXml* generations! + TiXmlDeclaration *declaration = new TiXmlDeclaration("1.0", "", ""); + doc.LinkEndChild(declaration); + TiXmlComment *autoGenComment = new TiXmlComment(); + autoGenComment->SetValue(" THIS IS A AUTO GENERTATED FILE. DO NOT EDIT! "); + doc.LinkEndChild(autoGenComment); + + for(SettingsMap::iterator mapIter = m_Settings.begin(); mapIter != m_Settings.end(); mapIter++) + { + vector tokens; + strTokenizer(mapIter->first, SETTINGS_SEPERATOR_STR, tokens); + if(tokens.size() != 3) + { + doc.Clear(); + KODI->Log(LOG_ERROR, "Line: %i func: %s, Saving XML-File failed! Wrong SettingsMap string! Please call contact Addon author!\n", __LINE__, __func__, m_XMLFilename.c_str()); + return; + } + + TiXmlElement *mainCategory = NULL; + // check if this main category is already available + for(TiXmlNode *element = doc.FirstChild(); element && !mainCategory; element = element->NextSiblingElement()) + { + if(element->Value() == tokens[0]) + { + mainCategory = static_cast(element); + } + } + + if(!mainCategory) + { // create new main category + mainCategory = new TiXmlElement(tokens[0]); + doc.LinkEndChild(mainCategory); + } + + TiXmlElement *settingsGroup = new TiXmlElement("settings_group"); + settingsGroup->SetAttribute("sub_category", tokens[1].c_str()); + settingsGroup->SetAttribute("group_name", tokens[2].c_str()); + mainCategory->LinkEndChild(settingsGroup); + + for(CSettingsList::iterator setIter=mapIter->second.begin(); setIter != mapIter->second.end(); setIter++) + { + if(!*setIter) + { + KODI->Log(LOG_ERROR, "Line: %i func: %s, invalid settings element! Please call contact Addon author!\n", __LINE__, __func__); + return; + } + TiXmlElement *setting = new TiXmlElement("setting"); + setting->SetAttribute("key", (*setIter)->get_Key().c_str()); + + switch((*setIter)->get_Type()) + { + case ISettingsElement::STRING_SETTING: + setting->SetAttribute("string", STRING_SETTINGS(*setIter)->get_Setting().c_str()); + break; + + case ISettingsElement::UNSIGNED_INT_SETTING: + setting->SetAttribute("unsigned_int", toString(UNSIGNED_INT_SETTINGS(*setIter)->get_Setting()).c_str()); + break; + + case ISettingsElement::INT_SETTING: + setting->SetAttribute("int", INT_SETTINGS(*setIter)->get_Setting()); + break; + + case ISettingsElement::FLOAT_SETTING: + setting->SetDoubleAttribute("float", (double)FLOAT_SETTINGS(*setIter)->get_Setting()); + break; + + case ISettingsElement::DOUBLE_SETTING: + setting->SetDoubleAttribute("double", DOUBLE_SETTINGS(*setIter)->get_Setting()); + break; + + case ISettingsElement::BOOL_SETTING: + if(BOOL_SETTINGS(*setIter)->get_Setting()) + { + setting->SetAttribute("bool", "true"); + } + else + { + setting->SetAttribute("bool", "false"); + } + break; + + default: + KODI->Log(LOG_ERROR, "Line: %i func: %s, invalid settings type! Please call contact Addon author!\n", __LINE__, __func__); + return; + break; + } + + settingsGroup->LinkEndChild(setting); + } + } + + if(!doc.SaveFile(m_XMLFilename.c_str())) + { + KODI->Log(LOG_ERROR, "Couldn't save XML settings to file %s", m_XMLFilename.c_str()); + } + } + } + catch(bad_alloc &e) + { + KODI->Log(LOG_ERROR, "In function: %s a invalid memory allocation accured! Not enough free memory? Exception message: %s\n", __func__, e.what()); + } +} + +void CSettingsManager::read_SettingsXML() +{ + TiXmlDocument xmlDoc; + if(!xmlDoc.LoadFile(m_XMLFilename)) + { + KODI->Log(LOG_NOTICE, "No initial settings XML file found."); + return; + } + + TiXmlElement *pRootElement = xmlDoc.RootElement(); + if(!pRootElement) + { + KODI->Log(LOG_NOTICE, "Settings XML file is empty."); + return; + } + + string mainCategory = pRootElement->Value(); + for(TiXmlNode *pGroupNode = pRootElement->FirstChild(); pGroupNode != NULL; pGroupNode = pRootElement->IterateChildren(pGroupNode)) + { + if(pGroupNode->ValueStr() == "settings_group") + { + ATTRIBUTES_LIST groupAttributesList; + if(pGroupNode && pGroupNode->Type() == TiXmlNode::TINYXML_ELEMENT) + { + getAttributesAsList(pGroupNode->ToElement(), groupAttributesList); + } + + if(pGroupNode && pGroupNode->Type() == TiXmlNode::TINYXML_ELEMENT && groupAttributesList.size() == 2 && pGroupNode->ValueStr() == "settings_group") + { + string subCategory = ""; + string groupName = ""; + for(ATTRIBUTES_LIST::iterator iter = groupAttributesList.begin(); iter != groupAttributesList.end(); iter++) + { + if(iter->first == "sub_category") + { + subCategory = iter->second; + } + + if(iter->first == "group_name") + { + groupName = iter->second; + } + } + + for(TiXmlNode *pKeyNode = pGroupNode->FirstChild(); pKeyNode != NULL; pKeyNode = pGroupNode->IterateChildren(pKeyNode)) + { + if(pKeyNode && pKeyNode->Type() == TiXmlNode::TINYXML_ELEMENT && pKeyNode->ValueStr() == "setting") + { + ATTRIBUTES_LIST settingAttributesList; + if(getAttributesAsList(pKeyNode->ToElement(), settingAttributesList) == 2) + { + string key = ""; + ISettingsElement::SettingsTypes type = ISettingsElement::UNKNOWN_SETTING; + string value = ""; + for(ATTRIBUTES_LIST::iterator iter = settingAttributesList.begin(); iter != settingAttributesList.end(); iter++) + { + if(iter->first == "key") + { + key = iter->second; + } + else + { + type = CSettingsHelpers::TranslateTypeStrToEnum(iter->first); + value = iter->second; + } + } + + ISettingsElement *setting = find_Setting(mainCategory, subCategory, groupName, key); + if(setting && setting->get_Type() == type) + { + switch(type) + { + case ISettingsElement::STRING_SETTING: + STRING_SETTINGS(setting)->set_Setting(value); + break; + + case ISettingsElement::UNSIGNED_INT_SETTING: + { + unsigned int val = stringToVal(value); + UNSIGNED_INT_SETTINGS(setting)->set_Setting(val); + } + break; + + case ISettingsElement::INT_SETTING: + { + int val = stringToVal(value); + INT_SETTINGS(setting)->set_Setting(val); + } + break; + + case ISettingsElement::FLOAT_SETTING: + { + float val = stringToVal(value); + FLOAT_SETTINGS(setting)->set_Setting(val); + } + break; + + case ISettingsElement::DOUBLE_SETTING: + { + double val = stringToVal(value); + DOUBLE_SETTINGS(setting)->set_Setting(val); + } + break; + + case ISettingsElement::BOOL_SETTING: + if(value == "true" || value == "TRUE" || value == "True") + { + bool val = true; + BOOL_SETTINGS(setting)->set_Setting(val); + } + else if(value == "false" || value == "FALSE" || value == "False") + { + bool val = false; + BOOL_SETTINGS(setting)->set_Setting(val); + } + else + { + KODI->Log(LOG_ERROR, "CSettingsManager: Failed reading bool setting"); + } + break; + + default: + KODI->Log(LOG_ERROR, "CSettingsManager: Unknown settings type!"); + break; + } + } + else + { + KODI->Log(LOG_ERROR, "CSettingsManager: Read settings element does not match the created settings element type!"); + } + } + } + } + } + } + } +} + +bool CSettingsManager::add_Setting( string MainCategory, string SubCategory, + string GroupName, string Key, + ISettingsElement::SettingsTypes Type, void *Value) +{ + if(!Value) + { + KODI->Log(LOG_ERROR, "CSettingsManager: Invalid input for %s", __FUNCTION__); + return false; + } + + string settingsStr = MainCategory + SETTINGS_SEPERATOR_STR + SubCategory + SETTINGS_SEPERATOR_STR + GroupName; + SettingsMap::iterator mapIter = m_Settings.find(settingsStr); + if(mapIter != m_Settings.end()) + { // first we have to search, if the settings element is present in the founded Main- and Subcategory + CSettingsList::iterator settingsIter = mapIter->second.begin(); + while(settingsIter != mapIter->second.end() && (*settingsIter)->get_Key() != Key) + { + settingsIter++; + } + + if(settingsIter != mapIter->second.end() && (*settingsIter)->get_Key() == Key && Type == (*settingsIter)->get_Type()) + { // if the Type and Key are the same, we override the current setting with the new value + return SetNewElementValue(*settingsIter, Value); + } + } + + // No element with the requested Main- and Subcategory and Type exists + // so we create a new one + ISettingsElement *settingsElement = CSettingsManager::CreateElement(Key, Type, Value); + if(!settingsElement) + { + KODI->Log(LOG_ERROR, "CSettingsManager: Couldn't create settings element!"); + return false; + } + + if(mapIter != m_Settings.end()) + { + mapIter->second.push_back(settingsElement); + } + else + { + CSettingsList settingsList; + settingsList.push_back(settingsElement); + m_Settings[settingsStr] = settingsList; + } + + return true; +} + +ISettingsElement *CSettingsManager::CreateElement(string Key, ISettingsElement::SettingsTypes Type, void *Value) +{ + if(!Value) + { + KODI->Log(LOG_ERROR, "CSettingsManager: Invalid input for %s", __FUNCTION__); + return NULL; + } + + ISettingsElement *element = NULL; + switch(Type) + { + case ISettingsElement::STRING_SETTING: + { + string *pVal = static_cast(Value); + CStringSetting *p = new CStringSetting(*pVal, Key, Type); + + if(pVal && p) + { + element = dynamic_cast(p); + } + else + { + if(p) + { + delete p; + p = NULL; + } + } + } + break; + + case ISettingsElement::UNSIGNED_INT_SETTING: + { + unsigned int *pVal = (unsigned int*)(Value); + CUnsignedIntSetting *p = new CUnsignedIntSetting(*pVal, Key, Type); + + if(p) + { + element = dynamic_cast(p); + } + } + break; + + case ISettingsElement::INT_SETTING: + { + int *pVal = (int*)(Value); + CIntSetting *p = new CIntSetting(*pVal, Key, Type); + + if(p) + { + element = dynamic_cast(p); + } + } + break; + + case ISettingsElement::FLOAT_SETTING: + { + float *pVal = (float*)(Value); + CFloatSetting *p = new CFloatSetting(*pVal, Key, Type); + + if(p) + { + element = dynamic_cast(p); + } + } + break; + + case ISettingsElement::DOUBLE_SETTING: + { + double *pVal = (double*)(Value); + CDoubleSetting *p = new CDoubleSetting(*pVal, Key, Type); + + if(p) + { + element = dynamic_cast(p); + } + } + break; + + case ISettingsElement::BOOL_SETTING: + { + bool *pVal = (bool*)(Value); + CBoolSetting *p = new CBoolSetting(*pVal, Key, Type); + + if(p) + { + element = dynamic_cast(p); + } + } + break; + + default: + element = NULL; + break; + } + + return element; +} + +bool CSettingsManager::SetNewElementValue(ISettingsElement *Element, void *Value) +{ + if(!Element || !Value) + { + KODI->Log(LOG_ERROR, "CSettingsManager: Invalid input for %s", __FUNCTION__); + return false; + } + + switch(Element->get_Type()) + { + case ISettingsElement::STRING_SETTING: + STRING_SETTINGS(Element)->set_Setting(*static_cast(Value)); + break; + + case ISettingsElement::UNSIGNED_INT_SETTING: + UNSIGNED_INT_SETTINGS(Element)->set_Setting(*((unsigned int*)Value)); + break; + + case ISettingsElement::INT_SETTING: + INT_SETTINGS(Element)->set_Setting(*((int*)Value)); + break; + + case ISettingsElement::FLOAT_SETTING: + FLOAT_SETTINGS(Element)->set_Setting(*((float*)Value)); + break; + + case ISettingsElement::DOUBLE_SETTING: + DOUBLE_SETTINGS(Element)->set_Setting(*((double*)Value)); + break; + + case ISettingsElement::BOOL_SETTING: + BOOL_SETTINGS(Element)->set_Setting(*((bool*)Value)); + break; + + default: + return false; + break; + } + + return true; +} + +void CSettingsManager::destroy_Setting(string MainCategory, string SubCategory, string GroupName, string Key) +{ + string settingsStr = MainCategory + SETTINGS_SEPERATOR_STR + SubCategory + SETTINGS_SEPERATOR_STR + GroupName; + SettingsMap::iterator mapIter = m_Settings.find(settingsStr); + if(mapIter != m_Settings.end()) + { + CSettingsList::iterator listIter = mapIter->second.begin(); + + // search for the correct key + while(listIter != mapIter->second.end() && (*listIter)->get_Key() != Key) + { + listIter++; + } + + // if the key was found, delete this setting + if(listIter != mapIter->second.end() && (*listIter)->get_Key() != Key) + { + if(*listIter) + { + delete *listIter; + *listIter = NULL; + } + + // erase this setting from the list + mapIter->second.erase(listIter); + } + + // check if there are other settings, else delete this Main- and Subcategory + if(mapIter->second.size() <= 0) + { + m_Settings.erase(mapIter); + } + + if(listIter == mapIter->second.end()) + { + KODI->Log(LOG_NOTICE, "CSettingsManager: Requested settings element \"%s\" in method \"%s\" not found!", settingsStr.c_str(), __FUNCTION__); + } + } + else + { + KODI->Log(LOG_NOTICE, "CSettingsManager: Requested settings element \"%s\" in method \"%s\" not found!", settingsStr.c_str(), __FUNCTION__); + } +} + +ISettingsElement *CSettingsManager::find_Setting(string MainCategory, string SubCategory, string GroupName, string Key) +{ + string settingsStr = MainCategory + SETTINGS_SEPERATOR_STR + SubCategory + SETTINGS_SEPERATOR_STR + GroupName; + SettingsMap::iterator mapIter = m_Settings.end(); + if(m_Settings.size() > 0) + { + mapIter = m_Settings.find(settingsStr); + } + if(mapIter != m_Settings.end()) + { + CSettingsList::iterator listIter = mapIter->second.begin(); + + // search for the correct key + while(listIter != mapIter->second.end() && (*listIter)->get_Key() != Key) + { + listIter++; + } + + if(listIter != mapIter->second.end() && (*listIter)->get_Key() == Key) + { + return *listIter; + } + } + + KODI->Log(LOG_NOTICE, "CSettingsManager: Couldn't find requested settings element \"%s\" in method \"%s\" not found!", settingsStr.c_str(), __FUNCTION__); + return NULL; +} + + +// Helper functions for XML-Files +int getAttributesAsList(TiXmlElement* pElement, ATTRIBUTES_LIST &AttributesList) +{ + if ( !pElement ) return -1; + + for(TiXmlAttribute *pAttrib = pElement->FirstAttribute(); pAttrib != NULL; pAttrib = pAttrib->Next()) + { + AttributesList.push_back(ATTRIBUTE_PAIR(pAttrib->Name(), pAttrib->Value())); + } + + return AttributesList.size(); +} diff --git a/src/template/Settings/SettingsManager.h b/src/template/Settings/SettingsManager.h new file mode 100644 index 0000000..328b58e --- /dev/null +++ b/src/template/Settings/SettingsManager.h @@ -0,0 +1,83 @@ +#pragma once +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + + + +#include +#include +#include +#include