[9479] Use Clear call in MotionMaster::Initilize

Function can be called from deep code in time MotionMaster::Update.
So need use safe way cleanup with possible delayed movegens deletion.

Signed-off-by: VladimirMangos <vladimir@getmangos.com>
This commit is contained in:
Quriq14 2010-02-28 09:39:31 +03:00 committed by VladimirMangos
parent e05f4b1b03
commit bf7616138b
3 changed files with 42 additions and 57 deletions

View file

@ -40,20 +40,13 @@ void
MotionMaster::Initialize() MotionMaster::Initialize()
{ {
// clear ALL movement generators (including default) // clear ALL movement generators (including default)
while(!empty()) Clear(false,true);
{
MovementGenerator *curr = top();
pop();
curr->Finalize(*i_owner);
if( !isStatic( curr ) )
delete curr;
}
// set new default movement generator // set new default movement generator
if(i_owner->GetTypeId() == TYPEID_UNIT) if (i_owner->GetTypeId() == TYPEID_UNIT)
{ {
MovementGenerator* movement = FactorySelector::selectMovementGenerator((Creature*)i_owner); MovementGenerator* movement = FactorySelector::selectMovementGenerator((Creature*)i_owner);
push( movement == NULL ? &si_idleMovement : movement ); push(movement == NULL ? &si_idleMovement : movement);
top()->Initialize(*i_owner); top()->Initialize(*i_owner);
} }
else else
@ -63,14 +56,7 @@ MotionMaster::Initialize()
MotionMaster::~MotionMaster() MotionMaster::~MotionMaster()
{ {
// clear ALL movement generators (including default) // clear ALL movement generators (including default)
while(!empty()) DirectClean(false,true);
{
MovementGenerator *curr = top();
pop();
curr->Finalize(*i_owner);
if( !isStatic( curr ) )
delete curr;
}
} }
void void
@ -112,18 +98,18 @@ MotionMaster::UpdateMotion(uint32 diff)
} }
void void
MotionMaster::DirectClean(bool reset) MotionMaster::DirectClean(bool reset, bool all)
{ {
while( !empty() && size() > 1 ) while( all ? !empty() : size() > 1 )
{ {
MovementGenerator *curr = top(); MovementGenerator *curr = top();
pop(); pop();
curr->Finalize(*i_owner); curr->Finalize(*i_owner);
if( !isStatic( curr ) ) if (!isStatic( curr ))
delete curr; delete curr;
} }
if (reset) if (!all && reset)
{ {
assert( !empty() ); assert( !empty() );
top()->Reset(*i_owner); top()->Reset(*i_owner);
@ -131,20 +117,25 @@ MotionMaster::DirectClean(bool reset)
} }
void void
MotionMaster::DelayedClean() MotionMaster::DelayedClean(bool reset, bool all)
{ {
if (empty() || size() == 1) if(reset)
m_cleanFlag |= MMCF_RESET;
else
m_cleanFlag &= ~MMCF_RESET;
if (empty() || !all && size() == 1)
return; return;
if(!m_expList) if (!m_expList)
m_expList = new ExpireList(); m_expList = new ExpireList();
while( !empty() && size() > 1 ) while( all ? !empty() : size() > 1 )
{ {
MovementGenerator *curr = top(); MovementGenerator *curr = top();
pop(); pop();
curr->Finalize(*i_owner); curr->Finalize(*i_owner);
if( !isStatic( curr ) ) if (!isStatic( curr ))
m_expList->push_back(curr); m_expList->push_back(curr);
} }
} }
@ -152,7 +143,7 @@ MotionMaster::DelayedClean()
void void
MotionMaster::DirectExpire(bool reset) MotionMaster::DirectExpire(bool reset)
{ {
if( empty() || size() == 1 ) if (empty() || size() == 1)
return; return;
MovementGenerator *curr = top(); MovementGenerator *curr = top();
@ -170,25 +161,31 @@ MotionMaster::DirectExpire(bool reset)
// it can add another motions instead // it can add another motions instead
curr->Finalize(*i_owner); curr->Finalize(*i_owner);
if( !isStatic(curr) ) if (!isStatic(curr))
delete curr; delete curr;
if( empty() ) if (empty())
Initialize(); Initialize();
if (reset) top()->Reset(*i_owner); if (reset)
top()->Reset(*i_owner);
} }
void void
MotionMaster::DelayedExpire() MotionMaster::DelayedExpire(bool reset)
{ {
if( empty() || size() == 1 ) if (reset)
m_cleanFlag |= MMCF_RESET;
else
m_cleanFlag &= ~MMCF_RESET;
if (empty() || size() == 1)
return; return;
MovementGenerator *curr = top(); MovementGenerator *curr = top();
pop(); pop();
if(!m_expList) if (!m_expList)
m_expList = new ExpireList(); m_expList = new ExpireList();
// also drop stored under top() targeted motions // also drop stored under top() targeted motions
@ -202,14 +199,14 @@ MotionMaster::DelayedExpire()
curr->Finalize(*i_owner); curr->Finalize(*i_owner);
if( !isStatic(curr) ) if (!isStatic(curr))
m_expList->push_back(curr); m_expList->push_back(curr);
} }
void MotionMaster::MoveIdle() void MotionMaster::MoveIdle()
{ {
if( empty() || !isStatic( top() ) ) if (empty() || !isStatic(top()))
push( &si_idleMovement ); push(&si_idleMovement);
} }
void void

View file

@ -79,29 +79,17 @@ class MANGOS_DLL_SPEC MotionMaster : private std::stack<MovementGenerator *>
const_iterator end() const { return Impl::c.end(); } const_iterator end() const { return Impl::c.end(); }
void UpdateMotion(uint32 diff); void UpdateMotion(uint32 diff);
void Clear(bool reset = true) void Clear(bool reset = true, bool all = false)
{ {
if (m_cleanFlag & MMCF_UPDATE) if (m_cleanFlag & MMCF_UPDATE)
{ DelayedClean(reset, all);
if(reset)
m_cleanFlag |= MMCF_RESET;
else
m_cleanFlag &= ~MMCF_RESET;
DelayedClean();
}
else else
DirectClean(reset); DirectClean(reset, all);
} }
void MovementExpired(bool reset = true) void MovementExpired(bool reset = true)
{ {
if (m_cleanFlag & MMCF_UPDATE) if (m_cleanFlag & MMCF_UPDATE)
{ DelayedExpire(reset);
if(reset)
m_cleanFlag |= MMCF_RESET;
else
m_cleanFlag &= ~MMCF_RESET;
DelayedExpire();
}
else else
DirectExpire(reset); DirectExpire(reset);
} }
@ -129,11 +117,11 @@ class MANGOS_DLL_SPEC MotionMaster : private std::stack<MovementGenerator *>
private: private:
void Mutate(MovementGenerator *m); // use Move* functions instead void Mutate(MovementGenerator *m); // use Move* functions instead
void DirectClean(bool reset); void DirectClean(bool reset, bool all);
void DelayedClean(); void DelayedClean(bool reset, bool all);
void DirectExpire(bool reset); void DirectExpire(bool reset);
void DelayedExpire(); void DelayedExpire(bool reset);
Unit *i_owner; Unit *i_owner;
ExpireList *m_expList; ExpireList *m_expList;

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 "9478" #define REVISION_NR "9479"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__