diff --git a/src/astarnode.cpp b/src/astarnode.cpp index f9bfbb7bc8c..bb8786d1d36 100755 --- a/src/astarnode.cpp +++ b/src/astarnode.cpp @@ -1,6 +1,7 @@ /* $Id$ */ /* Copyright (C) 2003 by David White +Copyright (C) 2005 by Guillaume Melquiond Part of the Battle for Wesnoth Project http://www.wesnoth.org/ This program is free software; you can redistribute it and/or modify @@ -15,11 +16,8 @@ See the COPYING file for more details. #include "astarnode.hpp" #include "wassert.hpp" -poss_a_star_node* SingletonPOSS_AStarNode = NULL; - -void a_star_node::initNode(const gamemap::location& pos, const gamemap::location& dst, - double cost, a_star_node* parent, - const std::set* teleports) +void a_star_node::initNode(gamemap::location const &pos, gamemap::location const &dst, + double cost, a_star_node *parent, std::set const *teleports) { isInCloseList = false; loc = pos; @@ -46,128 +44,116 @@ void a_star_node::initNode(const gamemap::location& pos, const gamemap::location } } -poss_a_star_node::poss_a_star_node(void) : -capacity(0), curIndex(0) +class a_star_world::poss_a_star_node { - nbElemByPage = size_t((4096 - 24) / sizeof(a_star_node)); - wassert(nbElemByPage > 0); +private: + typedef std::vector vect_page_a_star_node; + vect_page_a_star_node vectPageAStarNode_; + size_t nbElemByPage_; + size_t capacity_; + size_t curIndex_; + void addPage(); + +public: + poss_a_star_node(); + ~poss_a_star_node(); + a_star_node *getAStarNode(); + void clear(); +}; + +void a_star_world::poss_a_star_node::addPage() +{ + vectPageAStarNode_.push_back(new a_star_node[nbElemByPage_]); + capacity_ += nbElemByPage_; +} + +a_star_world::poss_a_star_node::poss_a_star_node() + : capacity_(0), curIndex_(0) +{ + nbElemByPage_ = size_t((4096 - 24) / sizeof(a_star_node)); + wassert(nbElemByPage_ > 0); addPage(); - SingletonPOSS_AStarNode = this; } -void poss_a_star_node::addPage(void) +a_star_world::poss_a_star_node::~poss_a_star_node() { - a_star_node* locPageAStarNode; - - locPageAStarNode = new a_star_node[nbElemByPage]; - vectPageAStarNode.push_back(locPageAStarNode); - capacity += nbElemByPage; + for(vect_page_a_star_node::iterator iter = vectPageAStarNode_.begin(), + iend = vectPageAStarNode_.end(); + iter != iend; ++iter) + delete[] *iter; } -a_star_node* poss_a_star_node::getAStarNode(void) +a_star_node *a_star_world::poss_a_star_node::getAStarNode() { //----------------- PRE_CONDITIONS ------------------ - wassert(capacity > 0); - wassert(curIndex <= capacity); + wassert(capacity_ > 0); + wassert(curIndex_ <= capacity_); //--------------------------------------------------- - a_star_node* locPageAStarNode; - - if (curIndex == capacity) + if (curIndex_ == capacity_) addPage(); - - const size_t locIndexPage = curIndex / nbElemByPage; - const size_t locIndexInsidePage = curIndex % nbElemByPage; - ++curIndex; - - assertParanoAstar(locIndexPage < vectPageAStarNode.size()); - locPageAStarNode = vectPageAStarNode[locIndexPage]; - assertParanoAstar(locIndexInsidePage < nbElemByPage); - return (&(locPageAStarNode[locIndexInsidePage])); + size_t i = curIndex_++; + return &vectPageAStarNode_[i / nbElemByPage_][i % nbElemByPage_]; } -void poss_a_star_node::reduce(void) +void a_star_world::poss_a_star_node::clear() { - if (capacity > nbElemByPage) - { - for (vect_page_a_star_node::iterator iter = vectPageAStarNode.begin() + 1; iter != vectPageAStarNode.end(); ++iter) - delete[] (*iter); - vectPageAStarNode.resize(1); - capacity = nbElemByPage; + if (capacity_ > nbElemByPage_) { + for(vect_page_a_star_node::iterator iter = vectPageAStarNode_.begin() + 1, + iend = vectPageAStarNode_.end(); + iter != iend; ++iter) + delete[] *iter; + vectPageAStarNode_.resize(1); + capacity_ = nbElemByPage_; } - curIndex = 0; + curIndex_ = 0; //----------------- POST_CONDITIONS ----------------- - wassert(capacity == nbElemByPage); - wassert(vectPageAStarNode.size() == 1); + wassert(capacity_ == nbElemByPage_); + wassert(vectPageAStarNode_.size() == 1); //--------------------------------------------------- } -void a_star_world::resize_IFN(const size_t parWidth, const size_t parHeight) +a_star_world::a_star_world() + : pool_(new poss_a_star_node), width_(0), nbNode_(0) +{ +} + +a_star_world::~a_star_world() +{ + delete pool_; +} + +void a_star_world::resize_IFN(size_t parWidth, size_t parHeight) { //----------------- PRE_CONDITIONS ------------------ - wassert(_nbNode == 0); + wassert(nbNode_ == 0); //--------------------------------------------------- - _width = parWidth; - if (_vectAStarNode.size() != parWidth * parHeight) - { - _vectAStarNode.reserve(parWidth * parHeight); - _vectAStarNode.resize(parWidth * parHeight); - } + width_ = parWidth; + size_t sz = parWidth * parHeight; + if (vectAStarNode_.size() == sz) + return; + vectAStarNode_.reserve(sz); + vectAStarNode_.resize(sz); } void a_star_world::clear(void) { - if (_nbNode > 0) - { - a_star_node* locNode = NULL; - std::fill(_vectAStarNode.begin(), _vectAStarNode.end(), locNode); - _nbNode = 0; - } + a_star_node *locNode = NULL; + std::fill(vectAStarNode_.begin(), vectAStarNode_.end(), locNode); + nbNode_ = 0; + pool_->clear(); } -bool a_star_world::empty(void) -{ - return (_nbNode == 0); -} - -bool a_star_world::reallyEmpty(void) -{ - for (vect_a_star_node::iterator iter = _vectAStarNode.begin(); iter != _vectAStarNode.end(); ++iter) - { - if (*iter != NULL) - return (false); - } - return (true); -} - -void a_star_world::erase(gamemap::location const &loc) +a_star_node *a_star_world::getNodeFromLocation(gamemap::location const &loc, bool &isCreated) { //----------------- PRE_CONDITIONS ------------------ wassert(loc.valid()); - wassert(loc.x + (loc.y * _width) < _vectAStarNode.size()); + wassert(loc.x + loc.y * width_ < vectAStarNode_.size()); //--------------------------------------------------- - _vectAStarNode[loc.x + (loc.y * _width)] = NULL; -} -a_star_node* a_star_world::getNodeFromLocation(gamemap::location const &loc, bool& isCreated) -{ - //----------------- PRE_CONDITIONS ------------------ - wassert(loc.valid()); - //--------------------------------------------------- - a_star_node* node; - size_t index; - - index = size_t(loc.x + (loc.y * _width)); - assertParanoAstar(index < _vectAStarNode.size()); - node = _vectAStarNode[index]; - if (node == NULL) - { - isCreated = true; - wassert(SingletonPOSS_AStarNode != NULL); - node = SingletonPOSS_AStarNode->getAStarNode(); - _vectAStarNode[index] = node; - ++_nbNode; + a_star_node *&node = vectAStarNode_[loc.x + loc.y * width_]; + if ((isCreated = (node == NULL))) { + node = pool_->getAStarNode(); + ++nbNode_; } - else - isCreated = false; - return (node); + return node; } diff --git a/src/astarnode.hpp b/src/astarnode.hpp index 9d4b4d9c96f..b2a255b3f25 100755 --- a/src/astarnode.hpp +++ b/src/astarnode.hpp @@ -1,6 +1,7 @@ /* $Id$ */ /* Copyright (C) 2003 by David White +Copyright (C) 2005 by Guillaume Melquiond Part of the Battle for Wesnoth Project http://www.wesnoth.org/ This program is free software; you can redistribute it and/or modify @@ -19,12 +20,6 @@ See the COPYING file for more details. #include #include -#ifdef _PARANO_ASTAR_ -# define assertParanoAstar(param) assert(param) -#else -# define assertParanoAstar(param) {} -#endif - struct a_star_node { public: @@ -42,41 +37,20 @@ public: } }; -class poss_a_star_node -{ -private: - typedef std::vector vect_page_a_star_node; - - vect_page_a_star_node vectPageAStarNode; - size_t nbElemByPage; - size_t capacity; - size_t curIndex; - -public: - poss_a_star_node(void); - void addPage(void); - a_star_node* getAStarNode(void); - void reduce(void); -}; - class a_star_world { -protected: + class poss_a_star_node; + poss_a_star_node *pool_; typedef std::vector vect_a_star_node; - - vect_a_star_node _vectAStarNode; - size_t _width; + vect_a_star_node vectAStarNode_; + size_t width_, nbNode_; public: - size_t _nbNode; - - void resize_IFN(const size_t parWidth, const size_t parHeight); - void clear(void); - void erase(gamemap::location const &loc); + void resize_IFN(size_t parWidth, size_t parHeight); + void clear(); a_star_node* getNodeFromLocation(gamemap::location const &loc, bool& isCreated); - bool empty(void); - bool reallyEmpty(void); - a_star_world(void) : _width(0), _nbNode(0) {}; + a_star_world(); + ~a_star_world(); }; #endif diff --git a/src/pathfind.cpp b/src/pathfind.cpp index 3b138b24f26..03c76219aa2 100644 --- a/src/pathfind.cpp +++ b/src/pathfind.cpp @@ -1,6 +1,7 @@ /* $Id$ */ /* Copyright (C) 2003 by David White +Copyright (C) 2005 by Guillaume Melquiond Part of the Battle for Wesnoth Project http://www.wesnoth.org/ This program is free software; you can redistribute it and/or modify @@ -46,7 +47,6 @@ static void a_star_init(gamemap::location const &src, gamemap::location const &d bool locIsCreated; aStarGameWorld.resize_IFN(parWidth, parHeight); - wassert(aStarGameWorld.empty()); a_star_node *locStartNode = aStarGameWorld.getNodeFromLocation(src, locIsCreated); wassert(locIsCreated); locStartNode->initNode(src, dst, 0.0, NULL, teleports); @@ -152,7 +152,6 @@ paths::route a_star_search(gamemap::location const &src, gamemap::location const wassert(stop_at <= costCalculator->getNoPathValue()); //--------------------------------------------------- static a_star_world aStarGameWorld; - static poss_a_star_node POSS_AStarNode; vector_a_star_node openList; vector_location vectLocation; @@ -213,7 +212,6 @@ paths::route a_star_search(gamemap::location const &src, gamemap::location const label_AStarSearch_end: openList.clear(); - POSS_AStarNode.reduce(); aStarGameWorld.clear(); return locRoute; }