Skip to content

Commit

Permalink
Merge pull request #202 from vcmi/noncopyableBonusSystemNode2
Browse files Browse the repository at this point in the history
Didn't manage to find any crashes in newly created games. Merging.

Keep in mind that even if most of old saves will load properly some of them still corrupted beyond repair and after some turns they might eventually crash.
  • Loading branch information
ArseniyShestakov committed Sep 4, 2016
2 parents 5fc1fd4 + 69395d4 commit f4f170b
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 50 deletions.
43 changes: 36 additions & 7 deletions lib/CGameState.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -1080,13 +1080,14 @@ void CGameState::initPlayerStates()
logGlobal->debug("\tCreating player entries in gs"); logGlobal->debug("\tCreating player entries in gs");
for(auto & elem : scenarioOps->playerInfos) for(auto & elem : scenarioOps->playerInfos)
{ {
std::pair<PlayerColor, PlayerState> ins(elem.first,PlayerState()); PlayerState & p = players[elem.first];
ins.second.color=ins.first; //std::pair<PlayerColor, PlayerState> ins(elem.first,PlayerState());
ins.second.human = elem.second.playerID; p.color=elem.first;
ins.second.team = map->players[ins.first.getNum()].team; p.human = elem.second.playerID;
teams[ins.second.team].id = ins.second.team;//init team p.team = map->players[elem.first.getNum()].team;
teams[ins.second.team].players.insert(ins.first);//add player to team teams[p.team].id = p.team;//init team
players.insert(ins); teams[p.team].players.insert(elem.first);//add player to team
//players.insert(ins);
} }
} }


Expand Down Expand Up @@ -2936,6 +2937,25 @@ PlayerState::PlayerState()
setNodeType(PLAYER); setNodeType(PLAYER);
} }


PlayerState::PlayerState(PlayerState && other):
CBonusSystemNode(std::move(other)),
color(other.color),
human(other.human),
team(other.team),
resources(other.resources),
enteredWinningCheatCode(other.enteredWinningCheatCode),
enteredLosingCheatCode(other.enteredLosingCheatCode),
status(other.status),
daysWithoutCastle(other.daysWithoutCastle)
{
std::swap(visitedObjects, other.visitedObjects);
std::swap(heroes, other.heroes);
std::swap(towns, other.towns);
std::swap(availableHeroes, other.availableHeroes);
std::swap(dwellings, other.dwellings);
std::swap(quests, other.quests);
}

std::string PlayerState::nodeName() const std::string PlayerState::nodeName() const
{ {
return "Player " + (color.getNum() < VLC->generaltexth->capColors.size() ? VLC->generaltexth->capColors[color.getNum()] : boost::lexical_cast<std::string>(color)); return "Player " + (color.getNum() < VLC->generaltexth->capColors.size() ? VLC->generaltexth->capColors[color.getNum()] : boost::lexical_cast<std::string>(color));
Expand Down Expand Up @@ -3235,6 +3255,15 @@ TeamState::TeamState()
setNodeType(TEAM); setNodeType(TEAM);
} }


TeamState::TeamState(TeamState && other):
CBonusSystemNode(std::move(other)),
id(other.id)
{
std::swap(players, other.players);
std::swap(fogOfWarMap, other.fogOfWarMap);
}


CRandomGenerator & CGameState::getRandomGenerator() CRandomGenerator & CGameState::getRandomGenerator()
{ {
//logGlobal->traceStream() << "Fetching CGameState::rand with seed " << rand.nextInt(); //logGlobal->traceStream() << "Fetching CGameState::rand with seed " << rand.nextInt();
Expand Down
3 changes: 3 additions & 0 deletions lib/CPlayerState.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ struct DLL_LINKAGE PlayerState : public CBonusSystemNode
boost::optional<ui8> daysWithoutCastle; boost::optional<ui8> daysWithoutCastle;


PlayerState(); PlayerState();
PlayerState(PlayerState && other);

std::string nodeName() const override; std::string nodeName() const override;


template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
Expand All @@ -56,6 +58,7 @@ struct DLL_LINKAGE TeamState : public CBonusSystemNode
std::vector<std::vector<std::vector<ui8> > > fogOfWarMap; //true - visible, false - hidden std::vector<std::vector<std::vector<ui8> > > fogOfWarMap; //true - visible, false - hidden


TeamState(); TeamState();
TeamState(TeamState && other);


template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
Expand Down
66 changes: 49 additions & 17 deletions lib/HeroBonus.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -96,6 +96,13 @@ BonusList::BonusList(const BonusList &bonusList)
belongsToTree = false; belongsToTree = false;
} }


