[7311] Divide MessageChatLocaleCacheDo to specialized helper classes

1) LocalizedPacketDo (allocate and cache packets for locale indexes)
2) MonsterChatBuilder (prepare monster chat message packet for specific locale index)
This commit is contained in:
VladimirMangos 2009-02-21 03:06:34 +03:00
parent 1ccafb2fc9
commit 34a9f0302e
5 changed files with 95 additions and 52 deletions

View file

@ -479,6 +479,26 @@ namespace MaNGOS
template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
};
template<class Do>
struct MANGOS_DLL_DECL PlayerDistWorker
{
WorldObject const* i_searcher;
float i_dist;
Do& i_do;
PlayerDistWorker(WorldObject const* searcher, float _dist, Do& _do)
: i_searcher(searcher), i_dist(_dist), i_do(_do) {}
void Visit(PlayerMapType &m)
{
for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
if(itr->getSource()->InSamePhase(i_searcher) && itr->getSource()->GetDistance(i_searcher) <= i_dist)
i_do(itr->getSource());
}
template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
};
// CHECKS && DO classes
// WorldObject check classes
@ -819,6 +839,28 @@ namespace MaNGOS
float i_range;
};
// Player checks and do
// Prepare using Builder localized packets with caching and send to player
template<class Builder>
class LocalizedPacketDo
{
public:
explicit LocalizedPacketDo(Builder& builder) : i_builder(builder) {}
LocalizedPacketDo::~LocalizedPacketDo()
{
for(int i = 0; i < i_data_cache.size(); ++i)
delete i_data_cache[i];
}
void operator()( Player* p );
private:
Builder& i_builder;
std::vector<WorldPacket*> i_data_cache; // 0 = default, i => i-1 locale index
};
#ifndef WIN32
template<> void PlayerRelocationNotifier::Visit<Creature>(CreatureMapType &);
template<> void PlayerRelocationNotifier::Visit<Player>(PlayerMapType &);

View file

@ -537,4 +537,29 @@ void MaNGOS::PlayerSearcher<Check>::Visit(PlayerMapType &m)
}
}
template<class Builder>
void MaNGOS::LocalizedPacketDo<Builder>::operator()( Player* p )
{
uint32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex();
uint32 cache_idx = loc_idx+1;
WorldPacket* data;
// create if not cached yet
if(i_data_cache.size() < cache_idx+1 || !i_data_cache[cache_idx])
{
if(i_data_cache.size() < cache_idx+1)
i_data_cache.resize(cache_idx+1);
data = new WorldPacket(SMSG_MESSAGECHAT, 200);
i_builder(*data,loc_idx);
i_data_cache[cache_idx] = data;
}
else
data = i_data_cache[cache_idx];
p->SendDirectMessage(data);
}
#endif // MANGOS_GRIDNOTIFIERSIMPL_H

View file

@ -315,6 +315,14 @@ class Guild
void BroadcastPacketToRank(WorldPacket *packet, uint32 rankId);
void BroadcastPacket(WorldPacket *packet);
template<class Do>
void BroadcastWorker(Do& _do)
{
for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
if(Player *player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)))
_do(player);
}
void CreateRank(std::string name,uint32 rights);
void DelRank();
std::string GetRankName(uint32 rankId);

View file

