MotorControlModuleSDFM_TMS3.../Projects/EFC_Communication/UMLibrary/systemic/SettingValue.hh
2024-06-07 11:12:56 +03:00

236 lines
6.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 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_ */