/*!\file * \brief Файл содержит модуль хранения и распостранения ресурсов программы. */ /* * ResourceHolder.h * * Created on: 22 нояб. 2018 г. * Author: titov */ #ifndef SOURCE_SYSTEMIC_RESOURCEHOLDER_H_ #define SOURCE_SYSTEMIC_RESOURCEHOLDER_H_ #include #include #include #include #include #include #include #include "../memories/memories.hh" #include "../memories/pmr/StaticMemoryResource.hh" #include "../common/ResourceKeeper.hpp" #include "../systemic/ResourceRecord.hpp" namespace systemic { class ResourceHolder { public: typedef ResourceRecord::Id Id; typedef ResourceRecord::Tag Tag; template void share( Type & obj, Id id ); template void insert( ResourceKeeper * rk, Id id ); template ResourceKeeper * getShared( Id id ); struct NotificationInterface { virtual void notify( Id id, Tag tag, const std::type_info * type, void * rk ) = 0; virtual ~NotificationInterface() = default; }; static NotificationInterface & getDefault() { struct DefaultHerald : public NotificationInterface { void notify( Id id, Tag tag, const std::type_info * type, void * rk ) {} }; static DefaultHerald herald; return herald; } ResourceHolder( std::size_t max_size, std::pmr::memory_resource * record_allocator, std::pmr::memory_resource * record_guard_allocator = nullptr, NotificationInterface & herald = getDefault() ); virtual void * getRecord( const std::type_info & obj_type, Id id, Tag tag ); private: typedef std::map< ResourceRecord::Info, ResourceRecord::Data, std::less< ResourceRecord::Info >, std::pmr::polymorphic_allocator < std::pair< const ResourceRecord::Info, ResourceRecord::Data > > > ResourceRecordMap; const std::size_t size_limit; ResourceRecordMap records; NotificationInterface & herald; std::pmr::memory_resource * record_allocator; std::pmr::memory_resource * record_guard_allocator; }; template struct ResourceHolderBox { ResourceRecord records[num]; ResourceHolder manager; ResourceHolderBox( std::pmr::memory_resource* allocator ) : records(), manager(num, allocator) {} }; } /* namespace systemic */ template void systemic::ResourceHolder::share( Type & obj, Id id ) { //while( records.size() == size_limit ); const std::type_info & obj_type = typeid(Type); ResourceRecord::Info record_info(&obj_type, id, tag); ResourceRecordMap::iterator iter = records.find(record_info); if( records.end() != iter ) return; std::atomic_flag * record_guard = memories::instance_object(*record_guard_allocator); ResourceKeeper * record_keeper = memories::instance_object< ResourceKeeper< Type > >(*record_allocator, obj, *record_guard); void * record_data = reinterpret_cast< void * >(record_keeper); records[record_info] = record_data; herald.notify(id, tag, &obj_type, record_data); } template ResourceKeeper * systemic::ResourceHolder::getShared( Id id ) { const std::type_info & obj_type = typeid(Type); void * record_data = getRecord(obj_type, id, tag); return reinterpret_cast< ResourceKeeper * >(record_data); } template void systemic::ResourceHolder::insert( ResourceKeeper * record_keeper, Id id ) { //while( records.size() == size_limit ); const std::type_info & obj_type = typeid(Type); ResourceRecord::Info record_info(&obj_type, id, tag); ResourceRecordMap::iterator iter = records.find(record_info); if( records.end() != iter ) return; records[record_info] = reinterpret_cast< void * >(record_keeper); } #endif /* SOURCE_SYSTEMIC_RESOURCEHOLDER_HPP_ */