/* * CustomParameters.h * * Created on: 14 нояб. 2016 г. * Author: Gorbunov_DV */ #ifndef SOURCE_SYSTEM_CUSTOMPARAMETERS_H_ #define SOURCE_SYSTEM_CUSTOMPARAMETERS_H_ #include "IParameterProvider.hh" #include #include "SystemException.hh" namespace systemic { //!Модуль осущетсвляющий доступ к параметрам системы и динамическим строкам. class CustomParameters { private: IParameterProvider * * const providers; //!<Массив источников параметров. const std::size_t size; //!<Размер массива источников параметров. public: typedef unsigned short ProviderId; typedef unsigned int Id; //!Получить строку. /*!Возвращает строку в случае если она есть в заданном источнике параметров. * * \param[in] provider_id Источник параметров. * \param[in] parameter_id Идентификатор строки. * * \return Указатель и размер строки, в случае ошибки - (nullptr, 0). */ SharedData getString( ProviderId provider_id, Id parameter_id ) const; /*!Создать строку. * * \param[in] provider_id Источник параметров. * \param[in] parameter_id Идентификатор строки. * \param[in] size Размер строки. * * \return Указатель и размер строки, в случае ошибки - (nullptr, 0). */ SharedData createString( ProviderId provider_id, Id parameter_id, std::size_t size); //!Синхронизировать строку в ПЗУ. /*!Синхронизирует строку в случае если: * * указатель на строку не изменился. * * размер строки не изменился. * * данная строка существует в заданном источнике параметров. * * \param[in] provider_id Источник параметров. * \param[in] parameter_id Идентификатор строки. * \param[in] string Указатель и размер строки. * \return Строка будет синхронизированна, или ошибка доступа. */ bool flushString( ProviderId provider_id, Id parameter_id, std::pair string ); //!Добавить источник параметров с заданным идентификатором. bool addProvider( IParameterProvider * provider, ProviderId provider_id ); CustomParameters( IParameterProvider * * providers, std::size_t size ); }; template struct Parameter { SharedData data; operator bool() const; }; template struct LocalSetting { LocalSetting( Parameter & ); typename T::Setting & setting; std::lock_guard guard; }; //!Возвращает указатель на валидную структуру настроек, или nullptr. template Parameter getSetting( CustomParameters & cparams, CustomParameters::ProviderId provider_id, CustomParameters::Id id ); //!Получение строки данных по идентификатору. /*!Гарантирует что для всех вызовов с одинаковыми id, provider_id, cparams, мы получим одинаковые string. * */ bool getStringView( SharedData & string, const CustomParameters & cparams, CustomParameters::ProviderId provider_id, CustomParameters::Id id ); //!Создание строки данных по идентификатору. /*!Гарантирует что для всех вызовов с одинаковыми id, provider_id, cparams, мы создадим одинаковые string. * */ bool createStringView( SharedData & string, CustomParameters & cparams, CustomParameters::ProviderId provider_id, std::size_t size, CustomParameters::Id id ); template struct CustomParametersBox { IParameterProvider * records[size]; CustomParameters manager; CustomParametersBox() : records(), manager( records, size ) {} }; } // //struct InvalidSetting : public systemic::SystemException { // // struct Data { // systemic::CustomParameters::ProviderId provider_id; // systemic::CustomParameters::Id id; // } data; // // std::size_t id() const noexcept { return 97; } // std::pair binary() const noexcept { // return std::make_pair( reinterpret_cast(&data), sizeof(Data) ); // } // //}; template inline systemic::Parameter systemic::getSetting( CustomParameters & cparams, CustomParameters::ProviderId provider_id, CustomParameters::Id id ) { systemic::Parameter result; SharedData setting = cparams.getString( provider_id, id ); if( setting.get().first ) result.data = setting; return result; } template inline systemic::Parameter::operator bool() const { //todo: check alignof if( data.get().second == sizeof(typename T::Setting) ) return LocalSetting(const_cast &>(*this)).setting.isValid(); return false; } template inline systemic::LocalSetting::LocalSetting( Parameter & parameter ) : guard( parameter.data ), setting( *reinterpret_cast< typename T::Setting * >( parameter.data.get().first ) ) {} #endif /* SOURCE_SYSTEM_CUSTOMPARAMETERS_H_ */