好幾天沒寫博客了
接著以前寫的Loki系列來
首先Loki Factory設(shè)計的目的就是讓對象功能按名生成!
該文主要涉及Loki/Factory.h文件
首先上工廠異常類
如下:
/**
* \defgroup FactoryErrorPoliciesGroup Factory Error Policies
* \ingroup FactoryGroup
* \brief Manages the "Unknown Type" error in an object factory
*
* \class DefaultFactoryError
* \ingroup FactoryErrorPoliciesGroup
* \brief Default policy that throws an exception
*
*/
template <typename IdentifierType, class AbstractProduct>
struct DefaultFactoryError
{
struct Exception : public std::exception
{
const char* what() const throw() { return "Unknown Type"; }
};
static AbstractProduct* OnUnknownType(IdentifierType)
{
throw Exception();
}
};
這里使用了一個模板來處理當出現(xiàn)不可定名的對象標示時的處理方法
其中Identifier是對象的標示(比如id,字符串等等)
AbstrctProduct就是工廠產(chǎn)品的基類
不過感覺如果出現(xiàn)非存在的對象標示時應(yīng)該返回空的對象指針為不是出現(xiàn)異常
所以我加入了下面模板
////////////////////////////////////////////////////////
/// 定義蓋莫引擎工廠產(chǎn)品制作出錯處理(出錯則返回NULL!)
////////////////////////////////////////////////////////////
template <typename IdentifierType, class AbstractProduct>
struct EngineFactoryError
{
struct Exception : public std::exception
{
const char* what() const throw()
{
return "Not Found";
}
};
static AbstractProduct* OnUnknownType(IdentifierType)
{
return NULL;
}
};
當然這里沒有誰對誰錯的問題
而
struct FactoryImplBase
{
typedef EmptyType Parm1;
typedef EmptyType Parm2;
typedef EmptyType Parm3;
typedef EmptyType Parm4;
typedef EmptyType Parm5;
typedef EmptyType Parm6;
typedef EmptyType Parm7;
typedef EmptyType Parm8;
typedef EmptyType Parm9;
typedef EmptyType Parm10;
typedef EmptyType Parm11;
typedef EmptyType Parm12;
typedef EmptyType Parm13;
typedef EmptyType Parm14;
typedef EmptyType Parm15;
};
是一個作為工廠基類的數(shù)據(jù)結(jié)構(gòu)
最大可以持有15個模板參數(shù)(太多了吧)
template <typename AP, typename Id, typename TList >
struct FactoryImpl;
這個前向聲明表明了
FactoryImpl具有3個模板參數(shù) 一個工廠產(chǎn)品指針 一個對象標識 一個對象所在鏈表
而
template<typename AP, typename Id>
struct FactoryImpl<AP, Id, NullType>
: public FactoryImplBase
{
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id & id ) = 0;
};
則是對象鏈表為空的特化形式
通過調(diào)用CreateObject來獲取對象指針
接下來的
template <typename AP, typename Id, typename P1 >
struct FactoryImpl<AP,Id, Seq<P1> >
: public FactoryImplBase
{
typedef typename TypeTraits<P1>::ParameterType Parm1;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1 ) = 0;
};
一直到 P15大致都是一樣的
簡單的說Pi說明了名字鏈表的上限
接下來就是Loki的Factory
////////////////////////////////////////////////////////////////////////////////
/// \class Factory
///
/// \ingroup FactoryGroup
/// Implements a generic object factory.
///
/// Create functions can have up to 15 parameters.
///
/// \par Singleton lifetime when used with Loki::SingletonHolder
/// Because Factory uses internally Functors which inherits from
/// SmallObject you must use the singleton lifetime
/// \code Loki::LongevityLifetime::DieAsSmallObjectChild \endcode
/// Alternatively you could suppress for Functor the inheritance
/// from SmallObject by defining the macro:
/// \code LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT \endcode
////////////////////////////////////////////////////////////////////////////////
從注釋可以看出 她最多支持15個對象鏈表
再是模板頭
template
<
class AbstractProduct,
typename IdentifierType,
typename CreatorParmTList = NullType,
template<typename, class> class FactoryErrorPolicy = EngineFactoryError//DefaultFactoryError
>
在這里我做了修改并沒有使用其默認的異常處理
而是采用當出現(xiàn)非法標識時返回空的對象指針的策略
class Factory : public FactoryErrorPolicy<IdentifierType, AbstractProduct>
{
typedef FactoryImpl< AbstractProduct, IdentifierType, CreatorParmTList > Impl;
typedef typename Impl::Parm1 Parm1;
typedef typename Impl::Parm2 Parm2;
typedef typename Impl::Parm3 Parm3;
typedef typename Impl::Parm4 Parm4;
typedef typename Impl::Parm5 Parm5;
typedef typename Impl::Parm6 Parm6;
typedef typename Impl::Parm7 Parm7;
typedef typename Impl::Parm8 Parm8;
typedef typename Impl::Parm9 Parm9;
typedef typename Impl::Parm10 Parm10;
typedef typename Impl::Parm11 Parm11;
typedef typename Impl::Parm12 Parm12;
typedef typename Impl::Parm13 Parm13;
typedef typename Impl::Parm14 Parm14;
typedef typename Impl::Parm15 Parm15;
typedef Functor<AbstractProduct*, CreatorParmTList> ProductCreator;
typedef AssocVector<IdentifierType, ProductCreator> IdToProductMap;
IdToProductMap associations_;
在這里庫作者使用了AssocVector容器 具體代碼在對等頭文件里面
構(gòu)造和析構(gòu)沒什么說的了
Factory()
: associations_()
{
}
~Factory()
{
associations_.erase(associations_.begin(), associations_.end());
}
析構(gòu)無非是對對象的清空動作
下面是對象的注冊和反注冊動作
bool Register(const IdentifierType& id, ProductCreator creator)
{
return associations_.insert(
typename IdToProductMap::value_type(id, creator)).second != 0;
}
template <class PtrObj, typename CreaFn>
bool Register(const IdentifierType& id, const PtrObj& p, CreaFn fn)
{
ProductCreator creator( p, fn );
return associations_.insert(
typename IdToProductMap::value_type(id, creator)).second != 0;
}
bool Unregister(const IdentifierType& id)
{
return associations_.erase(id) != 0;
}
可以看出 如果需要注冊一個新的對象標識
只需要把對象標示和其對于的Creator加入鏈表即可
下面的這個函數(shù)就是獲取對象標識鏈表
std::vector<IdentifierType> RegisteredIds()
{
std::vector<IdentifierType> ids;
for(typename IdToProductMap::iterator it = associations_.begin();
it != associations_.end(); ++it)
{
ids.push_back(it->first);
}
return ids;
}
之后的16個函數(shù)
AbstractProduct* CreateObject(const IdentifierType& id)
{
typename IdToProductMap::iterator i = associations_.find(id);
if (i != associations_.end())
return (i->second)( );
return this->OnUnknownType(id);
}
...
是對象的生成動作
可以看出
如果在鏈表中沒有發(fā)現(xiàn)給定標識則模板異常策略發(fā)生作用
代碼最后是復制工廠
/**
* \defgroup CloneFactoryGroup Clone Factory
* \ingroup FactoriesGroup
* \brief Creates a copy from a polymorphic object.
*
* \class CloneFactory
* \ingroup CloneFactoryGroup
* \brief Creates a copy from a polymorphic object.
*/
template
<
class AbstractProduct,
class ProductCreator =
AbstractProduct* (*)(const AbstractProduct*),
template<typename, class>
class FactoryErrorPolicy = DefaultFactoryError
>
class CloneFactory
: public FactoryErrorPolicy<TypeInfo, AbstractProduct>
{
public:
bool Register(const TypeInfo& ti, ProductCreator creator)
{
return associations_.insert(
typename IdToProductMap::value_type(ti, creator)).second != 0;
}
bool Unregister(const TypeInfo& id)
{
return associations_.erase(id) != 0;
}
AbstractProduct* CreateObject(const AbstractProduct* model)
{
if (model == NULL)
{
return NULL;
}
typename IdToProductMap::iterator i =
associations_.find(typeid(*model));
if (i != associations_.end())
{
return (i->second)(model);
}
return this->OnUnknownType(typeid(*model));
}
private:
typedef AssocVector<TypeInfo, ProductCreator> IdToProductMap;
IdToProductMap associations_;
};
其復制過程為
首先檢測復制源是否為空為空則返回空指針
然后根據(jù)對象名字獲取她在標識-產(chǎn)品鏈表中的迭代器位置
如果存在則返回復制
否則根據(jù)處置的異常處理策略處理它!
Loki Factory看完了 不過感覺有點華而不實
本來蓋莫游戲引擎期望采用這個現(xiàn)在看來需要另外寫了
下面是一大堆亂代碼O(∩_∩)O~


/**/////////////////////////////////////////////////////////////
/// 重定義引擎對象鏈表數(shù)據(jù)類型
////////////////////////////////////////////////////////////
typedef Loki::Seq
<
//! 在這里添加新的類型
#include <GEngine/Template/RegisterObject.inl>
>::Type ObjectList;

namespace Loki


{


/**/////////////////////////////////////////////////////////
/// 定義蓋莫引擎工廠產(chǎn)品制作出錯處理(出錯則返回NULL!)
////////////////////////////////////////////////////////////

/**//*template <typename IdentifierType, class AbstractProduct>
struct EngineFactoryError
{
struct Exception : public std::exception
{
const char* what() const throw()
{
return "Not Found";
}
};

static AbstractProduct* OnUnknownType(IdentifierType)
{
return NULL;
}
};*/

}

namespace core


{


/**/////////////////////////////////////////////////////////////
/// 重定義蓋莫游戲引擎對象工廠類型
////////////////////////////////////////////////////////////
typedef Loki::SingletonHolder
<
Loki::Factory<Object,engine_string>
> ObjectFactory;

static inline bool RegisterObject(engine_string key,RefPtr<Object>(*Creator)())


{
return ObjectFactory::Instance().Register(key,Creator);
}


/**/////////////////////////////////////////////////////////////
/// 定義蓋莫游戲引擎工廠基類(Interface必須是RefCount的子類)
////////////////////////////////////////////////////////////
template<typename Interface>
class Factory


{
virtual RefPtr<Interface> Create() = 0;
};

/**/////////////////////////////////////////////////////////////
/// 獲取一個新的工廠產(chǎn)品
////////////////////////////////////////////////////////////
template<class Product,class AbstractProduct>
RefPtr<AbstractProduct> CreateNewObject()


{
return new Product;
}


/**/////////////////////////////////////////////////////////////
/// 獲取一個新的工廠產(chǎn)品(模板特化)
////////////////////////////////////////////////////////////
template<class Product>
RefPtr<Product> CreateNewObject()


{
return new Product();
}


/**/////////////////////////////////////////////////////////////
/// 獲取一個新的工廠產(chǎn)品
////////////////////////////////////////////////////////////
template<class Product,class AbstractProduct,class P1>
RefPtr<AbstractProduct> CreateNewObject(P1 p1)


{
return new Product(p1);
}


/**/////////////////////////////////////////////////////////////
/// 獲取一個新的工廠產(chǎn)品(模板特化)
////////////////////////////////////////////////////////////
template<class Product,class P1>
RefPtr<Product> CreateNewObject(P1 p1)


{
return new Product(p1);
}


/**/////////////////////////////////////////////////////////////
/// 獲取一個新的工廠產(chǎn)品
////////////////////////////////////////////////////////////
template<class Product,class AbstractProduct,class P1,class P2>
RefPtr<AbstractProduct> CreateNewObject(P1 p1,P2 p2)


{
return new Product(p1,p2);
}


/**/////////////////////////////////////////////////////////////
/// 獲取一個新的工廠產(chǎn)品(模板特化)
////////////////////////////////////////////////////////////
template<class Product,class P1,class P2>
RefPtr<Product> CreateNewObject(P1 p1,P2 p2)


{
return new Product(p1,p2);
}


/**/////////////////////////////////////////////////////////////
/// 獲取一個新的工廠產(chǎn)品
////////////////////////////////////////////////////////////
template<class Product,class AbstractProduct,class P1,class P2,class P3>
RefPtr<AbstractProduct> CreateNewObject(P1 p1,P2 p2,P3 p3)


{
return new Product(p1,p2,p3);
}


/**/////////////////////////////////////////////////////////////
/// 獲取一個新的工廠產(chǎn)品(模板特化)
////////////////////////////////////////////////////////////
template<class Product,class P1,class P2,class P3>
RefPtr<Product> CreateNewObject(P1 p1,P2 p2,P3 p3)


{
return new Product(p1,p2,p3);
}

}

#define REGISTER_FUNCTION(Object)\
namespace Loki\


{\
template<> \
bool RegisterFunction<Object>()\

{\
return RegisterObject(#Object,&core::CreateNewObject<Object>);\
}\
}

/**//*#define REGISTER_FUNCTION1(Object)\
template<> \
bool RegisterFunction<Object>()\
{\
return RegisterObject(#Object,&core::CreateNewObject<Object>);\
}

#define REGISTER_FUNCTION2(Object)\
template<> \
bool RegisterFunction<Object>()\
{\
return RegisterObject(#Object,&core::CreateNewObject<Object>);\
}

#define REGISTER_FUNCTION3(Object)\
template<> \
bool RegisterFunction<Object>()\
{\
return RegisterObject(#Object,&core::CreateNewObject<Object>);\
}

#define REGISTER_FUNCTION4(Object)\
template<> \
bool RegisterFunction<Object>()\
{\
return RegisterObject(#Object,&core::CreateNewObject<Object>);\
}*/
#define UNREGISTER_FUNCTION(Object)\
namespace Loki\


{\
template<> \
bool UnRegisterFunction<Object>()\

{\
return true;\
}\
}

#define GlobalGetNewObjectByName(name)\
core::ObjectFactory::Instance().CreateObject(name);
