# GpgFrontend Project: src/core/GpgFunctionObject.h Source File

GpgFunctionObject.h
#ifndef GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
#define GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
#include <map>
#include <memory>
#include <mutex>
#include <shared_mutex>
#include <stdexcept>
#include <string>
#include "GpgConstants.h"
namespace GpgFrontend {
template <typename T>
class SingletonFunctionObject {
public:
static T& GetInstance(
int channel = GpgFrontend::GPGFRONTEND_DEFAULT_CHANNEL) {
static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
"T not derived from SingletonFunctionObject<T>");
auto _p_pbj = find_object_in_channel(channel);
if (_p_pbj == nullptr)
return *set_object_in_channel(channel, std::make_unique<T>(channel));
else
return *_p_pbj;
}
static T& CreateInstance(int channel,
std::function<std::unique_ptr<T>(void)> factory) {
static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
"T not derived from SingletonFunctionObject<T>");
auto _p_pbj = find_object_in_channel(channel);
if (_p_pbj == nullptr)
return *set_object_in_channel(channel, std::move(factory()));
else
return *_p_pbj;
}
static T& CreateInstance(int channel, std::unique_ptr<T> p_obj = nullptr) {
static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
"T not derived from SingletonFunctionObject<T>");
auto _p_pbj = find_object_in_channel(channel);
if (_p_pbj == nullptr)
return *set_object_in_channel(channel, std::move(p_obj));
else
return *_p_pbj;
}
static T& ReleaseChannel(int channel) {
decltype(_instances_map.end()) _it;
{
std::shared_lock lock(_instances_mutex);
_it = _instances_map.find(channel);
}
if (_it != _instances_map.end()) _instances_map.erase(_it);
DLOG(INFO) << "channel" << channel << "released";
}
static int GetDefaultChannel() { return _default_channel; }
[[nodiscard]] int GetChannel() const { return channel_; }
SingletonFunctionObject(T&&) = delete;
SingletonFunctionObject(const T&) = delete;
void operator=(const T&) = delete;
protected:
SingletonFunctionObject() = default;
explicit SingletonFunctionObject(int channel) : channel_(channel) {}
virtual ~SingletonFunctionObject() = default;
void SetChannel(int channel) { this->channel_ = channel; }
private:
int channel_ = _default_channel;
static int _default_channel;
static std::mutex _instance_mutex;
static std::shared_mutex _instances_mutex;
static std::unique_ptr<T> _instance;
static std::map<int, std::unique_ptr<T>> _instances_map;
static T* find_object_in_channel(int channel) {
// read _instances_map
decltype(_instances_map.end()) _it;
{
std::shared_lock lock(_instances_mutex);
_it = _instances_map.find(channel);
if (_it == _instances_map.end())
return nullptr;
else
return _it->second.get();
}
}
static T* set_object_in_channel(int channel, std::unique_ptr<T> p_obj) {
{
if (p_obj == nullptr) p_obj = std::make_unique<T>();
T* obj = p_obj.get();
obj->SetChannel(channel);
{
std::unique_lock lock(_instances_mutex);
_instances_map.insert({channel, std::move(p_obj)});
}
return obj;
}
}
};
template <typename T>
int SingletonFunctionObject<T>::_default_channel =
GpgFrontend::GPGFRONTEND_DEFAULT_CHANNEL;
template <typename T>
std::mutex SingletonFunctionObject<T>::_instance_mutex;
template <typename T>
std::shared_mutex SingletonFunctionObject<T>::_instances_mutex;
template <typename T>
std::unique_ptr<T> SingletonFunctionObject<T>::_instance = nullptr;
template <typename T>
std::map<int, std::unique_ptr<T>> SingletonFunctionObject<T>::_instances_map;
} // namespace GpgFrontend
#endif // GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
GpgFrontend::SingletonFunctionObject::ReleaseChannel
static T & ReleaseChannel(int channel)
Definition: GpgFunctionObject.h:112
GpgFrontend::SingletonFunctionObject
Definition: GpgFunctionObject.h:49
GpgFrontend::SingletonFunctionObject::SetChannel
void SetChannel(int channel)
Set the Channel object.
Definition: GpgFunctionObject.h:179
GpgFrontend
Definition: CoreCommonUtil.cpp:29
GpgFrontend::SingletonFunctionObject::GetInstance
static T & GetInstance(int channel=GpgFrontend::GPGFRONTEND_DEFAULT_CHANNEL)
Get the Instance object.
Definition: GpgFunctionObject.h:57
GpgFrontend::SingletonFunctionObject::SingletonFunctionObject
SingletonFunctionObject(int channel)
Construct a new Singleton Function Object object.
Definition: GpgFunctionObject.h:166
GpgFrontend::SingletonFunctionObject::GetChannel
int GetChannel() const
Get the Channel object.
Definition: GpgFunctionObject.h:134
GpgFrontend::SingletonFunctionObject::~SingletonFunctionObject
virtual ~SingletonFunctionObject()=default
Destroy the Singleton Function Object object.
GpgFrontend::SingletonFunctionObject::CreateInstance
static T & CreateInstance(int channel, std::unique_ptr< T > p_obj=nullptr)
Create a Instance object.
Definition: GpgFunctionObject.h:95
GpgFrontend::SingletonFunctionObject::set_object_in_channel
static T * set_object_in_channel(int channel, std::unique_ptr< T > p_obj)
Set the object in channel object.
Definition: GpgFunctionObject.h:215
GpgFrontend::SingletonFunctionObject::SingletonFunctionObject
SingletonFunctionObject()=default
Construct a new Singleton Function Object object.
GpgFrontend::SingletonFunctionObject::GetDefaultChannel
static int GetDefaultChannel()
Get the Default Channel object.
Definition: GpgFunctionObject.h:127
GpgFrontend::SingletonFunctionObject::find_object_in_channel
static T * find_object_in_channel(int channel)
Definition: GpgFunctionObject.h:195
GpgFrontend::SingletonFunctionObject::CreateInstance
static T & CreateInstance(int channel, std::function< std::unique_ptr< T >(void)> factory)
Create a Instance object.
Definition: GpgFunctionObject.h:76