Merge branch 'master' into 303

This commit is contained in:
tomrus88 2008-11-28 18:15:12 +03:00
commit a4b8862803
6 changed files with 58 additions and 15 deletions

View file

@ -44,6 +44,11 @@ class LinkedListElement
LinkedListElement * prev() { return hasPrev() ? iPrev : NULL; }
LinkedListElement const* prev() const { return hasPrev() ? iPrev : NULL; }
LinkedListElement * nocheck_next() { return iNext; }
LinkedListElement const* nocheck_next() const { return iNext; }
LinkedListElement * nocheck_prev() { return iPrev; }
LinkedListElement const* nocheck_prev() const { return iPrev; }
void delink()
{
if(isInList())
@ -134,7 +139,10 @@ class LinkedListHead
typedef ptrdiff_t difference_type;
typedef ptrdiff_t distance_type;
typedef _Ty* pointer;
typedef _Ty const* const_pointer;
typedef _Ty& reference;
typedef _Ty const & const_reference;
Iterator() : _Ptr(0)
{ // construct with null node pointer
@ -144,6 +152,17 @@ class LinkedListHead
{ // construct with node pointer _Pnode
}
Iterator& operator=(Iterator const &_Right)
{
return (*this) = _Right._Ptr;
}
Iterator& operator=(const_pointer const &_Right)
{
_Ptr = (pointer)_Right;
return (*this);
}
reference operator*()
{ // return designated value
return *_Ptr;
@ -200,6 +219,17 @@ class LinkedListHead
return (!(*this == _Right));
}
bool operator==(const_reference _Right) const
{ // test for reference equality
return (_Ptr == &_Right);
}
bool operator!=(const_reference _Right) const
{ // test for reference equality
return (_Ptr != &_Right);
}
pointer _Mynode()
{ // return node pointer
return (_Ptr);

View file

@ -71,9 +71,15 @@ template <class TO, class FROM> class Reference : public LinkedListElement
return iRefTo != NULL;
}
Reference<TO,FROM>* next() { return((Reference<TO,FROM>*)LinkedListElement::next()); }
Reference<TO,FROM>const* next() const { return((Reference<TO,FROM> const*)LinkedListElement::next()); }
Reference<TO,FROM>* prev() { return((Reference<TO,FROM>*)LinkedListElement::prev()); }
Reference<TO,FROM> * next() { return((Reference<TO,FROM> *) LinkedListElement::next()); }
Reference<TO,FROM> const * next() const { return((Reference<TO,FROM> const *) LinkedListElement::next()); }
Reference<TO,FROM> * prev() { return((Reference<TO,FROM> *) LinkedListElement::prev()); }
Reference<TO,FROM> const * prev() const { return((Reference<TO,FROM> const *) LinkedListElement::prev()); }
Reference<TO,FROM> * nocheck_next() { return((Reference<TO,FROM> *) LinkedListElement::nocheck_next()); }
Reference<TO,FROM> const * nocheck_next() const { return((Reference<TO,FROM> const *) LinkedListElement::nocheck_next()); }
Reference<TO,FROM> * nocheck_prev() { return((Reference<TO,FROM> *) LinkedListElement::nocheck_prev()); }
Reference<TO,FROM> const * nocheck_prev() const { return((Reference<TO,FROM> const *) LinkedListElement::nocheck_prev()); }
inline TO* operator ->() const { return iRefTo; }
inline TO* getTarget() const { return iRefTo; }

View file

@ -573,21 +573,15 @@ void Map::Update(const uint32 &t_diff)
// for pets
TypeContainerVisitor<MaNGOS::ObjectUpdater, WorldTypeMapContainer > world_object_update(updater);
//TODO: Player guard
HashMapHolder<Player>::MapType& playerMap = HashMapHolder<Player>::GetContainer();
for(HashMapHolder<Player>::MapType::iterator iter = playerMap.begin(); iter != playerMap.end(); ++iter)
// the player iterator is stored in the map object
// to make sure calls to Map::Remove don't invalidate it
for(m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); ++m_mapRefIter)
{
Player* plr = iter->second;
Player* plr = m_mapRefIter->getSource();
if(!plr->IsInWorld())
continue;
if(plr->GetMapId() != GetId())
continue;
if(plr->GetInstanceId() != GetInstanceId())
continue;
CellPair standing_cell(MaNGOS::ComputeCellPair(plr->GetPositionX(), plr->GetPositionY()));
// Check for correctness of standing_cell, it also avoids problems with update_cell
@ -639,6 +633,13 @@ void Map::Update(const uint32 &t_diff)
void Map::Remove(Player *player, bool remove)
{
// this may be called during Map::Update
// after decrement+unlink, ++m_mapRefIter will continue correctly
// when the first element of the list is being removed
// nocheck_prev will return the padding element of the RefManager
// instead of NULL in the case of prev
if(m_mapRefIter == player->GetMapRef())
m_mapRefIter = m_mapRefIter->nocheck_prev();
player->GetMapRef().unlink();
CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
@ -1623,6 +1624,8 @@ bool InstanceMap::Add(Player *player)
}
if(i_data) i_data->OnPlayerEnter(player);
// for normal instances cancel the reset schedule when the
// first player enters (no players yet)
SetResetSchedule(false);
player->SendInitWorldStates();
@ -1649,11 +1652,12 @@ void InstanceMap::Update(const uint32& t_diff)
void InstanceMap::Remove(Player *player, bool remove)
{
sLog.outDetail("MAP: Removing player '%s' from instance '%u' of map '%s' before relocating to other map", player->GetName(), GetInstanceId(), GetMapName());
SetResetSchedule(true);
//if last player set unload timer
if(!m_unloadTimer && m_mapRefManager.getSize() == 1)
m_unloadTimer = m_unloadWhenEmpty ? MIN_UNLOAD_DELAY : std::max(sWorld.getConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY);
Map::Remove(player, remove);
// for normal instances schedule the reset after all players have left
SetResetSchedule(true);
}
void InstanceMap::CreateInstanceData(bool load)

View file

@ -303,6 +303,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
uint32 m_unloadTimer;
MapRefManager m_mapRefManager;
MapRefManager::iterator m_mapRefIter;
private:
typedef GridReadGuard ReadGuard;
typedef GridWriteGuard WriteGuard;

View file

@ -46,5 +46,7 @@ class MANGOS_DLL_SPEC MapReference : public Reference<Map, Player>
~MapReference() { unlink(); }
MapReference *next() { return (MapReference*)Reference<Map, Player>::next(); }
MapReference const *next() const { return (MapReference const*)Reference<Map, Player>::next(); }
MapReference *nockeck_prev() { return (MapReference*)Reference<Map, Player>::nocheck_prev(); }
MapReference const *nocheck_prev() const { return (MapReference const*)Reference<Map, Player>::nocheck_prev(); }
};
#endif

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "6854"
#define REVISION_NR "6856"
#endif // __REVISION_NR_H__