BonusList::BonusList(BonusList&& other):
belongsToTree(false)
{
std::swap(belongsToTree, other.belongsToTree);
std::swap(bonuses, other.bonuses);
}

BonusList& BonusList::operator=(const BonusList &bonusList) BonusList& BonusList::operator=(const BonusList &bonusList)
{ {
bonuses.resize(bonusList.size()); bonuses.resize(bonusList.size());
Expand All @@ -104,6 +111,12 @@ BonusList& BonusList::operator=(const BonusList &bonusList)
return *this; return *this;
} }


void BonusList::changed()
{
if(belongsToTree)
CBonusSystemNode::treeHasChanged();
}

int BonusList::totalValue() const int BonusList::totalValue() const
{ {
int base = 0; int base = 0;
Expand Down Expand Up @@ -257,24 +270,19 @@ void BonusList::eliminateDuplicates()
void BonusList::push_back(Bonus* const &x) void BonusList::push_back(Bonus* const &x)
{ {
bonuses.push_back(x); bonuses.push_back(x);

changed();
if (belongsToTree)
CBonusSystemNode::treeHasChanged();
} }


std::vector<Bonus*>::iterator BonusList::erase(const int position) std::vector<Bonus*>::iterator BonusList::erase(const int position)
{ {
if (belongsToTree) changed();
CBonusSystemNode::treeHasChanged();
return bonuses.erase(bonuses.begin() + position); return bonuses.erase(bonuses.begin() + position);
} }


void BonusList::clear() void BonusList::clear()
{ {
bonuses.clear(); bonuses.clear();

changed();
if (belongsToTree)
CBonusSystemNode::treeHasChanged();
} }


std::vector<BonusList*>::size_type BonusList::operator-=(Bonus* const &i) std::vector<BonusList*>::size_type BonusList::operator-=(Bonus* const &i)
Expand All @@ -283,26 +291,20 @@ std::vector<BonusList*>::size_type BonusList::operator-=(Bonus* const &i)
if(itr == bonuses.end()) if(itr == bonuses.end())
return false; return false;
bonuses.erase(itr); bonuses.erase(itr);

changed();
if (belongsToTree)
CBonusSystemNode::treeHasChanged();
return true; return true;
} }


void BonusList::resize(std::vector<Bonus*>::size_type sz, Bonus* c ) void BonusList::resize(std::vector<Bonus*>::size_type sz, Bonus* c )
{ {
bonuses.resize(sz, c); bonuses.resize(sz, c);

changed();
if (belongsToTree)
CBonusSystemNode::treeHasChanged();
} }


void BonusList::insert(std::vector<Bonus*>::iterator position, std::vector<Bonus*>::size_type n, Bonus* const &x) void BonusList::insert(std::vector<Bonus*>::iterator position, std::vector<Bonus*>::size_type n, Bonus* const &x)
{ {
bonuses.insert(position, n, x); bonuses.insert(position, n, x);

changed();
if (belongsToTree)
CBonusSystemNode::treeHasChanged();
} }


int IBonusBearer::valOfBonuses(Bonus::BonusType type, const CSelector &selector) const int IBonusBearer::valOfBonuses(Bonus::BonusType type, const CSelector &selector) const
Expand Down Expand Up @@ -708,6 +710,36 @@ CBonusSystemNode::CBonusSystemNode() : bonuses(true), exportedBonuses(true), nod
{ {
} }


