Files
Sun1602/Server/GameServer/ObjectFactory.cpp
T
2022-10-26 12:25:11 +08:00

885 lines
28 KiB
C++

#include "stdafx.h"
#include "ObjectFactory.h"
#include <boost/pool/object_pool.hpp>
#include "Object.h"
#include "Player.h"
#include "Item.h"
#include "MapObject.h"
#include "Monster.h"
#include "Summoned.h"
#include "MapNPC.h"
#include "Merchant.h"
#include "LuckyMonster.h"
#include "TotemNpc.h"
#include "SSQMonster.h"
#include "Collection.h"
#include "CrystalWarp.h"
#include "FriendMonster.h"
#include "SyncMerchant.h"
#include "ObjKeyGenerator.h"
#include "MemoryPoolFactory.h"
#include "MemoryPoolFactoryV.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
// REGION : IObjectFactoryImpl
////////////////////////////////////////////////////////////////////////////////////////////////////
class IObjectFactoryImpl
{
public:
IObjectFactoryImpl() {}
virtual ~IObjectFactoryImpl() {}
public:
virtual void Init(
const size_t player_pool_size,
const size_t monster_pool_size,
const size_t item_pool_size,
const size_t map_object_Pool_size,
const size_t map_npc_pool_size,
const size_t merchant_pool_size,
const size_t lucky_monster_pool_size
) {
__UNUSED(player_pool_size);
__UNUSED(monster_pool_size);
__UNUSED(item_pool_size);
__UNUSED(map_object_Pool_size);
__UNUSED(map_npc_pool_size);
__UNUSED(merchant_pool_size);
__UNUSED(lucky_monster_pool_size);
}
virtual void Release() {}
virtual Object* AllocObject(const eOBJECT_TYPE object_type) = 0;
virtual bool FreeObject(Object* const object) = 0;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// REGION : FixedChunkImpl
////////////////////////////////////////////////////////////////////////////////////////////////////
class FixedChunkImpl : public IObjectFactoryImpl
{
public:
FixedChunkImpl() :
monster_keygen_(MONSTER_OBJECT_KEY+1, NPC_OBJECT_KEY),
item_keygen_(ITEM_OBJECT_KEY+1, PET_OBJECT_KEY),
monster_pool_(monster_keygen_),
summoned_pool_(monster_keygen_),
item_pool_(item_keygen_),
money_pool_(item_keygen_),
map_npc_pool_(monster_keygen_),
merchant_pool_(monster_keygen_),
lucky_monster_pool_(monster_keygen_),
totem_npc_pool_(item_keygen_),
ssq_monster_pool_(monster_keygen_),
crystal_warp_pool_(monster_keygen_),
friend_monster_pool_(monster_keygen_),
sync_merchant_pool_(monster_keygen_)
{
pools_[player_pool_.kType] = &player_pool_;
pools_[monster_pool_.kType] = &monster_pool_;
pools_[summoned_pool_.kType] = &summoned_pool_;
pools_[item_pool_.kType] = &item_pool_;
pools_[money_pool_.kType] = &money_pool_;
pools_[map_object_pool_.kType] = &map_object_pool_;
pools_[map_npc_pool_.kType] = &map_npc_pool_;
pools_[merchant_pool_.kType] = &merchant_pool_;
pools_[lucky_monster_pool_.kType] = &lucky_monster_pool_;
pools_[totem_npc_pool_.kType] = &totem_npc_pool_;
pools_[ssq_monster_pool_.kType] = &ssq_monster_pool_;
pools_[collection_pool_.kType] = &collection_pool_;
pools_[crystal_warp_pool_.kType] = &crystal_warp_pool_;
pools_[friend_monster_pool_.kType] = &friend_monster_pool_;
pools_[sync_merchant_pool_.kType] = &sync_merchant_pool_;
}
~FixedChunkImpl()
{
}
public:
virtual Object* AllocObject(const eOBJECT_TYPE object_type)
{
Pools::iterator it = pools_.find(object_type);
if (it == pools_.end())
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Invalid object type.|ObjectType = %d|"),
__FUNCTION__,
__LINE__,
object_type
);
assert(false);
return NULL;
}
IObjectPool* const object_pool = it->second;
return object_pool->Alloc();
}
virtual bool FreeObject(Object* const object)
{
if (object == NULL)
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Object is null.|"),
__FUNCTION__,
__LINE__
);
assert(false);
return false;
}
if (object->IsDeleted())
{
const Object::Key key = object->GetObjectKey();
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Object is already deleted.|ObjectKey = %d|"),
__FUNCTION__,
__LINE__,
key
);
assert(false);
return false;
}
const eOBJECT_TYPE object_type = object->GetObjectType();
Pools::iterator it = pools_.find(object_type);
if (it == pools_.end())
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Invalid object type.|ObjectType = %d|"),
__FUNCTION__,
__LINE__,
object_type
);
assert(false);
return false;
}
IObjectPool* const object_pool = it->second;
return object_pool->Free(object);
}
private:
// 키 생성기
class ObjectKeyGenerator
{
public:
enum { kInvalidKey = 0 };
public:
ObjectKeyGenerator(const Object::Key min_key, const Object::Key max_key) :
min_key_(min_key), max_key_(max_key), key_(min_key_)
{
assert(min_key_ < max_key_);
}
~ObjectKeyGenerator()
{
}
public:
Object::Key Alloc()
{
if (return_keys_.empty() == false)
{
const Object::Key key = return_keys_.front();
return_keys_.pop_front();
free_keys_.erase(key);
return key;
}
if (key_ > max_key_)
{
assert(false);
return kInvalidKey;
}
return key_++;
}
bool Free(const Object::Key key)
{
if (free_keys_.find(key) != free_keys_.end())
{
assert(false);
return false;
}
return_keys_.push_back(key);
free_keys_.insert(key);
return true;
}
private:
typedef STLX_DEQUE<Object::Key> ReturnKeys;
typedef STLX_HASH_SET<Object::Key> FreeKeys;
const Object::Key min_key_;
const Object::Key max_key_;
Object::Key key_;
ReturnKeys return_keys_;
FreeKeys free_keys_;
};
// 메모리 풀 인터페이스
class IObjectPool
{
public:
IObjectPool() {}
virtual ~IObjectPool() {}
virtual Object* Alloc() = 0;
virtual bool Free(Object* const object) = 0;
};
// 메모리 풀 (키젠 사용)
template <typename OBJECT_T, eOBJECT_TYPE kObjectType, size_t kPoolSize, bool kUseKeygen = true>
class ObjectPool : public IObjectPool
{
public:
enum { kType = kObjectType };
ObjectPool(ObjectKeyGenerator& keygen) : pool_impl_(kPoolSize), keygen_(keygen)
{
}
public:
virtual Object* Alloc()
{
const Object::Key key = keygen_.Alloc();
if (key == ObjectKeyGenerator::kInvalidKey)
{
return NULL;
}
Object* object = pool_impl_.construct();
if (object == NULL) {
keygen_.Free(key);
return NULL;
}
object->SetObjectKey(key);
object->SetObjectType(kObjectType);
return object;
}
virtual bool Free(Object* const object)
{
OBJECT_T* dest_obj = (OBJECT_T*)object;
const Object::Key key = dest_obj->GetObjectKey();
if (keygen_.Free(key) == false)
{
return false;
}
dest_obj->Reuse();
pool_impl_.destroy(dest_obj);
return true;
}
private:
typedef boost::object_pool<OBJECT_T> PoolImpl;
PoolImpl pool_impl_;
ObjectKeyGenerator& keygen_;
};
// 메모리 풀 (키젠 사용 안함)
template <typename OBJECT_T, eOBJECT_TYPE kObjectType, size_t kPoolSize>
class ObjectPool<OBJECT_T, kObjectType, kPoolSize, false> : public IObjectPool
{
public:
enum { kType = kObjectType };
ObjectPool() : pool_impl_(kPoolSize)
{
}
public:
virtual Object* Alloc()
{
Object* object = pool_impl_.construct();
object->SetObjectKey(1);
object->SetObjectType(kObjectType);
return object;
}
virtual bool Free(Object* const object)
{
OBJECT_T* dest_obj = (OBJECT_T*)object;
dest_obj->Reuse();
pool_impl_.destroy(dest_obj);
return true;
}
private:
typedef boost::object_pool<OBJECT_T> PoolImpl;
PoolImpl pool_impl_;
};
struct PoolSize
{
enum { kPlayer = 10 };
enum { kMonster = 1000 };
enum { kSummoned = 10 };
enum { kItem = 1000 };
enum { kMoney = 1000 };
enum { kMapObject = 100 };
enum { kMapNpc = 10 };
enum { kMerchant = 10 };
enum { kLuckyMonster = 10 };
enum { kTotemNpc = 10 };
enum { kSSQMonster = 20 };
enum { kCollection = 20 };
enum { kCrystalWarp = 10 };
enum { kFriendMonster = 20 };
enum { kSyncMerchant = 20 };
};
typedef ObjectPool<Player, PLAYER_OBJECT, PoolSize::kPlayer, false> PlayerPool;
typedef ObjectPool<Monster, MONSTER_OBJECT, PoolSize::kMonster> MonsterPool;
typedef ObjectPool<Summoned, SUMMON_OBJECT, PoolSize::kSummoned> SummonedPool;
typedef ObjectPool<Item, ITEM_OBJECT, PoolSize::kItem> ItemPool;
typedef ObjectPool<Item, MONEY_OBJECT, PoolSize::kMoney> MoneyPool;
typedef ObjectPool<MapObject, MAP_OBJECT, PoolSize::kMapObject, false> MapObjectPool;
typedef ObjectPool<MapNpc, MAPNPC_OBJECT, PoolSize::kMapNpc> MapNpcPool;
typedef ObjectPool<Merchant, MERCHANT_OBJECT, PoolSize::kMerchant> MerchantPool;
typedef ObjectPool<LuckyMonster, LUCKYMON_OBJECT, PoolSize::kLuckyMonster> LuckyMonsterPool;
typedef ObjectPool<TotemNpc, TOTEMNPC_OBJECT, PoolSize::kTotemNpc> TotemNpcPool;
typedef ObjectPool<SSQMonster, SSQMONSTER_OBJECT, PoolSize::kSSQMonster> SSQMonsterPool;
typedef ObjectPool<Collection, COLLECTION_OBJECT, PoolSize::kCollection, false> CollectionPool;
typedef ObjectPool<CrystalWarp, CRYSTALWARP_OBJECT, PoolSize::kCrystalWarp> CrystalWarpPool;
typedef ObjectPool<FriendMonster, FRIEND_MONSTER_OBJECT, PoolSize::kFriendMonster> FriendMonsterPool;
typedef ObjectPool<SyncMerchant, SYNC_MERCHANT_OBJECT, PoolSize::kSyncMerchant> SyncMerchantPool;
typedef STLX_HASH_MAP<int, IObjectPool*> Pools;
private:
ObjectKeyGenerator monster_keygen_;
ObjectKeyGenerator item_keygen_;
PlayerPool player_pool_;
MonsterPool monster_pool_;
SummonedPool summoned_pool_;
ItemPool item_pool_;
MoneyPool money_pool_;
MapObjectPool map_object_pool_;
MapNpcPool map_npc_pool_;
MerchantPool merchant_pool_;
LuckyMonsterPool lucky_monster_pool_;
TotemNpcPool totem_npc_pool_;
SSQMonsterPool ssq_monster_pool_;
CollectionPool collection_pool_;
CrystalWarpPool crystal_warp_pool_;
FriendMonsterPool friend_monster_pool_;
SyncMerchantPool sync_merchant_pool_;
Pools pools_;
}; // FixedChunkImpl
////////////////////////////////////////////////////////////////////////////////////////////////////
// REGION : VariableChunkImpl
////////////////////////////////////////////////////////////////////////////////////////////////////
class VariableChunkImpl : public IObjectFactoryImpl
{
public:
VariableChunkImpl()
{
typedef ObjectPoolDefault<PLAYER_OBJECT, Player> PlayerPool;
typedef ObjectPoolDefault<MONSTER_OBJECT, Monster> MonsterPool;
typedef ObjectPoolDefault<SUMMON_OBJECT, Summoned> SummonedPool;
typedef ObjectPoolDefault<ITEM_OBJECT, Item> ItemPool;
typedef ObjectPoolDefault<MAP_OBJECT, MapObject> MapObjectPool;
typedef ObjectPoolDefault<MAPNPC_OBJECT, MapNpc> MapNpcPool;
typedef ObjectPoolDefault<MERCHANT_OBJECT, Merchant> MerchantPool;
typedef ObjectPoolDefault<LUCKYMON_OBJECT, LuckyMonster> LuckyMonsterPool;
typedef ObjectPoolDefault<TOTEMNPC_OBJECT, TotemNpc> TotemNpcPool;
typedef ObjectPoolDefault<SSQMONSTER_OBJECT, SSQMonster> SSQMonsterPool;
typedef ObjectPoolDefault<COLLECTION_OBJECT, Collection> CollectionPool;
typedef ObjectPoolDefault<CRYSTALWARP_OBJECT, CrystalWarp> CrystalWarpPool;
typedef ObjectPoolDefault<FRIEND_MONSTER_OBJECT, FriendMonster> FriendMonsterPool;
typedef ObjectPoolDefault<SYNC_MERCHANT_OBJECT, SyncMerchant> SyncMerchantPool;
router_.RegisterPool<PlayerPool>(PoolIndex::kPlayer);
router_.RegisterPool<MonsterPool>(PoolIndex::kMonster);
router_.RegisterPool<SummonedPool>(PoolIndex::kSummoned);
router_.RegisterPool<ItemPool>(PoolIndex::kItem);
router_.RegisterPool<MapObjectPool>(PoolIndex::kMapObject);
router_.RegisterPool<MapNpcPool>(PoolIndex::kMapNpc);
router_.RegisterPool<MerchantPool>(PoolIndex::kMerchant);
router_.RegisterPool<LuckyMonsterPool>(PoolIndex::kLuckyMonster);
router_.RegisterPool<TotemNpcPool>(PoolIndex::kTotemNpc);
router_.RegisterPool<SSQMonsterPool>(PoolIndex::kSSQMonster);
router_.RegisterPool<CollectionPool>(PoolIndex::kCollection);
router_.RegisterPool<CrystalWarpPool>(PoolIndex::kCrystalWarp);
router_.RegisterPool<FriendMonsterPool>(PoolIndex::kFriendMonster);
router_.RegisterPool<SyncMerchantPool>(PoolIndex::kSyncMerchant);
KeyGenerator* keygens[PoolIndex::kMax] =
{
NULL, // PoolIndex::kPlayer
&monster_keygen_, // PoolIndex::kMonster
&monster_keygen_, // PoolIndex::kSummoned
&field_item_keygen_, // PoolIndex::kItem
NULL, // PoolIndex::kMapObject
&monster_keygen_, // PoolIndex::kMapNpc
&monster_keygen_, // PoolIndex::kMerchant
&monster_keygen_, // PoolIndex::kLuckyMonster
&field_item_keygen_, // PoolIndex::kTotemNpc
&monster_keygen_, // PoolIndex::kSSQMonster
NULL, // PoolIndex::kCollection
&monster_keygen_, // PoolIndex::kCrystalWarp
&monster_keygen_, // PoolIndex::kFriendMonster
&monster_keygen_ // PoolIndex::kSyncMerchant
};
for (int i = PoolIndex::kPlayer; i < PoolIndex::kMax; ++i)
{
IObjectAllocator* const alloc = dynamic_cast<IObjectAllocator*>(router_.GetPool(i));
alloc->RegisterKeyGenerator(keygens[i]);
}
}
~VariableChunkImpl()
{
}
public:
virtual void Init(
const size_t player_pool_size,
const size_t monster_pool_size,
const size_t item_pool_size,
const size_t map_object_Pool_size,
const size_t map_npc_pool_size,
const size_t merchant_pool_size,
const size_t lucky_monster_pool_size
) {
__UNUSED(player_pool_size);
__UNUSED(monster_pool_size);
__UNUSED(item_pool_size);
__UNUSED(map_object_Pool_size);
__UNUSED(map_npc_pool_size);
__UNUSED(merchant_pool_size);
__UNUSED(lucky_monster_pool_size);
if (router_.Initialize(PoolIndex::kPlayer, 10, 20, "Player") == false)
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Failed to initialize memory pool.|PoolIndex = %d|"),
__FUNCTION__,
__LINE__,
PoolIndex::kPlayer
);
assert(false);
}
if (router_.Initialize(PoolIndex::kMonster, 100, 100, "Monster") == false)
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Failed to initialize memory pool.|PoolIndex = %d|"),
__FUNCTION__,
__LINE__,
PoolIndex::kMonster
);
assert(false);
}
if (router_.Initialize(PoolIndex::kSummoned, 10, 20, "Summoned") == false)
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Failed to initialize memory pool.|PoolIndex = %d|"),
__FUNCTION__,
__LINE__,
PoolIndex::kSummoned
);
assert(false);
}
if (router_.Initialize(PoolIndex::kItem, 100, 100, "Item") == false)
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Failed to initialize memory pool.|PoolIndex = %d|"),
__FUNCTION__,
__LINE__,
PoolIndex::kItem
);
assert(false);
}
if (router_.Initialize(PoolIndex::kMapObject, 100, 100, "MapObject") == false)
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Failed to initialize memory pool.|PoolIndex = %d|"),
__FUNCTION__,
__LINE__,
PoolIndex::kMapObject
);
assert(false);
}
if (router_.Initialize(PoolIndex::kMapNpc, 10, 20, "MapNpc") == false)
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Failed to initialize memory pool.|PoolIndex = %d|"),
__FUNCTION__,
__LINE__,
PoolIndex::kMapNpc
);
assert(false);
}
if (router_.Initialize(PoolIndex::kMerchant, 10, 20, "Merchant") == false)
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Failed to initialize memory pool.|PoolIndex = %d|"),
__FUNCTION__,
__LINE__,
PoolIndex::kMerchant
);
assert(false);
}
if (router_.Initialize(PoolIndex::kLuckyMonster, 10, 10, "LuckyMonster") == false)
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Failed to initialize memory pool.|PoolIndex = %d|"),
__FUNCTION__,
__LINE__,
PoolIndex::kLuckyMonster
);
assert(false);
}
if (router_.Initialize(PoolIndex::kTotemNpc, 10, 20, "TotemNpc") == false)
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Failed to initialize memory pool.|PoolIndex = %d|"),
__FUNCTION__,
__LINE__,
PoolIndex::kTotemNpc
);
assert(false);
}
if (router_.Initialize(PoolIndex::kSSQMonster, 20, 20, "SSQMonster") == false)
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Failed to initialize memory pool.|PoolIndex = %d|"),
__FUNCTION__,
__LINE__,
PoolIndex::kSSQMonster
);
assert(false);
}
if (router_.Initialize(PoolIndex::kCollection, 20, 20, "Collection") == false)
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Failed to initialize memory pool.|PoolIndex = %d|"),
__FUNCTION__,
__LINE__,
PoolIndex::kCollection
);
assert(false);
}
if (router_.Initialize(PoolIndex::kCrystalWarp, 10, 10, "CrystalWarp") == false)
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Failed to initialize memory pool.|PoolIndex = %d|"),
__FUNCTION__,
__LINE__,
PoolIndex::kCrystalWarp
);
assert(false);
}
if (router_.Initialize(PoolIndex::kFriendMonster, 20, 20, "FriendMonster") == false)
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Failed to initialize memory pool.|PoolIndex = %d|"),
__FUNCTION__,
__LINE__,
PoolIndex::kFriendMonster
);
assert(false);
}
if (router_.Initialize(PoolIndex::kSyncMerchant, 20, 20, "SyncMerchant") == false)
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Failed to initialize memory pool.|PoolIndex = %d|"),
__FUNCTION__,
__LINE__,
PoolIndex::kSyncMerchant
);
assert(false);
}
monster_keygen_.Create(MONSTER_OBJECT_KEY+1, NPC_OBJECT_KEY);
field_item_keygen_.Create(ITEM_OBJECT_KEY+1, PET_OBJECT_KEY);
}
virtual void Release()
{
router_.Release();
}
virtual Object* AllocObject(const eOBJECT_TYPE object_type)
{
const PoolIndex::Value pool_index = GetPoolIndex(object_type);
if (pool_index >= PoolIndex::kMax)
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Invalid object type.|ObjectType = %d|"),
__FUNCTION__,
__LINE__,
object_type
);
assert(false);
return NULL;
}
Object* const object = (Object*)router_.Alloc(pool_index);
if (object == NULL)
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Fail to create object.|ObjectType = %d, PoolIndex = %d|"),
__FUNCTION__,
__LINE__,
object_type,
pool_index
);
assert(false);
return NULL;
}
if (object_type == ITEM_OBJECT || object_type == MONEY_OBJECT)
{
object->SetObjectType(object_type);
}
return object;
}
virtual bool FreeObject(Object* const object)
{
if (object == NULL)
{
return false;
}
const eOBJECT_TYPE object_type = object->GetObjectType();
const PoolIndex::Value pool_index = GetPoolIndex(object_type);
if (pool_index >= PoolIndex::kMax)
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Invalid object type.|ObjectType = %d|"),
__FUNCTION__,
__LINE__,
object_type
);
assert(false);
return false;
}
return !!router_.Free(pool_index, object);
}
private:
struct PoolIndex
{
enum Value
{
kPlayer = 0,
kMonster,
kSummoned,
kItem,
kMapObject,
kMapNpc,
kMerchant,
kLuckyMonster,
kTotemNpc,
kSSQMonster,
kCollection,
kCrystalWarp,
kFriendMonster,
kSyncMerchant,
kMax
};
};
typedef util::CObjKeyGenerator<> KeyGenerator;
// IObjectAllocator
class IObjectAllocator
{
public:
IObjectAllocator() : keygen_(NULL)
{
}
virtual void RegisterKeyGenerator(KeyGenerator* const keygen)
{
keygen_ = keygen;
}
virtual void ActionPostAlloc(Object* const object, const eOBJECT_TYPE object_type)
{
if (keygen_ != NULL)
{
const DWORD key = keygen_->GetKey();
object->SetObjectKey(key);
}
else
{
object->SetObjectKey(1);
}
object->SetObjectType(object_type);
}
virtual void ActionPrevFree(Object* const object)
{
if (keygen_ != NULL)
{
const DWORD key = object->GetObjectKey();
keygen_->RestoreKey(key);
}
object->Reuse();
}
private:
KeyGenerator* keygen_;
};
// ObjectPoolDefault
template <eOBJECT_TYPE kObjectType, typename OBJECT_T>
class ObjectPoolDefault : public util::CMemoryPoolFactory<OBJECT_T>, public IObjectAllocator
{
public:
ObjectPoolDefault()
{
}
virtual void* Alloc()
{
Object* const object = (Object*)Base::Alloc();
IObjectAllocator::ActionPostAlloc(object, object->GetObjectType());
return object;
}
virtual BOOL Free(void* node)
{
Object* const object = (Object*)node;
IObjectAllocator::ActionPrevFree(object);
return Base::Free(object);
}
private:
typedef util::CMemoryPoolFactory<OBJECT_T> Base;
};
private:
PoolIndex::Value GetPoolIndex(const eOBJECT_TYPE object_type) const
{
switch (object_type)
{
case PLAYER_OBJECT:
return PoolIndex::kPlayer;
case MONSTER_OBJECT:
return PoolIndex::kMonster;
case SUMMON_OBJECT:
return PoolIndex::kSummoned;
case ITEM_OBJECT:
case MONEY_OBJECT:
return PoolIndex::kItem;
case MAP_OBJECT:
return PoolIndex::kMapObject;
case MAPNPC_OBJECT:
return PoolIndex::kMapNpc;
case MERCHANT_OBJECT:
return PoolIndex::kMerchant;
case LUCKYMON_OBJECT:
return PoolIndex::kLuckyMonster;
case TOTEMNPC_OBJECT:
return PoolIndex::kTotemNpc;
case SSQMONSTER_OBJECT:
return PoolIndex::kSSQMonster;
case COLLECTION_OBJECT:
return PoolIndex::kCollection;
case CRYSTALWARP_OBJECT:
return PoolIndex::kCrystalWarp;
case FRIEND_MONSTER_OBJECT:
return PoolIndex::kFriendMonster;
case SYNC_MERCHANT_OBJECT:
return PoolIndex::kSyncMerchant;
}
return PoolIndex::kMax;
}
private:
util::PoolRouter<PoolIndex::kMax> router_;
KeyGenerator monster_keygen_;
KeyGenerator field_item_keygen_;
}; // VariableChunkImpl
////////////////////////////////////////////////////////////////////////////////////////////////////
// REGION : ObjectFactory
////////////////////////////////////////////////////////////////////////////////////////////////////
ObjectFactory::ObjectFactory()
{
}
ObjectFactory::~ObjectFactory()
{
}
void ObjectFactory::CreateImpl(const int chunk_mode)
{
SUNLOG(
eCRITICAL_LOG,
_T("|%s|%d|Creating object factory implement...|ChunkMode = %d|"),
__FUNCTION__,
__LINE__,
chunk_mode
);
//#ifdef USE_FIXED_SIZE_MEMORY_POOL
typedef FixedChunkImpl DefaultImpl;
//#else
// typedef VariableChunkImpl DefaultImpl;
//#endif
switch (chunk_mode)
{
case kVariableChunk:
impl_.reset(new VariableChunkImpl());
return;
case kFixedChunk:
impl_.reset(new FixedChunkImpl());
return;
default:
impl_.reset(new DefaultImpl());
return;
}
}
void ObjectFactory::Init(
const size_t player_pool_size,
const size_t monster_pool_size,
const size_t item_pool_size,
const size_t map_object_Pool_size,
const size_t map_npc_pool_size,
const size_t merchant_pool_size,
const size_t lucky_monster_pool_size
) {
int chunk_mode = kDefaultChunkMode;
{
char path_buf[MAX_PATH] = { 0 };
const size_t written = ::GetModuleFileName(NULL, path_buf, _countof(path_buf));
if (written > 0)
{
std::string ini_path(path_buf, written);
const size_t deli_pos = ini_path.find_last_of('\\');
if (deli_pos > 0)
{
ini_path = ini_path.substr(0, deli_pos);
ini_path += "\\MemoryPool.ini";
chunk_mode = ::GetPrivateProfileInt(
"OBJECT_FACTORY", "CHUNK_MODE", kDefaultChunkMode, ini_path.c_str());
}
}
}
CreateImpl(chunk_mode);
return impl_->Init(
player_pool_size,
monster_pool_size,
item_pool_size,
map_object_Pool_size,
map_npc_pool_size,
merchant_pool_size,
lucky_monster_pool_size);
}
void ObjectFactory::Release()
{
return impl_->Release();
}
Object* ObjectFactory::AllocObject(const eOBJECT_TYPE object_type)
{
return impl_->AllocObject(object_type);
}
bool ObjectFactory::FreeObject(Object* const object)
{
return impl_->FreeObject(object);
}