nim_duilib/tool_kits/shared/templated_object_factory.h

115 lines
4.0 KiB
C
Raw Normal View History

2019-04-19 17:19:57 +08:00
#pragma once
namespace shared
{
class TemplatedObjectFactoryWrapper;
/*
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>TemplatedObjectFactory
<EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>TOBJFLG<EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>TBaseӦ<EFBFBD><EFBFBD>TOBJFLG<EFBFBD>ĸ<EFBFBD><EFBFBD><EFBFBD>
*/
template<typename TBase, typename TOBJFLG>
class TemplatedObjectFactory : public nbase::Singleton<TemplatedObjectFactory<typename TBase, typename TOBJFLG>>
{
private:
using _ParentType = nbase::Singleton<TemplatedObjectFactory<typename TBase, typename TOBJFLG>>;
using _MyType = TemplatedObjectFactory<typename TBase, typename TOBJFLG>;
friend class TemplatedObjectFactoryWrapper;
public:
TemplatedObjectFactory() = default;
~TemplatedObjectFactory() = default;
private:
/*
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>TClassʵ<EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>TClass : public TBase<EFBFBD>Ĺ<EFBFBD>ϵ
params TClass<EFBFBD>Ĺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>TBase<EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
template<typename TClass, typename... TParam>
TBase* Create(const TParam&... params)
{
return dynamic_cast<TBase*>(new TClass(params...));
}
template<typename TClass, typename... TParam>
void AddCreateFunction(TOBJFLG flg, const TParam&... params)
{
auto it = std::find_if(crate_function_list_.begin(), crate_function_list_.end(), [&](const decltype(*crate_function_list_.begin()) & item){
return flg == item.first;
});
if (it == crate_function_list_.end())
crate_function_list_.emplace_back(std::make_pair(flg, std::bind(&TemplatedObjectFactory::Create<TClass, TParam...>, this, params...)));
}
auto CreateSharedObject(TOBJFLG flg)->std::shared_ptr<TBase>
{
auto it = std::find_if(crate_function_list_.begin(), crate_function_list_.end(), [&](const decltype(*crate_function_list_.begin()) & item){
return flg == item.first;
});
if (it != crate_function_list_.end())
return std::shared_ptr<TBase>((*it).second());
return nullptr;
}
TBase* CreateObject(TOBJFLG flg)
{
TBase* ret = nullptr;
auto it = std::find_if(crate_function_list_.begin(), crate_function_list_.end(), [&](const decltype(*crate_function_list_.begin()) & item){
return flg == item.first;
});
if (it != crate_function_list_.end())
ret = (*it).second();
return ret;
}
void CreateAllSharedObject(std::list<std::shared_ptr<TBase>>& objects)
{
for (auto it : crate_function_list_)
objects.emplace_back(std::shared_ptr<TBase>(it.second()));
}
private:
std::list<std::pair<TOBJFLG, std::function<TBase*()>>> crate_function_list_;
};
class TemplatedObjectFactoryWrapper
{
public:
//ע<><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
template<typename TBase, typename TObject, typename TOBJFLG, typename... TParam>
static void RegisteredOjbect(const TOBJFLG& flg, const TParam&... params)
{
using TDecayType = typename std::decay<TOBJFLG>::type;
if (std::is_base_of<TBase, TObject>::value)
{
auto&& manager = TemplatedObjectFactory<TBase, TDecayType>::GetInstance();
if (manager != nullptr)
manager->AddCreateFunction<TObject>(flg, params...);
}
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ü<EFBFBD><C3BC><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>
template<typename TBase, typename TFLG>
static auto InstantiateSharedRegisteredOjbect(const TFLG& flag)->std::shared_ptr<TBase>
{
using TDecayType = typename std::decay<TFLG>::type;
auto&& manager = TemplatedObjectFactory<TBase, TDecayType>::GetInstance();
if (manager != nullptr)
return manager->CreateSharedObject(flag);
return nullptr;
}
//<2F><><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>
template<typename TBase, typename TFLG>
static auto InstantiateRegisteredOjbect(const TFLG& flag)->TBase*
{
using TDecayType = typename std::decay<TFLG>::type;
auto&& manager = TemplatedObjectFactory<TBase, TDecayType>::GetInstance();
if (manager != nullptr)
return manager->CreateObject(flag);
return nullptr;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><D7A2>Ϊ TBase <20><> TFLG Ϊ<><CEAA>ʶ<EFBFBD>ĵ<EFBFBD>ʵ<EFBFBD><CAB5>
template<typename TBase, typename TFLG>
static auto InstantiateAllRegisteredSharedOjbect()->std::list<std::shared_ptr<TBase>>
{
using TDecayType = typename std::decay<TFLG>::type;
std::list<std::shared_ptr<TBase>> ret;
auto&& manager = TemplatedObjectFactory<TBase, TDecayType>::GetInstance();
if (manager != nullptr)
manager->CreateAllSharedObject(ret);
return ret;
}
};
}