mirror of
https://github.com/OpenMW/openmw.git
synced 2025-07-10 04:41:35 +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:
parent
68afac6a19
commit
996e49c534
3 changed files with 32 additions and 20 deletions
|
@ -1,7 +1,7 @@
|
||||||
#ifndef GAME_MWSTATE_STATEMANAGER_H
|
#ifndef GAME_MWSTATE_STATEMANAGER_H
|
||||||
#define GAME_MWSTATE_STATEMANAGER_H
|
#define GAME_MWSTATE_STATEMANAGER_H
|
||||||
|
|
||||||
#include <vector>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace MWState
|
namespace MWState
|
||||||
|
@ -24,7 +24,7 @@ namespace MWBase
|
||||||
State_Running
|
State_Running
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<MWState::Character>::const_iterator CharacterIterator;
|
typedef std::list<MWState::Character>::const_iterator CharacterIterator;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -49,20 +49,17 @@ MWState::Character *MWState::CharacterManager::getCurrentCharacter (bool create)
|
||||||
|
|
||||||
void MWState::CharacterManager::deleteSlot(const MWState::Character *character, const MWState::Slot *slot)
|
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()))
|
it->deleteSlot(slot);
|
||||||
throw std::logic_error ("invalid character");
|
|
||||||
|
|
||||||
mCharacters[index].deleteSlot(slot);
|
if (character->begin() == character->end())
|
||||||
|
|
||||||
if (mCharacters[index].begin() == mCharacters[index].end())
|
|
||||||
{
|
{
|
||||||
// All slots deleted, cleanup and remove this character
|
// All slots deleted, cleanup and remove this character
|
||||||
mCharacters[index].cleanup();
|
it->cleanup();
|
||||||
if (character == mCurrent)
|
if (character == mCurrent)
|
||||||
mCurrent = NULL;
|
mCurrent = NULL;
|
||||||
mCharacters.erase(mCharacters.begin() + index);
|
mCharacters.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,14 +75,24 @@ void MWState::CharacterManager::createCharacter()
|
||||||
mCurrent = &mCharacters.back();
|
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)
|
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()))
|
mCurrent = &*it;
|
||||||
throw std::logic_error ("invalid character");
|
|
||||||
|
|
||||||
mCurrent = &mCharacters[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWState::CharacterManager::clearCurrentCharacter()
|
void MWState::CharacterManager::clearCurrentCharacter()
|
||||||
|
@ -93,12 +100,12 @@ void MWState::CharacterManager::clearCurrentCharacter()
|
||||||
mCurrent = 0;
|
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();
|
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();
|
return mCharacters.end();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,10 @@ namespace MWState
|
||||||
{
|
{
|
||||||
boost::filesystem::path mPath;
|
boost::filesystem::path mPath;
|
||||||
int mNext;
|
int mNext;
|
||||||
std::vector<Character> mCharacters;
|
|
||||||
|
// Uses std::list, so that mCurrent stays valid when characters are deleted
|
||||||
|
std::list<Character> mCharacters;
|
||||||
|
|
||||||
Character *mCurrent;
|
Character *mCurrent;
|
||||||
std::string mGame;
|
std::string mGame;
|
||||||
|
|
||||||
|
@ -23,6 +26,8 @@ namespace MWState
|
||||||
CharacterManager& operator= (const CharacterManager&);
|
CharacterManager& operator= (const CharacterManager&);
|
||||||
///< Not implemented
|
///< Not implemented
|
||||||
|
|
||||||
|
std::list<Character>::iterator findCharacter(const MWState::Character* character);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CharacterManager (const boost::filesystem::path& saves, const std::string& game);
|
CharacterManager (const boost::filesystem::path& saves, const std::string& game);
|
||||||
|
@ -39,9 +44,9 @@ namespace MWState
|
||||||
|
|
||||||
void clearCurrentCharacter();
|
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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue