[10914] Remove ObjectLevelLockable inheritance in Map class + cleanup locks in Map code. Restore build after recent commits.

Signed-off-by: Ambal <pogrebniak@gala.net>
This commit is contained in:
Ambal 2010-12-24 01:22:04 +02:00
parent 8f37314950
commit f56e13966f
4 changed files with 124 additions and 133 deletions

View file

@ -31,7 +31,6 @@
#include "ObjectMgr.h" #include "ObjectMgr.h"
#include "World.h" #include "World.h"
#include "ScriptCalls.h" #include "ScriptCalls.h"
#include "ScriptMgr.h"
#include "Group.h" #include "Group.h"
#include "MapRefManager.h" #include "MapRefManager.h"
#include "DBCEnums.h" #include "DBCEnums.h"
@ -39,14 +38,6 @@
#include "VMapFactory.h" #include "VMapFactory.h"
#include "BattleGroundMgr.h" #include "BattleGroundMgr.h"
struct ScriptAction
{
ObjectGuid sourceGuid;
ObjectGuid targetGuid;
ObjectGuid ownerGuid; // owner of source if source is item
ScriptInfo const* script; // pointer to static script data
};
Map::~Map() Map::~Map()
{ {
ObjectAccessor::DelinkMap(this); ObjectAccessor::DelinkMap(this);
@ -227,24 +218,20 @@ Map::EnsureGridCreated(const GridPair &p)
{ {
if(!getNGrid(p.x_coord, p.y_coord)) if(!getNGrid(p.x_coord, p.y_coord))
{ {
Guard guard(*this); setNGrid(new NGridType(p.x_coord*MAX_NUMBER_OF_GRIDS + p.y_coord, p.x_coord, p.y_coord, i_gridExpiry, sWorld.getConfig(CONFIG_BOOL_GRID_UNLOAD)),
if(!getNGrid(p.x_coord, p.y_coord)) p.x_coord, p.y_coord);
{
setNGrid(new NGridType(p.x_coord*MAX_NUMBER_OF_GRIDS + p.y_coord, p.x_coord, p.y_coord, i_gridExpiry, sWorld.getConfig(CONFIG_BOOL_GRID_UNLOAD)),
p.x_coord, p.y_coord);
// build a linkage between this map and NGridType // build a linkage between this map and NGridType
buildNGridLinkage(getNGrid(p.x_coord, p.y_coord)); buildNGridLinkage(getNGrid(p.x_coord, p.y_coord));
getNGrid(p.x_coord, p.y_coord)->SetGridState(GRID_STATE_IDLE); getNGrid(p.x_coord, p.y_coord)->SetGridState(GRID_STATE_IDLE);
//z coord //z coord
int gx = (MAX_NUMBER_OF_GRIDS - 1) - p.x_coord; int gx = (MAX_NUMBER_OF_GRIDS - 1) - p.x_coord;
int gy = (MAX_NUMBER_OF_GRIDS - 1) - p.y_coord; int gy = (MAX_NUMBER_OF_GRIDS - 1) - p.y_coord;
if(!m_bLoadedGrids[gx][gy]) if(!m_bLoadedGrids[gx][gy])
LoadMapAndVMap(gx,gy); LoadMapAndVMap(gx,gy);
}
} }
} }
@ -1319,118 +1306,115 @@ bool InstanceMap::Add(Player *player)
// GMs still can teleport player in instance. // GMs still can teleport player in instance.
// Is it needed? // Is it needed?
{ if (!CanEnter(player))
Guard guard(*this); return false;
if (!CanEnter(player))
return false;
// Dungeon only code // Dungeon only code
if (IsDungeon()) if (IsDungeon())
{
// check for existing instance binds
InstancePlayerBind *playerBind = player->GetBoundInstance(GetId(), GetDifficulty());
if (playerBind && playerBind->perm)
{ {
// check for existing instance binds // cannot enter other instances if bound permanently
InstancePlayerBind *playerBind = player->GetBoundInstance(GetId(), GetDifficulty()); if (playerBind->save != GetInstanceSave())
if (playerBind && playerBind->perm)
{ {
// cannot enter other instances if bound permanently sLog.outError("InstanceMap::Add: player %s(%d) is permanently bound to instance %d,%d,%d,%d,%d,%d but he is being put in instance %d,%d,%d,%d,%d,%d",
if (playerBind->save != GetInstanceSave()) player->GetName(), player->GetGUIDLow(), playerBind->save->GetMapId(),
playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(),
playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(),
playerBind->save->CanReset(),
GetInstanceSave()->GetMapId(), GetInstanceSave()->GetInstanceId(),
GetInstanceSave()->GetDifficulty(), GetInstanceSave()->GetPlayerCount(),
GetInstanceSave()->GetGroupCount(), GetInstanceSave()->CanReset());
MANGOS_ASSERT(false);
}
}
else
{
Group *pGroup = player->GetGroup();
if (pGroup)
{
// solo saves should be reset when entering a group
InstanceGroupBind *groupBind = pGroup->GetBoundInstance(this,GetDifficulty());
if (playerBind)
{ {
sLog.outError("InstanceMap::Add: player %s(%d) is permanently bound to instance %d,%d,%d,%d,%d,%d but he is being put in instance %d,%d,%d,%d,%d,%d", sLog.outError("InstanceMap::Add: %s is being put in instance %d,%d,%d,%d,%d,%d but he is in group (Id: %d) and is bound to instance %d,%d,%d,%d,%d,%d!",
player->GetName(), player->GetGUIDLow(), playerBind->save->GetMapId(), player->GetGuidStr().c_str(), GetInstanceSave()->GetMapId(), GetInstanceSave()->GetInstanceId(),
playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), GetInstanceSave()->GetDifficulty(), GetInstanceSave()->GetPlayerCount(), GetInstanceSave()->GetGroupCount(),
playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), GetInstanceSave()->CanReset(), pGroup->GetId(),
playerBind->save->CanReset(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(),
GetInstanceSave()->GetMapId(), GetInstanceSave()->GetInstanceId(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset());
GetInstanceSave()->GetDifficulty(), GetInstanceSave()->GetPlayerCount(),
GetInstanceSave()->GetGroupCount(), GetInstanceSave()->CanReset()); if (groupBind)
MANGOS_ASSERT(false); sLog.outError("InstanceMap::Add: the group (Id: %d) is bound to instance %d,%d,%d,%d,%d,%d",
pGroup->GetId(),
groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty(),
groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount(), groupBind->save->CanReset());
// no reason crash if we can fix state
player->UnbindInstance(GetId(), GetDifficulty());
}
// bind to the group or keep using the group save
if (!groupBind)
pGroup->BindToInstance(GetInstanceSave(), false);
else
{
// cannot jump to a different instance without resetting it
if (groupBind->save != GetInstanceSave())
{
sLog.outError("InstanceMap::Add: %s is being put in instance %d,%d,%d but he is in group (Id: %d) which is bound to instance %d,%d,%d!",
player->GetGuidStr().c_str(), GetInstanceSave()->GetMapId(),
GetInstanceSave()->GetInstanceId(), GetInstanceSave()->GetDifficulty(),
pGroup->GetId(), groupBind->save->GetMapId(),
groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty());
if (GetInstanceSave())
sLog.outError("MapSave players: %d, group count: %d",
GetInstanceSave()->GetPlayerCount(), GetInstanceSave()->GetGroupCount());
else
sLog.outError("MapSave NULL");
if (groupBind->save)
sLog.outError("GroupBind save players: %d, group count: %d", groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount());
else
sLog.outError("GroupBind save NULL");
MANGOS_ASSERT(false);
}
// if the group/leader is permanently bound to the instance
// players also become permanently bound when they enter
if (groupBind->perm)
{
WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4);
data << uint32(0);
player->GetSession()->SendPacket(&data);
player->BindToInstance(GetInstanceSave(), true);
}
} }
} }
else else
{ {
Group *pGroup = player->GetGroup(); // set up a solo bind or continue using it
if (pGroup) if(!playerBind)
{ player->BindToInstance(GetInstanceSave(), false);
// solo saves should be reset when entering a group
InstanceGroupBind *groupBind = pGroup->GetBoundInstance(this,GetDifficulty());
if (playerBind)
{
sLog.outError("InstanceMap::Add: %s is being put in instance %d,%d,%d,%d,%d,%d but he is in group (Id: %d) and is bound to instance %d,%d,%d,%d,%d,%d!",
player->GetGuidStr().c_str(), GetInstanceSave()->GetMapId(), GetInstanceSave()->GetInstanceId(),
GetInstanceSave()->GetDifficulty(), GetInstanceSave()->GetPlayerCount(), GetInstanceSave()->GetGroupCount(),
GetInstanceSave()->CanReset(), pGroup->GetId(),
playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(),
playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset());
if (groupBind)
sLog.outError("InstanceMap::Add: the group (Id: %d) is bound to instance %d,%d,%d,%d,%d,%d",
pGroup->GetId(),
groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty(),
groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount(), groupBind->save->CanReset());
// no reason crash if we can fix state
player->UnbindInstance(GetId(), GetDifficulty());
}
// bind to the group or keep using the group save
if (!groupBind)
pGroup->BindToInstance(GetInstanceSave(), false);
else
{
// cannot jump to a different instance without resetting it
if (groupBind->save != GetInstanceSave())
{
sLog.outError("InstanceMap::Add: %s is being put in instance %d,%d,%d but he is in group (Id: %d) which is bound to instance %d,%d,%d!",
player->GetGuidStr().c_str(), GetInstanceSave()->GetMapId(),
GetInstanceSave()->GetInstanceId(), GetInstanceSave()->GetDifficulty(),
pGroup->GetId(), groupBind->save->GetMapId(),
groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty());
if (GetInstanceSave())
sLog.outError("MapSave players: %d, group count: %d",
GetInstanceSave()->GetPlayerCount(), GetInstanceSave()->GetGroupCount());
else
sLog.outError("MapSave NULL");
if (groupBind->save)
sLog.outError("GroupBind save players: %d, group count: %d", groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount());
else
sLog.outError("GroupBind save NULL");
MANGOS_ASSERT(false);
}
// if the group/leader is permanently bound to the instance
// players also become permanently bound when they enter
if (groupBind->perm)
{
WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4);
data << uint32(0);
player->GetSession()->SendPacket(&data);
player->BindToInstance(GetInstanceSave(), true);
}
}
}
else else
{ // cannot jump to a different instance without resetting it
// set up a solo bind or continue using it MANGOS_ASSERT(playerBind->save == GetInstanceSave());
if(!playerBind)
player->BindToInstance(GetInstanceSave(), false);
else
// cannot jump to a different instance without resetting it
MANGOS_ASSERT(playerBind->save == GetInstanceSave());
}
} }
} }
// for normal instances cancel the reset schedule when the
// first player enters (no players yet)
SetResetSchedule(false);
DETAIL_LOG("MAP: Player '%s' is entering instance '%u' of map '%s'", player->GetName(), GetInstanceId(), GetMapName());
// initialize unload state
m_unloadTimer = 0;
m_resetAfterUnload = false;
m_unloadWhenEmpty = false;
} }
// for normal instances cancel the reset schedule when the
// first player enters (no players yet)
SetResetSchedule(false);
DETAIL_LOG("MAP: Player '%s' is entering instance '%u' of map '%s'", player->GetName(), GetInstanceId(), GetMapName());
// initialize unload state
m_unloadTimer = 0;
m_resetAfterUnload = false;
m_unloadWhenEmpty = false;
// this will acquire the same mutex so it cannot be in the previous block // this will acquire the same mutex so it cannot be in the previous block
Map::Add(player); Map::Add(player);
@ -1649,13 +1633,12 @@ bool BattleGroundMap::CanEnter(Player * player)
bool BattleGroundMap::Add(Player * player) bool BattleGroundMap::Add(Player * player)
{ {
{ if(!CanEnter(player))
Guard guard(*this); return false;
if(!CanEnter(player))
return false; // reset instance validity, battleground maps do not homebind
// reset instance validity, battleground maps do not homebind player->m_InstanceValid = true;
player->m_InstanceValid = true;
}
return Map::Add(player); return Map::Add(player);
} }