@ -1246,50 +1246,17 @@ void WorldObject::MonsterWhisper(const char* text, uint64 receiver, bool IsBossW
namespace MaNGOS
{
class MessageChatLocaleCacheDo
class MonsterChatBuilder
{
public:
MessageChatLocaleCacheDo(WorldObject const& obj, ChatMsg msgtype, int32 textId, uint32 language, uint64 targetGUID, float dist)
: i_object(obj), i_msgtype(msgtype), i_textId(textId), i_language(language),
i_targetGUID(targetGUID), i_dist(dist)
MonsterChatBuilder(WorldObject const& obj, ChatMsg msgtype, int32 textId, uint32 language, uint64 targetGUID)
: i_object(obj), i_msgtype(msgtype), i_textId(textId), i_language(language), i_targetGUID(targetGUID) {}
void operator()(WorldPacket& data, int32 loc_idx)
{
}
char const* text = objmgr.GetMangosString(i_textId,loc_idx);
~MessageChatLocaleCacheDo()
{
for(int i = 0; i < i_data_cache.size(); ++i)
delete i_data_cache[i];
}
void operator()(Player* p)
{
// skip far away players
if(p->GetDistance(&i_object) > i_dist)
return;
uint32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex();
uint32 cache_idx = loc_idx+1;
WorldPacket* data;
// create if not cached yet
if(i_data_cache.size() < cache_idx+1 || !i_data_cache[cache_idx])
{
if(i_data_cache.size() < cache_idx+1)
i_data_cache.resize(cache_idx+1);
char const* text = objmgr.GetMangosString(i_textId,loc_idx);
data = new WorldPacket(SMSG_MESSAGECHAT, 200);
// TODO: i_object.GetName() also must be localized?
i_object.BuildMonsterChat(data,i_msgtype,text,i_language,i_object.GetNameForLocaleIdx(loc_idx),i_targetGUID);
i_data_cache[cache_idx] = data;
}
else
data = i_data_cache[cache_idx];
p->SendDirectMessage(data);
// TODO: i_object.GetName() also must be localized?
i_object.BuildMonsterChat(&data,i_msgtype,text,i_language,i_object.GetNameForLocaleIdx(loc_idx),i_targetGUID);
}
private:
@ -1298,8 +1265,6 @@ namespace MaNGOS
int32 i_textId;
uint32 i_language;
uint64 i_targetGUID;
float i_dist;
std::vector<WorldPacket*> i_data_cache; // 0 = default, i => i-1 locale index
};
} // namespace MaNGOS
@ -1311,9 +1276,10 @@ void WorldObject::MonsterSay(int32 textId, uint32 language, uint64 TargetGuid)
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
MaNGOS::MessageChatLocaleCacheDo say_do(*this, CHAT_MSG_MONSTER_SAY, textId,language,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY));
MaNGOS::PlayerWorker<MaNGOS::MessageChatLocaleCacheDo> say_worker(this,say_do);
TypeContainerVisitor<MaNGOS::PlayerWorker<MaNGOS::MessageChatLocaleCacheDo>, WorldTypeMapContainer > message(say_worker);
MaNGOS::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_SAY, textId,language,TargetGuid);
MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> say_do(say_build);
MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY),say_do);
TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, message, *GetMap());
}
@ -1326,9 +1292,10 @@ void WorldObject::MonsterYell(int32 textId, uint32 language, uint64 TargetGuid)
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
MaNGOS::MessageChatLocaleCacheDo say_do(*this, CHAT_MSG_MONSTER_YELL, textId,language,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL));
MaNGOS::PlayerWorker<MaNGOS::MessageChatLocaleCacheDo> say_worker(this,say_do);
TypeContainerVisitor<MaNGOS::PlayerWorker<MaNGOS::MessageChatLocaleCacheDo>, WorldTypeMapContainer > message(say_worker);
MaNGOS::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_YELL, textId,language,TargetGuid);
MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> say_do(say_build);
MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL),say_do);
TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, message, *GetMap());
}
@ -1341,9 +1308,10 @@ void WorldObject::MonsterTextEmote(int32 textId, uint64 TargetGuid, bool IsBossE
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
MaNGOS::MessageChatLocaleCacheDo say_do(*this, IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, textId,LANG_UNIVERSAL,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
MaNGOS::PlayerWorker<MaNGOS::MessageChatLocaleCacheDo> say_worker(this,say_do);
TypeContainerVisitor<MaNGOS::PlayerWorker<MaNGOS::MessageChatLocaleCacheDo>, WorldTypeMapContainer > message(say_worker);
MaNGOS::MonsterChatBuilder say_build(*this, IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, textId,LANG_UNIVERSAL,TargetGuid);
MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> say_do(say_build);
MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),say_do);
TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, message, *GetMap());
}

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "7310"
#define REVISION_NR "7311"
#endif // __REVISION_NR_H__