MotorControlModuleSDFM_TMS3.../Projects/EFC_Application/UMLibrary/systemic/SettingValue.hh

236 lines
6.4 KiB
C++

/*
* SettingValue.h
*
* Created on: 15 èþí. 2020 ã.
* Author: user
*/
#ifndef UMLIBRARY_SYSTEMIC_SETTINGVALUE_HH_
#define UMLIBRARY_SYSTEMIC_SETTINGVALUE_H_
#include "IValueAsync.hpp"
#include "SharedData.hh"
#include <cstring>
#include <mutex>
#include <shared_mutex>
#include "SystemException.hh"
namespace systemic {
//! Êëàññ ðåàëèçóåò èíòåðôåéñ äîñòóïà ê ïîëþ íàñòðîéêè.
template<typename ValueType>
class SettingValue : public IValueType<ValueType> {
private:
mutable systemic::SharedData data;
const std::size_t offset;
const ValueType min;
const ValueType max;
public:
struct Constraints {
ValueType min;
ValueType max;
};
void set( ValueType value );
ValueType get() const;
SettingValue( systemic::SharedData data, const Constraints & constraints, size_t offset );
};
//! Êëàññ ðåàëèçóåò èíòåðôåéñ êåøèðóåìîãî äîñòóïà ê ïîëþ íàñòðîéêè.
template<typename ValueType>
class SettingCachedValue : public SettingValue<ValueType> {
ValueType cached;
public:
void set( ValueType value );
ValueType get() const;
void update();
SettingCachedValue( systemic::SharedData data, const typename SettingValue<ValueType>::Constraints & constraints, size_t offset );
};
//! Øàáëîííàÿ âåðñèÿ êëàññà äëÿ äîñòóïà ê ïîëþ íàñòðîéêè.
template<typename SettingType, typename ValueType, ValueType (SettingType::*member_p)>
struct ConcreteSettingValue : public IValueType<ValueType> {
private:
mutable systemic::SharedData data;
char * const base_pointer;
ValueType & getValue() { return ( reinterpret_cast<SettingType*>(base_pointer) )->*member_p; }
ValueType & getValue() const { return ( reinterpret_cast<SettingType*>(base_pointer) )->*member_p; }
const ValueType min;
const ValueType max;
public:
struct Constraints {
ValueType min;
ValueType max;
};
void set( ValueType value );
ValueType get() const;
ConcreteSettingValue( systemic::SharedData data, const Constraints & constraints );
};
struct SetValueError : public SystemException {
SetValueError( float mx, float mn, float value ) : mx(mx), mn(mn), value(value) {}
std::size_t id() const noexcept { return 54; }
std::pair<const char *, std::size_t> binary() const noexcept { return {reinterpret_cast<const char *>( this ), sizeof(*this)}; }
const char * what() const noexcept { return "Set Value Error"; }
float mx;
float mn;
float value;
};
struct IncorrectData : public SystemException {
IncorrectData( std::size_t data_size, std::size_t offset, std::size_t type_size ) : data_size(data_size), offset(offset), type_size(type_size) {}
std::size_t id() const noexcept { return 56; }
std::pair<const char *, std::size_t> binary() const noexcept { return { reinterpret_cast<const char *>( this ), sizeof(*this) }; }
const char * what() const noexcept { return "Incorrect data size"; }
std::size_t data_size;
std::size_t offset;
std::size_t type_size;
};
struct IncorrectType : public SystemException {
IncorrectType( std::size_t data_size, std::size_t setting_size ) : data_size(data_size), setting_size(setting_size) {}
std::size_t id() const noexcept { return 55; }
std::pair<const char *, std::size_t> binary() const noexcept { return { reinterpret_cast<const char *>( this ), sizeof(*this) }; }
const char * what() const noexcept { return "Incorrect setting type"; }
std::size_t data_size;
std::size_t setting_size;
};
} /* namespace systemic */
template<typename ValueType>
inline void systemic::SettingValue<ValueType>::set( ValueType value ) {
std::lock_guard<systemic::SharedData> lock(data);
if( value <= max and value >= min ) {
std::memcpy( data.get().first + offset, reinterpret_cast<char *>( &value ), sizeof(ValueType) );
} else
throw SetValueError( max, min, value ) ;
}
template<typename ValueType>
inline ValueType systemic::SettingValue<ValueType>::get() const {
std::shared_lock<systemic::SharedData> lock(data);
ValueType value;
std::memcpy( reinterpret_cast<char *>( &value ), data.get().first + offset, sizeof(ValueType) );
return value;
}
template<typename ValueType>
inline systemic::SettingValue<ValueType>::SettingValue(
systemic::SharedData data, const Constraints & constraints,
std::size_t offset )
: data(data), offset(offset),
min(constraints.min), max(constraints.max) {
if( offset + sizeof(ValueType) > data.get().second )
throw IncorrectData( data.get().second, offset, sizeof(ValueType) );
}
template<typename SettingType, typename ValueType,
ValueType (SettingType::*member_p)>
inline void systemic::ConcreteSettingValue<SettingType, ValueType, member_p>::set(
ValueType value ) {
std::lock_guard<systemic::SharedData> lock(data);
if( value <= max and value >= min ) {
getValue() = value;
} else
throw SetValueError( max, min, value ) ;
}
template<typename SettingType, typename ValueType,
ValueType (SettingType::*member_p)>
inline ValueType systemic::ConcreteSettingValue<SettingType, ValueType, member_p>::get() const {
std::shared_lock<systemic::SharedData> lock(data);
return getValue();
}
template<typename SettingType, typename ValueType,
ValueType (SettingType::*member_p)>
inline systemic::ConcreteSettingValue<SettingType, ValueType, member_p>::ConcreteSettingValue(
systemic::SharedData data, const Constraints & constraints ) :
data(data), base_pointer( data.get().first ),
min(constraints.min), max(constraints.max) {
if( sizeof(SettingType) != data.get().second )
throw IncorrectType( data.get().second, sizeof(SettingType) );
}
template<typename ValueType>
inline void systemic::SettingCachedValue<ValueType>::set( ValueType value ) {
cached = value;
SettingValue<ValueType>::set(cached);
}
template<typename ValueType>
inline ValueType systemic::SettingCachedValue<ValueType>::get() const {
return cached;
}
template<typename ValueType>
inline void systemic::SettingCachedValue<ValueType>::update() {
cached = SettingValue<ValueType>::get();
}
template<typename ValueType>
inline systemic::SettingCachedValue<ValueType>::SettingCachedValue(
systemic::SharedData data, const typename SettingValue<ValueType>::Constraints &constraints,
size_t offset) : SettingValue<ValueType>(data, constraints, offset) {}
#endif /* UMLIBRARY_SYSTEMIC_SETTINGVALUE_HH_ */