From c6f6a560bfc5ee408b3fb8f658ce0ffbe7860cb8 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Tue, 1 Jun 2021 19:13:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=AF=B9=E8=B1=A1=E6=B1=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/gameserver/app.cc | 3 + server/gameserver/constant.h | 4 - server/gameserver/gridcell.cc | 134 ++++++++++++++++++++--------- server/gameserver/gridcell.h | 6 +- server/gameserver/objectpoolmgr.cc | 99 +++++++++++++++++++++ server/gameserver/objectpoolmgr.h | 35 ++++++++ 6 files changed, 234 insertions(+), 47 deletions(-) create mode 100644 server/gameserver/objectpoolmgr.cc create mode 100644 server/gameserver/objectpoolmgr.h diff --git a/server/gameserver/app.cc b/server/gameserver/app.cc index 91683f7..4e075c9 100755 --- a/server/gameserver/app.cc +++ b/server/gameserver/app.cc @@ -22,6 +22,7 @@ #include "playermgr.h" #include "mapmgr.h" #include "entityfactory.h" +#include "objectpoolmgr.h" #include "perfmonitor.h" #include "ss_msgid.pb.h" @@ -137,6 +138,7 @@ bool App::Init(int argc, char* argv[]) JsonDataMgr::Instance()->Init(); MetaMgr::Instance()->Init(); EntityFactory::Instance()->Init(); + ObjectPoolMgr::Instance()->Init(); uuid.SetMachineId((node_id - 1) * MAX_NODE_ID + instance_id); RoomMgr::Instance()->Init(); MapMgr::Instance()->Init(); @@ -178,6 +180,7 @@ void App::UnInit() PlayerMgr::Instance()->UnInit(); MapMgr::Instance()->UnInit(); RoomMgr::Instance()->UnInit(); + ObjectPoolMgr::Instance()->UnInit(); EntityFactory::Instance()->UnInit(); MetaMgr::Instance()->UnInit(); JsonDataMgr::Instance()->UnInit(); diff --git a/server/gameserver/constant.h b/server/gameserver/constant.h index 714d41f..c36fbef 100755 --- a/server/gameserver/constant.h +++ b/server/gameserver/constant.h @@ -377,11 +377,7 @@ const int ADPLAY_BUFFID = 1006; const int FIXED_OBJECT_MAXID = 20140; -#ifdef DEBUG -const int MAX_ROOM_IDX = 100; -#else const int MAX_ROOM_IDX = 1024; -#endif const int VIEW_RANGE = 512; diff --git a/server/gameserver/gridcell.cc b/server/gameserver/gridcell.cc index 43e9009..88b5eea 100644 --- a/server/gameserver/gridcell.cc +++ b/server/gameserver/gridcell.cc @@ -8,39 +8,51 @@ #include "car.h" #include "hero.h" #include "creature.h" +#include "objectpoolmgr.h" GridCell::GridCell() { entitys_.reserve(MAX_ROOM_IDX); bullets_.reserve(MAX_ROOM_IDX); creatures_.reserve(MAX_ROOM_IDX); - for (int i = 0; i < MAX_ROOM_IDX; ++i) { - entitys_.push_back(std::set()); - bullets_.push_back(std::set()); - creatures_.push_back(std::set()); - } + memset(&entitys_[0], 0, sizeof(std::set*) * MAX_ROOM_IDX); + memset(&bullets_[0], 0, sizeof(std::set*) * MAX_ROOM_IDX); + memset(&creatures_[0], 0, sizeof(std::set*) * MAX_ROOM_IDX); } - void GridCell::ClearRoomData(Room* room) { - entitys_[room->GetRoomIdx()].clear(); - bullets_[room->GetRoomIdx()].clear(); - creatures_[room->GetRoomIdx()].clear(); + if (entitys_[room->GetRoomIdx()]) { + entitys_[room->GetRoomIdx()]->clear(); + ObjectPoolMgr::Instance()->FreeEntitySet(entitys_[room->GetRoomIdx()]); + entitys_[room->GetRoomIdx()] = nullptr; + } + if (bullets_[room->GetRoomIdx()]) { + bullets_[room->GetRoomIdx()]->clear(); + ObjectPoolMgr::Instance()->FreeBulletSet(bullets_[room->GetRoomIdx()]); + bullets_[room->GetRoomIdx()] = nullptr; + } + if (creatures_[room->GetRoomIdx()]) { + creatures_[room->GetRoomIdx()]->clear(); + ObjectPoolMgr::Instance()->FreeCreatureSet(creatures_[room->GetRoomIdx()]); + creatures_[room->GetRoomIdx()] = nullptr; + } } void GridCell::TraverseHumanList(std::function func, int room_idx, bool& stop) { - for (Creature* c : creatures_[room_idx]) { - if (!c->IsHuman()) { - continue; - } - Human* hum = (Human*)c; - func(hum, stop); - if (stop) { - return; + if (creatures_[room_idx]) { + for (Creature* c : *creatures_[room_idx]) { + if (!c->IsHuman()) { + continue; + } + Human* hum = (Human*)c; + func(hum, stop); + if (stop) { + return; + } } } } @@ -49,55 +61,83 @@ void GridCell::TraverseCreatures(std::function& func, int room_idx, bool& stop) { - for (Creature* c : creatures_[room_idx]) { - func(c, stop); - if (stop) { - return; + if (creatures_[room_idx]) { + for (Creature* c : *creatures_[room_idx]) { + func(c, stop); + if (stop) { + return; + } } } } void GridCell::AddBullet(Bullet* bullet) { - bullets_[bullet->room->GetRoomIdx()].insert(bullet); + if (!bullets_[bullet->room->GetRoomIdx()]) { + bullets_[bullet->room->GetRoomIdx()] = ObjectPoolMgr::Instance()->AllocBulletSet(this, bullet->room); + } + bullets_[bullet->room->GetRoomIdx()]->insert(bullet); } void GridCell::RemoveBullet(Bullet* bullet) { - bullets_[bullet->room->GetRoomIdx()].erase(bullet); + if (bullets_[bullet->room->GetRoomIdx()]) { + bullets_[bullet->room->GetRoomIdx()]->erase(bullet); + if (bullets_[bullet->room->GetRoomIdx()]->empty()) { + ObjectPoolMgr::Instance()->FreeBulletSet(bullets_[bullet->room->GetRoomIdx()]); + bullets_[bullet->room->GetRoomIdx()] = nullptr; + } + } } void GridCell::AddPermanentEntity(Entity* entity) { - entitys_[0].insert(entity); + if (!entitys_[0]) { + entitys_[0] = new std::set; + } + entitys_[0]->insert(entity); } void GridCell::AddRoomEntity(Room* room, Entity* entity) { - entitys_[room->GetRoomIdx()].insert(entity); + if (!entitys_[room->GetRoomIdx()]) { + entitys_[room->GetRoomIdx()] = ObjectPoolMgr::Instance()->AllocEntitySet(this, room); + } + entitys_[room->GetRoomIdx()]->insert(entity); } void GridCell::RemoveRoomEntity(Room* room, Entity* entity) { - entitys_[room->GetRoomIdx()].erase(entity); + if (entitys_[room->GetRoomIdx()]) { + entitys_[room->GetRoomIdx()]->erase(entity); + if (entitys_[room->GetRoomIdx()]->empty()) { + ObjectPoolMgr::Instance()->FreeEntitySet(entitys_[room->GetRoomIdx()]); + entitys_[room->GetRoomIdx()] = nullptr; + } + } } bool GridCell::EntityExists(Room* room, Entity* entity) { - if (entitys_[0].find(entity) != entitys_[0].end()) { + if (entitys_[0] && entitys_[0]->find(entity) != entitys_[0]->end()) { return true; } - return entitys_[room->GetRoomIdx()].find(entity) != - entitys_[room->GetRoomIdx()].end(); + if (!entitys_[room->GetRoomIdx()]) { + return false; + } + return entitys_[room->GetRoomIdx()]->find(entity) != + entitys_[room->GetRoomIdx()]->end(); } void GridCell::TraverseLayer0EntityList(std::function& func, bool& stop) { - for (Entity* entity : entitys_[0]) { - func(entity, stop); - if (stop) { - return; + if (entitys_[0]) { + for (Entity* entity : *entitys_[0]) { + func(entity, stop); + if (stop) { + return; + } } } } @@ -106,10 +146,12 @@ void GridCell::TraverseLayer1EntityList(std::function& fu int room_idx, bool& stop) { - for (Entity* entity : entitys_[room_idx]) { - func(entity, stop); - if (stop) { - return; + if (entitys_[room_idx]) { + for (Entity* entity : *entitys_[room_idx]) { + func(entity, stop); + if (stop) { + return; + } } } } @@ -126,15 +168,27 @@ void GridCell::TraverseAllLayerEntityList(std::function& void GridCell::AddCreature(Creature* c) { - creatures_[c->room->GetRoomIdx()].insert(c); + if (!creatures_[c->room->GetRoomIdx()]) { + creatures_[c->room->GetRoomIdx()] = ObjectPoolMgr::Instance()->AllocCreatureSet(this, c->room); + } + creatures_[c->room->GetRoomIdx()]->insert(c); } void GridCell::RemoveCreature(Creature* c) { - creatures_[c->room->GetRoomIdx()].erase(c); + if (creatures_[c->room->GetRoomIdx()]) { + creatures_[c->room->GetRoomIdx()]->erase(c); + if (creatures_[c->room->GetRoomIdx()]->empty()) { + ObjectPoolMgr::Instance()->FreeCreatureSet(creatures_[c->room->GetRoomIdx()]); + creatures_[c->room->GetRoomIdx()] = nullptr; + } + } } bool GridCell::CreatureExists(Creature* c) { - return creatures_[c->room->GetRoomIdx()].find(c) != creatures_[c->room->GetRoomIdx()].end(); + if (!creatures_[c->room->GetRoomIdx()]) { + return false; + } + return creatures_[c->room->GetRoomIdx()]->find(c) != creatures_[c->room->GetRoomIdx()]->end(); } diff --git a/server/gameserver/gridcell.h b/server/gameserver/gridcell.h index d6188c5..eeeb569 100644 --- a/server/gameserver/gridcell.h +++ b/server/gameserver/gridcell.h @@ -39,7 +39,7 @@ public: bool& stop); private: - std::vector> entitys_; - std::vector> bullets_; - std::vector> creatures_; + std::vector*> entitys_; + std::vector*> bullets_; + std::vector*> creatures_; }; diff --git a/server/gameserver/objectpoolmgr.cc b/server/gameserver/objectpoolmgr.cc new file mode 100644 index 0000000..13648f9 --- /dev/null +++ b/server/gameserver/objectpoolmgr.cc @@ -0,0 +1,99 @@ +#include "precompile.h" + +#include +#include "objectpoolmgr.h" + +void ObjectPoolMgr::Init() +{ + free_entitys_.reserve(1024 * 4); + free_bullets_.reserve(1024 * 4); + free_creatures_.reserve(1024 * 4); + a8::Timer::Instance()->AddRepeatTimer + (1000 * 10, + a8::XParams(), + [] (const a8::XParams& param) + { + ObjectPoolMgr::Instance()->GcTimerFunc(); + }); +} + +void ObjectPoolMgr::UnInit() +{ + +} + +std::set* ObjectPoolMgr::AllocEntitySet(GridCell* cell, Room* room) +{ + if (free_entitys_.empty()) { + return new std::set(); + } + std::set* p = free_entitys_[free_entitys_.size() - 1]; + free_entitys_.erase(free_entitys_.begin() + free_entitys_.size() - 1); + return p; +} + +std::set* ObjectPoolMgr::AllocBulletSet(GridCell* cell, Room* room) +{ + if (free_bullets_.empty()) { + return new std::set(); + } + std::set* p = free_bullets_[free_bullets_.size() - 1]; + free_bullets_.erase(free_bullets_.begin() + free_bullets_.size() - 1); + return p; +} + +std::set* ObjectPoolMgr::AllocCreatureSet(GridCell* cell, Room* room) +{ + if (free_creatures_.empty()) { + return new std::set(); + } + std::set* p = free_creatures_[free_creatures_.size() - 1]; + free_creatures_.erase(free_creatures_.begin() + free_creatures_.size() - 1); + return p; +} + +void ObjectPoolMgr::FreeEntitySet(std::set* p) +{ + free_entitys_.push_back(p); +} + +void ObjectPoolMgr::FreeBulletSet(std::set* p) +{ + free_bullets_.push_back(p); +} + +void ObjectPoolMgr::FreeCreatureSet(std::set* p) +{ + free_creatures_.push_back(p); +} + +void ObjectPoolMgr::GcTimerFunc() +{ + { + int count = 0; + while (free_entitys_.size() > 5000 && count < 100) { + std::set* p = free_entitys_[free_entitys_.size() - 1]; + delete p; + free_entitys_.erase(free_entitys_.begin() + free_entitys_.size() - 1); + ++count; + } + } + { + int count = 0; + while (free_bullets_.size() > 5000 && count < 100) { + std::set* p = free_bullets_[free_bullets_.size() - 1]; + delete p; + free_bullets_.erase(free_bullets_.begin() + free_bullets_.size() - 1); + ++count; + } + } + { + int count = 0; + while (free_creatures_.size() > 5000 && count < 100) { + std::set* p = free_creatures_[free_creatures_.size() - 1]; + delete p; + free_creatures_.erase(free_creatures_.begin() + free_creatures_.size() - 1); + ++count; + } + } +} diff --git a/server/gameserver/objectpoolmgr.h b/server/gameserver/objectpoolmgr.h new file mode 100644 index 0000000..333a2e6 --- /dev/null +++ b/server/gameserver/objectpoolmgr.h @@ -0,0 +1,35 @@ +#pragma once + +class GridCell; +class Room; +class Entity; +class Bullet; +class Creature; +class ObjectPoolMgr : public a8::Singleton +{ + + private: + ObjectPoolMgr() {}; + friend class a8::Singleton; + + public: + + void Init(); + void UnInit(); + + std::set* AllocEntitySet(GridCell* cell, Room* room); + std::set* AllocBulletSet(GridCell* cell, Room* room); + std::set* AllocCreatureSet(GridCell* cell, Room* room); + + void FreeEntitySet(std::set* p); + void FreeBulletSet(std::set* p); + void FreeCreatureSet(std::set* p); + + private: + void GcTimerFunc(); + + private: + std::vector*> free_entitys_; + std::vector*> free_bullets_; + std::vector*> free_creatures_; +};