/* * ValueManager.hpp * * Created on: 24 ����. 2018 �. * Author: titov */ #ifndef SOURCE_SYSTEMIC_VALUEMANAGER_HPP_ #define SOURCE_SYSTEMIC_VALUEMANAGER_HPP_ #include "IValue.hpp" #include "IValueOverride.hpp" #include "ValueImplementation.hpp" #include "../memories/memories.hh" namespace systemic { template< typename BaseType, class Interface = IValue, class InterfaceOverride = IValueOverride > class ValueManager { public: typedef unsigned short Id; typedef BaseType Type; typedef Interface InterfaceType; typedef InterfaceOverride InterfaceOverrideType; class Record { friend class ValueManager; Interface * obj; InterfaceOverride * override; volatile const BaseType * value; Id id; Record( Id id, Interface * obj, InterfaceOverride * override, volatile const BaseType * value ) : obj(obj), override(override), id(id), value(value) {} public: Record() : obj(nullptr), override(nullptr), value(nullptr), id(0) {} bool exist() const { return id; } }; struct NotificationInterface { virtual void notify( Id id, Interface * interface, InterfaceOverride * override, volatile const BaseType * value ) = 0; virtual ~NotificationInterface() = default; }; static NotificationInterface & getDefault() { struct DefaultHerald : public NotificationInterface { void notify( Id id, Interface * interface, InterfaceOverride * override, volatile const BaseType * value ) {} }; static DefaultHerald herald; return herald; } private: const std::size_t size; Record * const records; std::pmr::memory_resource* allocator; NotificationInterface & herald; bool place_in_parnas( Id id, const volatile BaseType * value, Interface * interface, InterfaceOverride * override ); protected: virtual Record & search( Id id ) const; public: ValueManager( Record * recods, std::size_t size, std::pmr::memory_resource* allocator, NotificationInterface & herald = getDefault() ); template< class Implemetation = ValueImplementation > Interface * create( Id id, const volatile BaseType & value, std::pmr::memory_resource* = nullptr ); Interface * get( Id id ) const; virtual bool add( Id id, Interface * interface, InterfaceOverride * override = nullptr, volatile const BaseType * value = nullptr ); InterfaceOverride * getOverride( Id id ); volatile const BaseType * getValue( Id id ) const; //todo: Ñïðÿòàòü. bool insert( Id id, Interface * interface, InterfaceOverride * override, volatile const BaseType * value ); }; template, class InterfaceOverride = IValueOverride > struct ValueManagerBox { typename ValueManager::Record records[num]; ValueManager manager; ValueManagerBox( void * (*allocator)( std::size_t size, std::size_t aligment ) ) : records(), manager( records, num, allocator ) {} }; } template inline systemic::ValueManager::ValueManager( Record * records, std::size_t size, std::pmr::memory_resource* allocator, NotificationInterface & herald ) : records(records), size(size), allocator(allocator), herald(herald) {} template template inline Interface * systemic::ValueManager::create( Id id, const volatile BaseType & value, std::pmr::memory_resource* allocator_local ) { typedef Implemetation Imp; Interface * interface( nullptr ); if( not get( id ) ) { Imp * impl = memories::instance_object( *(allocator_local ? allocator_local : allocator), value ); interface = impl->getValue(); if( not add( id, interface, impl->getValueOverride(), impl->getBase() ) ) { interface = nullptr; } } return interface; } template inline Interface * systemic::ValueManager::get( Id id ) const { return search(id).obj; } template bool systemic::ValueManager::place_in_parnas( Id id, const volatile BaseType * value, Interface * interface, InterfaceOverride * override) { bool result = false; for( int i = 0; i < size && !result; i++ ) if( !records[i].obj or records[i].id == id ) { records[i] = Record(id, interface, override, value); result = true; } return result; } template inline bool systemic::ValueManager::add( Id id, Interface * interface, InterfaceOverride * override, const volatile BaseType * value ) { bool result = false; if( id < size ) { Record old = records[id]; records[id] = Record( id, interface, override, value ); if( old.obj ) result = place_in_parnas(old.id, old.value, old.obj, old.override); else result = true; } else result = place_in_parnas(id, value, interface, override); if( result ) herald.notify(id, interface, override, value); return result; } template inline InterfaceOverride * systemic::ValueManager::getOverride( Id id ) { return search(id).override; } template inline typename systemic::ValueManager::Record & systemic::ValueManager::search( Id id ) const { static systemic::ValueManager::Record null_object; if( id < size ) return records[id].id == id ? records[id] : null_object; else for( int i = 0; i < size; i++ ) if( records[i].id == id ) return records[i]; return null_object; } template inline volatile const BaseType * systemic::ValueManager::getValue( Id id ) const { return search(id).value; } template inline bool systemic::ValueManager::insert( Id id, Interface * interface, InterfaceOverride * override, const volatile BaseType * value) { bool result = false; if( id < size ) { Record old = records[id]; records[id] = Record( id, interface, override, value ); if( old.obj ) result = place_in_parnas(old.id, old.value, old.obj, old.override); else result = true; } else result = place_in_parnas(id, value, interface, override); return result; } #endif /* SOURCE_SYSTEMIC_VALUEMANAGER_HPP_ */