CBonusSystemNode::CBonusSystemNode(CBonusSystemNode && other):
bonuses(std::move(other.bonuses)),
exportedBonuses(std::move(other.exportedBonuses)),
nodeType(other.nodeType),
description(other.description),
cachedLast(0)
{
std::swap(parents, other.parents);
std::swap(children, other.children);

//fixing bonus tree without recalculation

for(CBonusSystemNode * n : parents)
{
n->children -= &other;
n->children.push_back(this);
}

for(CBonusSystemNode * n : children)
{
n->parents -= &other;
n->parents.push_back(this);
}

//cache ignored

//cachedBonuses
//cachedRequests
}

CBonusSystemNode::~CBonusSystemNode() CBonusSystemNode::~CBonusSystemNode()
{ {
detachFromAll(); detachFromAll();
Expand Down
31 changes: 5 additions & 26 deletions lib/HeroBonus.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ class DLL_LINKAGE BonusList


TInternalContainer bonuses; TInternalContainer bonuses;
bool belongsToTree; bool belongsToTree;

void changed();


public: public:
typedef TInternalContainer::const_reference const_reference; typedef TInternalContainer::const_reference const_reference;
Expand All @@ -423,6 +423,7 @@ class DLL_LINKAGE BonusList


BonusList(bool BelongsToTree = false); BonusList(bool BelongsToTree = false);
BonusList(const BonusList &bonusList); BonusList(const BonusList &bonusList);
BonusList(BonusList && other);
BonusList& operator=(const BonusList &bonusList); BonusList& operator=(const BonusList &bonusList);


// wrapper functions of the STL vector container // wrapper functions of the STL vector container
Expand Down Expand Up @@ -494,12 +495,8 @@ class DLL_LINKAGE BonusList
{ {
return bonuses.end(); return bonuses.end();
} }

//friend inline std::vector<Bonus*>::iterator range_begin(BonusList & x);
//friend inline std::vector<Bonus*>::iterator range_end(BonusList & x);
}; };



// Extensions for BOOST_FOREACH to enable iterating of BonusList objects // Extensions for BOOST_FOREACH to enable iterating of BonusList objects
// Don't touch/call this functions // Don't touch/call this functions
inline BonusList::iterator range_begin(BonusList & x) inline BonusList::iterator range_begin(BonusList & x)
Expand Down Expand Up @@ -614,7 +611,7 @@ class DLL_LINKAGE IBonusBearer
const TBonusListPtr getSpellBonuses() const; const TBonusListPtr getSpellBonuses() const;
}; };


class DLL_LINKAGE CBonusSystemNode : public IBonusBearer class DLL_LINKAGE CBonusSystemNode : public IBonusBearer, public boost::noncopyable
{ {
public: public:
enum ENodeTypes enum ENodeTypes
Expand Down Expand Up @@ -647,8 +644,8 @@ class DLL_LINKAGE CBonusSystemNode : public IBonusBearer
const TBonusListPtr getAllBonusesWithoutCaching(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = nullptr) const; const TBonusListPtr getAllBonusesWithoutCaching(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = nullptr) const;


public: public:

explicit CBonusSystemNode(); explicit CBonusSystemNode();
CBonusSystemNode(CBonusSystemNode && other);
virtual ~CBonusSystemNode(); virtual ~CBonusSystemNode();


void limitBonuses(const BonusList &allBonuses, BonusList &out) const; //out will bo populed with bonuses that are not limited here void limitBonuses(const BonusList &allBonuses, BonusList &out) const; //out will bo populed with bonuses that are not limited here
Expand Down Expand Up @@ -1010,23 +1007,5 @@ template <class InputIterator>
void BonusList::insert(const int position, InputIterator first, InputIterator last) void BonusList::insert(const int position, InputIterator first, InputIterator last)
{ {
bonuses.insert(bonuses.begin() + position, first, last); bonuses.insert(bonuses.begin() + position, first, last);

changed();
if (belongsToTree)
CBonusSystemNode::treeHasChanged();
} }

// Extensions for BOOST_FOREACH to enable iterating of BonusList objects
/*namespace boost
{
template<>
struct range_mutable_iterator<BonusList>
{
typedef std::vector<Bonus*>::iterator type;
};
template<>
struct range_const_iterator<BonusList>
{
typedef std::vector<Bonus*>::const_iterator type;
};
}*/

0 comments on commit f4f170b

Please sign in to comment.