mirror of
https://github.com/eclipse-openvehicle-api/openvehicle-api.git
synced 2026-04-11 08:00:24 +00:00
732 lines
26 KiB
C++
732 lines
26 KiB
C++
/********************************************************************************
|
|
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
|
*
|
|
* This program and the accompanying materials are made available under the
|
|
* terms of the Apache License Version 2.0 which is available at
|
|
* https://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Contributors:
|
|
* Erik Verhoeven - initial API and implementation
|
|
********************************************************************************/
|
|
|
|
#ifndef PARAM_IMPL_INL
|
|
#define PARAM_IMPL_INL
|
|
|
|
#ifndef PARAM_IMPL_H
|
|
#include "param_impl.h"
|
|
#endif //! defined PARAM_IMPL_H
|
|
|
|
#include <regex>
|
|
#include <set>
|
|
|
|
/**
|
|
* @brief Software Defined Vehicle framework.
|
|
*/
|
|
namespace sdv
|
|
{
|
|
template <typename TVar, typename TDefaultType>
|
|
inline CSdvParamInfo::CSdvParamInfo(TVar&, const std::string& rssName, TDefaultType tDefaultVal, const std::string& rssUnit,
|
|
const std::string& rssCategory, const std::string& rssDescription, uint32_t uiFlagsParam)
|
|
{
|
|
EParamType eTypeLocal = EParamType::boolean_param;
|
|
|
|
if constexpr (std::is_same_v<TVar, bool>)
|
|
eTypeLocal = EParamType::boolean_param;
|
|
else if constexpr (std::is_arithmetic_v<TVar>)
|
|
eTypeLocal = EParamType::number_param; // No number limitation
|
|
else if constexpr (TypeIsString<TVar>())
|
|
eTypeLocal = EParamType::string_param; // No pattern
|
|
else if constexpr (std::is_enum_v<TVar>)
|
|
eTypeLocal = EParamType::enum_param; // No enumerator labels
|
|
else
|
|
static_assert(sdv::internal::always_false_v<TVar>, "The parameter type is not supported!");
|
|
|
|
any_t anyDefaultValLocal;
|
|
if constexpr (std::is_enum_v<TVar>)
|
|
{
|
|
static_assert(std::is_same_v<std::remove_reference_t<std::remove_const_t<TVar>>, TDefaultType>,
|
|
"The enum types of the value and the default value must be identical!");
|
|
anyDefaultValLocal = static_cast<std::underlying_type_t<TVar>>(tDefaultVal);
|
|
}
|
|
else
|
|
anyDefaultValLocal = tDefaultVal;
|
|
|
|
uint32_t uiFlagsLocal = uiFlagsParam;
|
|
if (TypeIsReadOnly<TVar>())
|
|
uiFlagsLocal |= static_cast<uint32_t>(EParamFlags::read_only);
|
|
if (uiFlagsLocal & static_cast<uint32_t>(EParamFlags::read_only))
|
|
uiFlagsLocal &= ~static_cast<uint32_t>(EParamFlags::locked); // Readonly cannot write
|
|
Init(eTypeLocal, rssName, anyDefaultValLocal, rssUnit, rssCategory, rssDescription, uiFlagsLocal);
|
|
|
|
if constexpr (std::is_enum_v<TVar>)
|
|
uExtInfo.sEnumInfo.seqLabels = internal::GetLabelMapHelper().GetLabelMap<TVar>();
|
|
}
|
|
|
|
template <typename TVar, typename TDefaultType>
|
|
inline CSdvParamInfo::CSdvParamInfo(TVar&, const std::string& rssName, TDefaultType tDefaultVal, const any_t& ranyLimitLow,
|
|
bool bIncludeLow, const any_t& ranyLimitHigh, bool bIncludeHigh, const std::string& rssUnit, const std::string& rssCategory,
|
|
const std::string& rssDescription, uint32_t uiFlagsParam)
|
|
{
|
|
static_assert(std::is_arithmetic_v<TVar> && !std::is_same_v<TVar, bool>,
|
|
"The construct function for numeric types expects the type to be numeric.");
|
|
uint32_t uiFlagsLocal = uiFlagsParam;
|
|
if (TypeIsReadOnly<TVar>())
|
|
uiFlagsLocal |= static_cast<uint32_t>(EParamFlags::read_only);
|
|
if (uiFlagsLocal & static_cast<uint32_t>(EParamFlags::read_only))
|
|
uiFlagsLocal &= ~static_cast<uint32_t>(EParamFlags::locked); // Readonly cannot write
|
|
Init(EParamType::number_param, rssName, tDefaultVal, rssUnit, rssCategory, rssDescription, uiFlagsLocal);
|
|
uExtInfo.sNumberInfo.anyLowerLimit = ranyLimitLow;
|
|
uExtInfo.sNumberInfo.bIncludeLowerLinit = bIncludeLow;
|
|
uExtInfo.sNumberInfo.anyUpperLimit = ranyLimitHigh;
|
|
uExtInfo.sNumberInfo.bIncludeUpperLimit = bIncludeHigh;
|
|
}
|
|
|
|
template <typename TVar, typename TDefaultType>
|
|
inline CSdvParamInfo::CSdvParamInfo(TVar&, const std::string& rssName, TDefaultType tDefaultVal, const std::string& rssPattern,
|
|
const std::string& rssUnit, const std::string& rssCategory, const std::string& rssDescription, uint32_t uiFlagsParam)
|
|
{
|
|
static_assert(TypeIsString<TVar>(), "The construct function for string types expects the type to be a string.");
|
|
uint32_t uiFlagsLocal = uiFlagsParam;
|
|
if (TypeIsReadOnly<TVar>())
|
|
uiFlagsLocal |= static_cast<uint32_t>(EParamFlags::read_only);
|
|
if (uiFlagsLocal & static_cast<uint32_t>(EParamFlags::read_only))
|
|
uiFlagsLocal &= ~static_cast<uint32_t>(EParamFlags::locked); // Readonly cannot write
|
|
Init(EParamType::string_param, rssName, tDefaultVal, rssUnit, rssCategory, rssDescription, uiFlagsLocal);
|
|
uExtInfo.sStringInfo.ssPattern = rssPattern;
|
|
}
|
|
|
|
template <typename TVar, typename TDefaultType>
|
|
inline CSdvParamInfo::CSdvParamInfo(TVar&, const std::string& rssName, TDefaultType tDefaultVal,
|
|
const sequence<SLabelInfo::SLabel>& rseqLabels, const std::string& rssCategory, const std::string& rssDescription,
|
|
uint32_t uiFlagsParam)
|
|
{
|
|
static_assert(std::is_enum_v<TVar> || (std::is_integral_v<TVar> && !std::is_same_v<TVar, bool>),
|
|
"The construct function for enumerators and bitmasks expects the type to be an enum or an integral type.");
|
|
uint32_t uiFlagsLocal = uiFlagsParam;
|
|
if (TypeIsReadOnly<TVar>())
|
|
uiFlagsLocal |= static_cast<uint32_t>(EParamFlags::read_only);
|
|
if (uiFlagsLocal & static_cast<uint32_t>(EParamFlags::read_only))
|
|
uiFlagsLocal &= ~static_cast<uint32_t>(EParamFlags::locked); // Readonly cannot write
|
|
if constexpr (std::is_enum_v<TVar>)
|
|
{
|
|
Init(EParamType::enum_param, rssName, static_cast<std::underlying_type_t<TVar>>(tDefaultVal), "",
|
|
rssCategory, rssDescription, uiFlagsLocal);
|
|
uExtInfo.sEnumInfo.seqLabels = rseqLabels;
|
|
}
|
|
else
|
|
{
|
|
Init(EParamType::bitmask_param, rssName, tDefaultVal, "", rssCategory, rssDescription, uiFlagsLocal);
|
|
uExtInfo.sBitmaskInfo.seqLabels = rseqLabels;
|
|
}
|
|
}
|
|
|
|
inline CSdvParamInfo::CSdvParamInfo(const SParamInfo& rInfo) : SParamInfo(rInfo)
|
|
{}
|
|
|
|
inline CSdvParamInfo::CSdvParamInfo(SParamInfo&& rInfo) : SParamInfo(std::move(rInfo))
|
|
{}
|
|
|
|
inline CSdvParamInfo& CSdvParamInfo::operator=(const SParamInfo& rsInfo)
|
|
{
|
|
static_cast<SParamInfo&>(*this) = rsInfo;
|
|
return *this;
|
|
}
|
|
|
|
inline CSdvParamInfo& CSdvParamInfo::operator=(SParamInfo&& rsInfo)
|
|
{
|
|
static_cast<SParamInfo&>(*this) = std::move(rsInfo);
|
|
return *this;
|
|
}
|
|
|
|
inline SParamInfo CSdvParamInfo::InfoStruct() const
|
|
{
|
|
return *this;
|
|
}
|
|
|
|
inline const u8string& CSdvParamInfo::Name() const
|
|
{
|
|
return SParamInfo::ssName;
|
|
}
|
|
|
|
inline u8string CSdvParamInfo::Path() const
|
|
{
|
|
sdv::u8string ssPath;
|
|
if (!SParamInfo::ssGroup.empty())
|
|
ssPath += ssGroup + ".";
|
|
ssPath += ssName;
|
|
return ssPath;
|
|
}
|
|
|
|
inline const any_t& CSdvParamInfo::DefaultVal() const
|
|
{
|
|
return SParamInfo::anyDefaultVal;
|
|
}
|
|
|
|
inline const u8string& CSdvParamInfo::Group() const
|
|
{
|
|
return SParamInfo::ssGroup;
|
|
}
|
|
|
|
inline const u8string& CSdvParamInfo::Description() const
|
|
{
|
|
return SParamInfo::ssDescription;
|
|
}
|
|
|
|
inline const u8string& CSdvParamInfo::Unit() const
|
|
{
|
|
return SParamInfo::ssUnit;
|
|
}
|
|
|
|
inline uint32_t CSdvParamInfo::Flags() const
|
|
{
|
|
return uiFlags;
|
|
}
|
|
|
|
inline bool CSdvParamInfo::ReadOnly() const
|
|
{
|
|
return (uiFlags & static_cast<uint32_t>(EParamFlags::read_only)) ? true : false;
|
|
}
|
|
|
|
inline bool CSdvParamInfo::Temporary() const
|
|
{
|
|
return (uiFlags & static_cast<uint32_t>(EParamFlags::temporary)) ? true : false;
|
|
}
|
|
|
|
inline bool CSdvParamInfo::Dirty() const
|
|
{
|
|
return (uiFlags & static_cast<uint32_t>(EParamFlags::dirty)) ? true : false;
|
|
}
|
|
|
|
inline bool CSdvParamInfo::Locked() const
|
|
{
|
|
return (uiFlags & static_cast<uint32_t>(EParamFlags::locked)) ? true : false;
|
|
}
|
|
|
|
|
|
inline bool CSdvParamInfo::Boolean() const
|
|
{
|
|
return get_switch() == EParamType::boolean_param;
|
|
}
|
|
|
|
inline bool CSdvParamInfo::Numeric() const
|
|
{
|
|
return get_switch() == EParamType::number_param;
|
|
}
|
|
|
|
inline bool CSdvParamInfo::String() const
|
|
{
|
|
return get_switch() == EParamType::string_param;
|
|
}
|
|
|
|
inline bool CSdvParamInfo::Enum() const
|
|
{
|
|
return get_switch() == EParamType::enum_param;
|
|
}
|
|
|
|
inline bool CSdvParamInfo::Bitmask() const
|
|
{
|
|
return get_switch() == EParamType::bitmask_param;
|
|
}
|
|
|
|
inline std::pair<any_t, bool> CSdvParamInfo::NumericLimitLow() const
|
|
{
|
|
if (!Numeric()) return {};
|
|
return std::make_pair(uExtInfo.sNumberInfo.anyLowerLimit, uExtInfo.sNumberInfo.bIncludeLowerLinit);
|
|
}
|
|
|
|
inline std::pair<any_t, bool> CSdvParamInfo::NumericLimitHigh() const
|
|
{
|
|
if (!Numeric()) return {};
|
|
return std::make_pair(uExtInfo.sNumberInfo.anyUpperLimit, uExtInfo.sNumberInfo.bIncludeUpperLimit);
|
|
}
|
|
|
|
inline std::string CSdvParamInfo::StringPattern() const
|
|
{
|
|
if (!String()) return {};
|
|
return uExtInfo.sStringInfo.ssPattern;
|
|
}
|
|
|
|
inline sequence<SLabelInfo::SLabel> CSdvParamInfo::EnumBitmaskLabels() const
|
|
{
|
|
if (Enum())
|
|
return uExtInfo.sEnumInfo.seqLabels;
|
|
else if (Bitmask())
|
|
return uExtInfo.sBitmaskInfo.seqLabels;
|
|
else
|
|
return {};
|
|
}
|
|
|
|
inline void CSdvParamInfo::Init(EParamType eTypeParam, const std::string& rssName, const any_t& ranyDefaultVal,
|
|
const std::string& rssUnit, const std::string& rssCategory, const std::string& rssDescription, uint32_t uiFlagsParam)
|
|
{
|
|
switch_to(eTypeParam);
|
|
uiFlags = uiFlagsParam;
|
|
ssName = rssName;
|
|
anyDefaultVal = ranyDefaultVal;
|
|
ssUnit = rssUnit;
|
|
ssGroup = rssCategory;
|
|
ssDescription = rssDescription;
|
|
}
|
|
|
|
namespace internal
|
|
{
|
|
template <typename... TInfoConstruct>
|
|
inline CParamGuardian::CParamGuardian(bool bLockable, bool bAutoDirty, TInfoConstruct... tConstruct) :
|
|
CSdvParamInfo(tConstruct...), m_bLockable(bLockable), m_bAutoDirty(bAutoDirty)
|
|
{}
|
|
|
|
inline SParamInfo CParamGuardian::InfoStruct() const
|
|
{
|
|
sdv::SParamInfo sInfo = CSdvParamInfo::InfoStruct();
|
|
sInfo.uiFlags = Flags();
|
|
return sInfo;
|
|
}
|
|
|
|
inline uint32_t CParamGuardian::Flags() const
|
|
{
|
|
uint32_t uiFlagsTemp = CSdvParamInfo::Flags() & ~static_cast<uint32_t>(EParamFlags::state_mask);
|
|
if (m_bLocked)
|
|
uiFlagsTemp |= static_cast<uint32_t>(EParamFlags::locked);
|
|
if (m_bDirty)
|
|
uiFlagsTemp |= static_cast<uint32_t>(EParamFlags::dirty);
|
|
return uiFlagsTemp;
|
|
}
|
|
|
|
inline bool CParamGuardian::UpdateDirty(const sdv::any_t& ranyValue)
|
|
{
|
|
if (!m_bAutoDirty) return false;
|
|
bool bDirty = m_bDirty;
|
|
m_bDirty |= ranyValue != m_anyStored;
|
|
m_anyStored = ranyValue;
|
|
return m_bDirty != bDirty;
|
|
}
|
|
|
|
inline bool CParamGuardian::SetDirty()
|
|
{
|
|
bool bDirty = m_bDirty;
|
|
m_bDirty = true;
|
|
return m_bDirty != bDirty;
|
|
}
|
|
|
|
inline bool CParamGuardian::ResetDirty()
|
|
{
|
|
bool bDirty = m_bDirty;
|
|
m_bDirty = false;
|
|
return m_bDirty != bDirty;
|
|
}
|
|
|
|
inline bool CParamGuardian::Dirty() const
|
|
{
|
|
return m_bDirty;
|
|
}
|
|
|
|
inline bool CParamGuardian::Lockable() const
|
|
{
|
|
return m_bLockable;
|
|
}
|
|
|
|
inline bool CParamGuardian::Lock()
|
|
{
|
|
if (!m_bLockable)
|
|
return false;
|
|
bool bLocked = m_bLocked;
|
|
m_bLocked = true;
|
|
return m_bLocked != bLocked;
|
|
}
|
|
|
|
inline bool CParamGuardian::Unlock()
|
|
{
|
|
if (!m_bLockable)
|
|
return false;
|
|
bool bLocked = m_bLocked;
|
|
m_bLocked = false;
|
|
return m_bLocked != bLocked;
|
|
}
|
|
|
|
inline bool CParamGuardian::Locked() const
|
|
{
|
|
return m_bLocked;
|
|
}
|
|
|
|
inline bool CParamGuardian::CheckRestrictions(const any_t& ranyValue)
|
|
{
|
|
if (Numeric())
|
|
{
|
|
// Check for lower limit
|
|
auto prLimitLow = NumericLimitLow();
|
|
if (!prLimitLow.first.empty())
|
|
{
|
|
if (prLimitLow.second)
|
|
{
|
|
if (ranyValue < prLimitLow.first) return false;
|
|
} else
|
|
{
|
|
if (ranyValue <= prLimitLow.first) return false;
|
|
}
|
|
}
|
|
// Check for higher limit
|
|
auto prLimitHigh = NumericLimitHigh();
|
|
if (!prLimitHigh.first.empty())
|
|
{
|
|
if (prLimitHigh.second)
|
|
{
|
|
if (ranyValue > prLimitHigh.first) return false;
|
|
}
|
|
else
|
|
{
|
|
if (ranyValue >= prLimitHigh.first) return false;
|
|
}
|
|
}
|
|
}
|
|
else if (String())
|
|
{
|
|
// Check for compatibility to the regular expression pattern.
|
|
if (!StringPattern().empty())
|
|
{
|
|
std::regex regexPattern(StringPattern());
|
|
if (!std::regex_match(static_cast<std::string>(ranyValue), regexPattern)) return false;
|
|
}
|
|
}
|
|
else if (Enum())
|
|
{
|
|
// Check for occurrence in the label sequence
|
|
auto seqLabels = EnumBitmaskLabels();
|
|
if (std::find_if(seqLabels.begin(), seqLabels.end(), [&](const auto& rsLabel)
|
|
{ return ranyValue == rsLabel.anyValue; }) == seqLabels.end()) return false;
|
|
}
|
|
else if (Bitmask())
|
|
{
|
|
// Check for the occurence of each set bit in the label sequence
|
|
auto seqLabels = EnumBitmaskLabels();
|
|
uint64_t uiBitmask = ranyValue;
|
|
for (const auto& rsLabel : seqLabels)
|
|
uiBitmask &= ~static_cast<uint64_t>(rsLabel.anyValue);
|
|
if (uiBitmask) return false;
|
|
}
|
|
|
|
// All okay; restrictions were checked
|
|
return true;
|
|
}
|
|
|
|
template <typename TVar>
|
|
template <typename... TInfoConstruct>
|
|
inline CParamValue<TVar>::CParamValue(TVar& rtVar, bool bLockable, bool bAutoDirty, TInfoConstruct... tConstruct) :
|
|
CParamGuardian(bLockable, bAutoDirty, rtVar, tConstruct...), m_rtVar(rtVar)
|
|
{
|
|
// Assign the default value
|
|
if constexpr (!CSdvParamInfo::TypeIsReadOnly<TVar>())
|
|
{
|
|
m_rtVar = DefaultVal().get<TVar>();
|
|
UpdateDirty(DefaultVal());
|
|
ResetDirty();
|
|
}
|
|
}
|
|
|
|
template <typename TVar>
|
|
inline bool CParamValue<TVar>::Set(const any_t& ranyValue)
|
|
{
|
|
// Assign the value
|
|
if constexpr (!CSdvParamInfo::TypeIsReadOnly<TVar>())
|
|
{
|
|
if (!Locked() && !ReadOnly() && CheckRestrictions(ranyValue))
|
|
{
|
|
m_rtVar = ranyValue.get<TVar>();
|
|
UpdateDirty(ranyValue);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
template <typename TVar>
|
|
inline any_t CParamValue<TVar>::Get() const
|
|
{
|
|
// Remarks: in case of an enum, an explicit construction is needed.
|
|
return sdv::any_t(m_rtVar);
|
|
}
|
|
} // namespace internal
|
|
|
|
inline std::shared_ptr<internal::CParamGuardian> CSdvParamMap::FindParamObject(const sdv::u8string& rssPath)
|
|
{
|
|
// Iterate through the registrations
|
|
for (const SParamRegistration& rsRegistration : m_vecParamMapRegistration)
|
|
{
|
|
// Member parameter map entry
|
|
if (rsRegistration.MemberMap() && rsRegistration.MemberMap()->Access())
|
|
{
|
|
auto ptrParameter = rsRegistration.MemberMap()->Access()->FindParamObject(rssPath);
|
|
if (ptrParameter) return ptrParameter;
|
|
}
|
|
|
|
// Parameter entry
|
|
if (rsRegistration.Parameter() && rsRegistration.Parameter()->Path() == rssPath)
|
|
return rsRegistration.Parameter();
|
|
}
|
|
return {};
|
|
}
|
|
|
|
inline std::shared_ptr<const internal::CParamGuardian> CSdvParamMap::FindParamObject(const sdv::u8string& rssPath) const
|
|
{
|
|
// Iterate through the registrations
|
|
for (const SParamRegistration& rsRegistration : m_vecParamMapRegistration)
|
|
{
|
|
// Member parameter map entry
|
|
if (rsRegistration.MemberMap() && rsRegistration.MemberMap()->Access())
|
|
{
|
|
auto ptrParameter = rsRegistration.MemberMap()->Access()->FindParamObject(rssPath);
|
|
if (ptrParameter)
|
|
return ptrParameter;
|
|
}
|
|
|
|
// Parameter entry
|
|
if (rsRegistration.Parameter() && rsRegistration.Parameter()->Path() == rssPath)
|
|
return rsRegistration.Parameter();
|
|
}
|
|
return {};
|
|
}
|
|
|
|
inline sequence<u8string> CSdvParamMap::GetParamPaths() const
|
|
{
|
|
// Split path function (splits the group from the parameter names)
|
|
auto fnSplitPath = [](const sdv::u8string& rssPath) -> std::pair<sdv::u8string, sdv::u8string>
|
|
{
|
|
size_t nPos = rssPath.find_last_of('.');
|
|
if (nPos == sdv::u8string::npos)
|
|
return std::make_pair("", rssPath);
|
|
return std::make_pair(rssPath.substr(0, nPos), rssPath.substr(nPos + 1));
|
|
};
|
|
|
|
std::set<u8string> setOneTime;
|
|
sequence<u8string> seqPaths;
|
|
for (const auto& rsRegistration : m_vecParamMapRegistration)
|
|
{
|
|
// Add a path to the sequence.
|
|
auto fnAddPath = [&](const u8string& rssPath)
|
|
{
|
|
// Check if already present in the list
|
|
if (setOneTime.find(rssPath) != setOneTime.end()) return;
|
|
setOneTime.insert(rssPath);
|
|
|
|
// Sort the paths per group, so all paths belonging to one group is returned together.
|
|
// Find thee first location where the group is larger than the one of this path.
|
|
auto prPath = fnSplitPath(rssPath);
|
|
auto itPos = seqPaths.begin();
|
|
while (itPos != seqPaths.end())
|
|
{
|
|
auto prStoredPath = fnSplitPath(*itPos);
|
|
if (prPath.first.compare(prStoredPath.first) < 0) break;
|
|
++itPos;
|
|
}
|
|
|
|
// Insert into the sequence
|
|
seqPaths.insert(itPos, rssPath);
|
|
};
|
|
|
|
// Add the chained member to the list
|
|
if (rsRegistration.MemberMap() && rsRegistration.MemberMap()->Access())
|
|
{
|
|
auto seqNamesMemberMap = rsRegistration.MemberMap()->Access()->GetParamPaths();
|
|
for (const auto& rssPath : seqNamesMemberMap)
|
|
fnAddPath(rssPath);
|
|
}
|
|
|
|
// Add the parameter to the list
|
|
if (rsRegistration.Parameter())
|
|
fnAddPath(rsRegistration.Parameter()->Path());
|
|
}
|
|
|
|
return seqPaths;
|
|
}
|
|
|
|
inline any_t CSdvParamMap::GetParam(const u8string& rssPath) const
|
|
{
|
|
auto ptrParam = FindParamObject(rssPath);
|
|
if (!ptrParam) return {};
|
|
return ptrParam->Get();
|
|
}
|
|
|
|
inline bool CSdvParamMap::SetParam(const u8string& rssPath, any_t ranyValue)
|
|
{
|
|
auto ptrParam = FindParamObject(rssPath);
|
|
if (!ptrParam) return false;
|
|
return ptrParam->Set(ranyValue);
|
|
}
|
|
|
|
inline SParamInfo CSdvParamMap::GetParamInfo(const u8string& rssPath) const
|
|
{
|
|
auto ptrParamInfo = FindParamObject(rssPath);
|
|
if (!ptrParamInfo) return {};
|
|
return ptrParamInfo.get()->InfoStruct();
|
|
}
|
|
|
|
inline bool CSdvParamMap::IsParamDirty(const u8string& rssPath) const
|
|
{
|
|
auto ptrParam = FindParamObject(rssPath);
|
|
if (!ptrParam) return false;
|
|
return ptrParam->Dirty();
|
|
}
|
|
|
|
inline void CSdvParamMap::SetParamDirtyFlag(const std::string& rssPath)
|
|
{
|
|
auto ptrParam = FindParamObject(rssPath);
|
|
if (!ptrParam) return;
|
|
ptrParam->SetDirty();
|
|
}
|
|
|
|
inline void CSdvParamMap::ResetParamDirtyFlag(const u8string& rssPath)
|
|
{
|
|
auto ptrParam = FindParamObject(rssPath);
|
|
if (!ptrParam) return;
|
|
ptrParam->ResetDirty();
|
|
}
|
|
|
|
inline bool CSdvParamMap::IsParamMapDirty() const
|
|
{
|
|
std::set<u8string> setOneTime;
|
|
for (const auto& rsRegistration : m_vecParamMapRegistration)
|
|
{
|
|
// Member parameter map entry
|
|
if (rsRegistration.MemberMap() && rsRegistration.MemberMap()->Access())
|
|
{
|
|
if (rsRegistration.MemberMap()->Access()->IsParamMapDirty())
|
|
return true;
|
|
continue;
|
|
}
|
|
|
|
// Parameter entry
|
|
if (rsRegistration.Parameter())
|
|
{
|
|
// Check if already present in the list
|
|
if (setOneTime.find(rsRegistration.Parameter()->Name()) != setOneTime.end())
|
|
continue;
|
|
setOneTime.insert(rsRegistration.Parameter()->Name());
|
|
|
|
// Check for dirtiness
|
|
if (rsRegistration.Parameter()->Dirty())
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
inline void CSdvParamMap::ResetParamMapDirtyFlags()
|
|
{
|
|
std::set<u8string> setOneTime;
|
|
for (const auto& rsRegistration : m_vecParamMapRegistration)
|
|
{
|
|
// Member parameter map entry
|
|
if (rsRegistration.MemberMap() && rsRegistration.MemberMap()->Access())
|
|
{
|
|
rsRegistration.MemberMap()->Access()->ResetParamMapDirtyFlags();
|
|
continue;
|
|
}
|
|
|
|
// Parameter entry
|
|
if (rsRegistration.Parameter())
|
|
{
|
|
// Check if already present in the list
|
|
if (setOneTime.find(rsRegistration.Parameter()->Name()) != setOneTime.end())
|
|
continue;
|
|
setOneTime.insert(rsRegistration.Parameter()->Name());
|
|
|
|
// Reset dirtiness
|
|
rsRegistration.Parameter()->ResetDirty();
|
|
}
|
|
}
|
|
}
|
|
|
|
inline void CSdvParamMap::LockParamMap()
|
|
{
|
|
for (const auto& rsRegistration : m_vecParamMapRegistration)
|
|
{
|
|
// Member parameter map entry
|
|
if (rsRegistration.MemberMap() && rsRegistration.MemberMap()->Access())
|
|
{
|
|
rsRegistration.MemberMap()->Access()->LockParamMap();
|
|
continue;
|
|
}
|
|
|
|
// Parameter entry
|
|
if (rsRegistration.Parameter())
|
|
{
|
|
// Lock
|
|
rsRegistration.Parameter()->Lock();
|
|
}
|
|
}
|
|
}
|
|
|
|
inline void CSdvParamMap::UnlockParamMap()
|
|
{
|
|
for (const auto& rsRegistration : m_vecParamMapRegistration)
|
|
{
|
|
// Member parameter map entry
|
|
if (rsRegistration.MemberMap() && rsRegistration.MemberMap()->Access())
|
|
{
|
|
rsRegistration.MemberMap()->Access()->UnlockParamMap();
|
|
continue;
|
|
}
|
|
|
|
// Parameter entry
|
|
if (rsRegistration.Parameter())
|
|
{
|
|
// Lock
|
|
rsRegistration.Parameter()->Unlock();
|
|
}
|
|
}
|
|
}
|
|
|
|
template <typename TVar, typename... TConstruct>
|
|
inline std::shared_ptr<CSdvParamInfo> CSdvParamMap::RegisterParameter(TVar& rtVar, bool bLockable, bool bAutoDirty,
|
|
TConstruct... tConstruct)
|
|
{
|
|
auto ptrParam = std::make_shared<internal::CParamValue<TVar>>(rtVar, bLockable, bAutoDirty, tConstruct...);
|
|
m_vecParamMapRegistration.push_back(SParamRegistration(ptrParam));
|
|
return ptrParam;
|
|
}
|
|
|
|
inline void CSdvParamMap::RegisterMemberMap(const std::shared_ptr<internal::SMemberMapAccess>& rptrMember)
|
|
{
|
|
m_vecParamMapRegistration.push_back(SParamRegistration(rptrMember));
|
|
}
|
|
|
|
inline void CSdvParamMap::InitParamMap()
|
|
{
|
|
// Nothing to do here.
|
|
}
|
|
|
|
inline bool CSdvParamMap::BuildNecessary() const
|
|
{
|
|
return m_vecParamMapRegistration.empty();
|
|
}
|
|
|
|
template <typename TType>
|
|
constexpr bool CSdvParamInfo::TypeIsString()
|
|
{
|
|
using TType2 = std::remove_cv_t<TType>;
|
|
using TRoot = std::remove_cv_t<std::remove_pointer_t<std::remove_extent_t<TType2>>>;
|
|
constexpr bool bArray = std::is_array_v<TType2>;
|
|
constexpr bool bPointer = std::is_pointer_v<TType2>;
|
|
constexpr bool bCharacter = std::is_same_v<TRoot, char> || std::is_same_v<TRoot, char16_t> ||
|
|
std::is_same_v<TRoot, char32_t> || std::is_same_v<TRoot, wchar_t>;
|
|
constexpr bool bStdString = std::is_same_v<TType2, std:: string> || std::is_same_v<TType2, std::u16string> ||
|
|
std::is_same_v<TType2, std::u32string> || std::is_same_v<TType2, std::wstring>;
|
|
constexpr bool bSdvString = std::is_same_v<TType2, string> || std::is_same_v<TType2, u8string> ||
|
|
std::is_same_v<TType2, u16string> || std::is_same_v<TType2, u32string> || std::is_same_v<TType2, wstring>;
|
|
constexpr bool bStdPath = std::is_same_v<TType2, std::filesystem::path>;
|
|
return bStdString || bSdvString || (bArray && bCharacter) || (bPointer && bCharacter) || bStdPath;
|
|
}
|
|
|
|
template <typename TType>
|
|
constexpr bool CSdvParamInfo::TypeIsReadOnly()
|
|
{
|
|
using TType2 = std::remove_cv_t<TType>;
|
|
constexpr bool bArray = std::is_array_v<TType2>;
|
|
constexpr bool bPointer = std::is_pointer_v<TType2>;
|
|
return bArray || bPointer || std::is_const_v<TType>;
|
|
}
|
|
}; // namespace sdv
|
|
|
|
|
|
#endif // !defined PARAM_IMPL_INL
|