MotorControlModuleSDFM_TMS3.../Projects/EFC_Application/UMLibrary/systemic/ResourceHolder.hpp

147 lines
4.1 KiB
C++

/*!\file
* \brief Ôàéë ñîäåðæèò ìîäóëü õðàíåíèÿ è ðàñïîñòðàíåíèÿ ðåñóðñîâ ïðîãðàììû.
*/
/*
* ResourceHolder.h
*
* Created on: 22 íîÿá. 2018 ã.
* Author: titov
*/
#ifndef SOURCE_SYSTEMIC_RESOURCEHOLDER_H_
#define SOURCE_SYSTEMIC_RESOURCEHOLDER_H_
#include <stdint.h>
#include <cstddef>
#include <typeinfo>
#include <new>
#include <memory_resource>
#include <unordered_map>
#include <map>
#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<typename Type, Tag = 0>
void share( Type & obj, Id id );
template<typename Type, Tag = 0>
void insert( ResourceKeeper<Type> * rk, Id id );
template<typename Type, Tag = 0>
ResourceKeeper<Type> * 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<std::size_t num>
struct ResourceHolderBox {
ResourceRecord records[num];
ResourceHolder manager;
ResourceHolderBox( std::pmr::memory_resource* allocator )
: records(),
manager(num, allocator) {}
};
} /* namespace systemic */
template<typename Type, systemic::ResourceHolder::Tag tag>
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<std::atomic_flag>(*record_guard_allocator);
ResourceKeeper<Type> * 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<typename Type, systemic::ResourceHolder::Tag tag>
ResourceKeeper<Type> * 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<Type> * >(record_data);
}
template<typename Type, systemic::ResourceHolder::Tag tag>
void systemic::ResourceHolder::insert( ResourceKeeper<Type> * 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_ */