MotorControlModuleSDFM_TMS3.../Projects/EFC_Communication/UMLibrary/systemic/ResourceHolder.hpp
2024-06-07 11:12:56 +03:00

147 lines
4.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*!\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_ */