236 lines
6.4 KiB
C++
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_ */
|