147 lines
4.1 KiB
C++
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_ */
|