1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-03 13:19:40 +00:00

Change CharacterManager to use list instead of vector

Solves a crash when deleting all savegames of a character due to mCurrent being invalidated
This commit is contained in:
scrawl 2014-06-02 20:24:35 +02:00
parent 68afac6a19
commit 996e49c534
3 changed files with 32 additions and 20 deletions

View file

@ -1,7 +1,7 @@
#ifndef GAME_MWSTATE_STATEMANAGER_H
#define GAME_MWSTATE_STATEMANAGER_H
#include <vector>
#include <list>
#include <string>
namespace MWState
@ -24,7 +24,7 @@ namespace MWBase
State_Running
};
typedef std::vector<MWState::Character>::const_iterator CharacterIterator;
typedef std::list<MWState::Character>::const_iterator CharacterIterator;
private:

View file

@ -49,20 +49,17 @@ MWState::Character *MWState::CharacterManager::getCurrentCharacter (bool create)
void MWState::CharacterManager::deleteSlot(const MWState::Character *character, const MWState::Slot *slot)
{
int index = character - &mCharacters[0];
std::list<Character>::iterator it = findCharacter(character);
if (index<0 || index>=static_cast<int> (mCharacters.size()))
throw std::logic_error ("invalid character");
it->deleteSlot(slot);
mCharacters[index].deleteSlot(slot);
if (mCharacters[index].begin() == mCharacters[index].end())
if (character->begin() == character->end())
{
// All slots deleted, cleanup and remove this character
mCharacters[index].cleanup();
it->cleanup();
if (character == mCurrent)
mCurrent = NULL;
mCharacters.erase(mCharacters.begin() + index);
mCharacters.erase(it);
}
}
@ -78,14 +75,24 @@ void MWState::CharacterManager::createCharacter()
mCurrent = &mCharacters.back();
}
std::list<MWState::Character>::iterator MWState::CharacterManager::findCharacter(const MWState::Character* character)
{
std::list<Character>::iterator it = mCharacters.begin();
for (; it != mCharacters.end(); ++it)
{
if (&*it == character)
break;
}
if (it == mCharacters.end())
throw std::logic_error ("invalid character");
return it;
}
void MWState::CharacterManager::setCurrentCharacter (const Character *character)
{
int index = character - &mCharacters[0];
std::list<Character>::iterator it = findCharacter(character);
if (index<0 || index>=static_cast<int> (mCharacters.size()))
throw std::logic_error ("invalid character");
mCurrent = &mCharacters[index];
mCurrent = &*it;
}
void MWState::CharacterManager::clearCurrentCharacter()
@ -93,12 +100,12 @@ void MWState::CharacterManager::clearCurrentCharacter()
mCurrent = 0;
}
std::vector<MWState::Character>::const_iterator MWState::CharacterManager::begin() const
std::list<MWState::Character>::const_iterator MWState::CharacterManager::begin() const
{
return mCharacters.begin();
}
std::vector<MWState::Character>::const_iterator MWState::CharacterManager::end() const
std::list<MWState::Character>::const_iterator MWState::CharacterManager::end() const
{
return mCharacters.end();
}

View file

@ -11,7 +11,10 @@ namespace MWState
{
boost::filesystem::path mPath;
int mNext;
std::vector<Character> mCharacters;
// Uses std::list, so that mCurrent stays valid when characters are deleted
std::list<Character> mCharacters;
Character *mCurrent;
std::string mGame;
@ -23,6 +26,8 @@ namespace MWState
CharacterManager& operator= (const CharacterManager&);
///< Not implemented
std::list<Character>::iterator findCharacter(const MWState::Character* character);
public:
CharacterManager (const boost::filesystem::path& saves, const std::string& game);
@ -39,9 +44,9 @@ namespace MWState
void clearCurrentCharacter();
std::vector<Character>::const_iterator begin() const;
std::list<Character>::const_iterator begin() const;
std::vector<Character>::const_iterator end() const;
std::list<Character>::const_iterator end() const;
};
}