View file

@ -35,6 +35,7 @@
#include "GameSystem/GridRefManager.h" #include "GameSystem/GridRefManager.h"
#include "MapRefManager.h" #include "MapRefManager.h"
#include "Utilities/TypeList.h" #include "Utilities/TypeList.h"
#include "ScriptMgr.h"
#include <bitset> #include <bitset>
#include <list> #include <list>
@ -46,7 +47,6 @@ class InstanceData;
class Group; class Group;
class InstanceSave; class InstanceSave;
struct ScriptInfo; struct ScriptInfo;
struct ScriptAction;
class BattleGround; class BattleGround;
class GridMap; class GridMap;
@ -80,7 +80,7 @@ enum LevelRequirementVsMode
#define MIN_UNLOAD_DELAY 1 // immediate unload #define MIN_UNLOAD_DELAY 1 // immediate unload
class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::ObjectLevelLockable<Map, ACE_Thread_Mutex> class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>
{ {
friend class MapReference; friend class MapReference;
friend class ObjectGridLoader; friend class ObjectGridLoader;
@ -276,7 +276,6 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
void SendObjectUpdates(); void SendObjectUpdates();
std::set<Object *> i_objectsToClientUpdate; std::set<Object *> i_objectsToClientUpdate;
protected: protected:
typedef MaNGOS::ObjectLevelLockable<Map, ACE_Thread_Mutex>::Lock Guard;
MapEntry const* i_mapEntry; MapEntry const* i_mapEntry;
uint8 i_spawnMode; uint8 i_spawnMode;

View file

@ -21,6 +21,7 @@
#include "Common.h" #include "Common.h"
#include "Policies/Singleton.h" #include "Policies/Singleton.h"
#include "ObjectGuid.h"
enum eScriptCommand enum eScriptCommand
{ {
@ -269,6 +270,14 @@ struct ScriptInfo
} }
}; };
struct ScriptAction
{
ObjectGuid sourceGuid;
ObjectGuid targetGuid;
ObjectGuid ownerGuid; // owner of source if source is item
ScriptInfo const* script; // pointer to static script data
};
typedef std::multimap<uint32, ScriptInfo> ScriptMap; typedef std::multimap<uint32, ScriptInfo> ScriptMap;
typedef std::map<uint32, ScriptMap > ScriptMapMap; typedef std::map<uint32, ScriptMap > ScriptMapMap;
extern ScriptMapMap sQuestEndScripts; extern ScriptMapMap sQuestEndScripts;

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "10913" #define REVISION_NR "10914"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__