//
// TFactory.h
// Common
//
// Created by Azure on 14-10-11.
// Copyright (c) 2014年 Azure. All rights reserved.
//
#ifndef Common_TFactory_h
#define Common_TFactory_h
//////////////////////////////////////////////////////
//定义一些不重复的Key ,枚举,int,字符串也可以
//定义基类,可以在基类定义模版来创建各个子类,或者各个子类有自己的创建函数,new的
//为单件类型
//typedef TFactory<BaseBullet, int> BulletFactory;就是一个工厂,
//注册创建函数
//BulletFactory::getInstance()->registerType(BulletType::BulletType_Red_L,BaseBullet::doCreate<Bullet_Red_L>);
//然后就可以根据定义的key来创建物品了,物品不需要delete,可以回收来重复利用,
//////////////////////////////////////////////////////
#include <map>
#include <vector>
#include <iostream>
namespace Lynx {
template <class AbstractProduct,typename IdentifierType,typename ProductCreator = AbstractProduct* (*)()>
class TFactory
{
typedef std::map<IdentifierType,ProductCreator> AssocMap;
AssocMap _associations;
typedef std::map<IdentifierType,std::vector<AbstractProduct*> > BackupMap;
BackupMap _backups;
TFactory(){}
TFactory(const TFactory<AbstractProduct,IdentifierType,ProductCreator>&);
TFactory(const TFactory<AbstractProduct,IdentifierType,ProductCreator>&&);
TFactory& operator = (const TFactory<AbstractProduct,IdentifierType,ProductCreator>&);
~TFactory()
{
clear();
}
public:
static TFactory<AbstractProduct,IdentifierType,ProductCreator>* getInstance()
{
static TFactory<AbstractProduct,IdentifierType,ProductCreator> instance;
return &instance;
}
bool registerType(const IdentifierType& idx,ProductCreator creator)
{
return _associations.insert(std::make_pair(idx,creator)).second;
}
bool unregisterType(const IdentifierType& idx)
{
return _associations.erase(idx) == 1;
}
AbstractProduct* createObject(const IdentifierType& idx)
{
typename BackupMap::iterator itBackup = _backups.find(idx);
if(itBackup != _backups.end() )
{
if(!itBackup->second.empty())
{
AbstractProduct *object = itBackup->second.back();
itBackup->second.pop_back();
return object;
}
}
typename AssocMap::const_iterator i = _associations.find(idx);
if (i != _associations.end())
{
return (i->second)();
}
return nullptr;
}
void recycleObject(const IdentifierType& idx,
AbstractProduct* object)
{
_backups[idx].push_back(object);
}
void clear()
{
typename BackupMap::iterator itCur,itEnd = _backups.end();
for (itCur = _backups.begin(); itCur != itEnd; ++itCur) {
for (size_t i = 0; i < itCur->second.size(); ++i) {
delete itCur->second[i];
}
}
_backups.clear();
}
};
}
#endif