Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Dec 25, 2010, 8:51:17 PM (13 years ago)
Author:
dafrick
Message:

Making the level list in the LevelManager (and as consequence the level list displayed by the GUI) alphabetically sorted. Also some cleanup and documented LevelManager.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/trunk/src/orxonox/LevelManager.cc

    r7801 r7802  
    2323 *      Fabian 'x3n' Landau
    2424 *   Co-authors:
    25  *      ...
     25 *      Damian 'Mozork' Frick
    2626 *
    2727 */
     
    3939#include "core/Resource.h"
    4040#include "core/XMLFile.h"
     41#include "Level.h"
    4142#include "PlayerManager.h"
    42 #include "Level.h"
    43 #include "LevelInfo.h"
    4443
    4544namespace orxonox
     
    4948    ManageScopedSingleton(LevelManager, ScopeID::Root, false);
    5049
     50    /**
     51    @brief
     52        Constructor. Registers the object, sets config values and initializes variables.
     53    */
    5154    LevelManager::LevelManager()
    5255    {
     
    6164
    6265        this->compileAvailableLevelList();
     66        this->nextIndex_ = 0;
     67        this->nextLevel_ = this->availableLevels_.begin();
    6368    }
    6469
     
    6772    }
    6873
     74    /**
     75    @brief
     76        Set the config values for this object.
     77    */
    6978    void LevelManager::setConfigValues()
    7079    {
     
    7382    }
    7483
     84    /**
     85    @brief
     86        Request activity for the input Level.
     87        The Level will be added to the list of Levels whose activity is requested. The list is accessed in a FIFO manner.
     88        If the Level is the only Level in the list it will be immediately activated. If not it will be activated as soon as it reaches the front of the list.
     89    @param level
     90        A pointer to the Level whose activity is requested.
     91    */
    7592    void LevelManager::requestActivity(Level* level)
    7693    {
    77         assert( std::find(this->levels_s.begin(), this->levels_s.end(), level)==this->levels_s.end() );
    78         if( std::find(this->levels_s.begin(), this->levels_s.end(), level)!=this->levels_s.end() )
    79             return; // level is already in list
    80         this->levels_s.push_back(level);
    81         if (this->levels_s.size() == 1)
     94        assert( std::find(this->levels_.begin(), this->levels_.end(), level)==this->levels_.end() );
     95        // If the level is already in list.
     96        if( std::find(this->levels_.begin(), this->levels_.end(), level)!=this->levels_.end() )
     97            return;
     98        // If it isn't insert it at the back.
     99        this->levels_.push_back(level);
     100        // If it is the only level in the list activate it.
     101        if (this->levels_.size() == 1)
    82102            this->activateNextLevel();
    83103    }
    84104
     105    /**
     106    @brief
     107        Release activity for the input Level.
     108        Removes the Level from the list. If the Level was the one currently active, it is deactivated and the next Level in line is activated.
     109    @param level
     110        A pointer to the Level whose activity is to be released.
     111    */
    85112    void LevelManager::releaseActivity(Level* level)
    86113    {
    87         if (this->levels_s.size() > 0)
    88         {
    89             if (this->levels_s.front() == level)
    90             {
     114        if (this->levels_.size() > 0)
     115        {
     116            // If the level is the active level in the front of the list.
     117            if (this->levels_.front() == level)
     118            {
     119                // Deactivate it, remove it from the list and activate the next level in line.
    91120                level->setActive(false);
    92                 this->levels_s.pop_front();
     121                this->levels_.pop_front();
    93122                this->activateNextLevel();
    94123            }
    95             else
    96             {
    97                 for (std::list<Level*>::iterator it = this->levels_s.begin(); it != this->levels_s.end(); ++it)
    98                     if ((*it) == level)
    99                         this->levels_s.erase(it);
    100             }
    101         }
    102     }
    103 
     124            else // Else just remove it from the list.
     125                this->levels_.erase(std::find(this->levels_.begin(), this->levels_.end(), level));
     126        }
     127    }
     128
     129    /**
     130    @brief
     131        Get the currently active Level.
     132    @return
     133        Returns a pointer to the currently active level or NULL if there currently are no active Levels.
     134    */
    104135    Level* LevelManager::getActiveLevel()
    105136    {
    106         if (this->levels_s.size() > 0)
    107             return this->levels_s.front();
     137        if (this->levels_.size() > 0)
     138            return this->levels_.front();
    108139        else
    109140            return 0;
    110141    }
    111142
     143    /**
     144    @brief
     145        Activate the next Level.
     146    */
    112147    void LevelManager::activateNextLevel()
    113148    {
    114         if (this->levels_s.size() > 0)
    115         {
    116             this->levels_s.front()->setActive(true);
     149        if (this->levels_.size() > 0)
     150        {
     151            // Activate the level that is the first in the list of levels whose activity has been requested.
     152            this->levels_.front()->setActive(true);
     153            // Make every player enter the newly activated level.
    117154            for (std::map<unsigned int, PlayerInfo*>::const_iterator it = PlayerManager::getInstance().getClients().begin(); it != PlayerManager::getInstance().getClients().end(); ++it)
    118                 this->levels_s.front()->playerEntered(it->second);
    119         }
    120     }
    121 
     155                this->levels_.front()->playerEntered(it->second);
     156        }
     157    }
     158
     159    /**
     160    @brief
     161        Set the default Level.
     162    @param levelName
     163        The filename of the default Level.
     164    */
    122165    void LevelManager::setDefaultLevel(const std::string& levelName)
    123166    {
     
    125168    }
    126169
    127     const std::string& LevelManager::getDefaultLevel() const
    128     {
    129         return defaultLevelName_;
    130     }
    131 
     170    /**
     171    @brief
     172        Get the number of available Levels.
     173        Also updates the list of available Levels.
     174    @return
     175        Returns the number of available Levels.
     176    */
    132177    unsigned int LevelManager::getNumberOfLevels()
    133178    {
     
    137182    }
    138183
    139     LevelInfoItem* LevelManager::getAvailableLevelListItem(unsigned int index) const
     184    /**
     185    @brief
     186        Get the LevelInfoItem at the given index in the list of available Levels.
     187        The LevelInfoItems are sorted in alphabetical order accoridng to the name of the Level.
     188        This method is most efficiently called with consecutive indices (or at least ascending indices).
     189    @return
     190        Returns a pointer to the LevelInfoItem at the given index.
     191    */
     192    LevelInfoItem* LevelManager::getAvailableLevelListItem(unsigned int index)
    140193    {
    141194        if (index >= this->availableLevels_.size())
    142195            return NULL;
     196
     197        // If this index directly follows the last we can optimize a lot.
     198        if(index == this->nextIndex_)
     199        {
     200            this->nextIndex_++;
     201            std::set<LevelInfoItem*, LevelInfoCompare>::iterator it = this->nextLevel_;
     202            this->nextLevel_++;
     203            return *it;
     204        }
    143205        else
    144206        {
    145             std::map<std::string, LevelInfoItem*>::const_iterator it = this->infos_.find(this->availableLevels_[index]);
    146             return it->second;
    147         }
    148     }
    149 
     207            // If this index is bigger than the last, we can optimize a little.
     208            if(index > this->nextIndex_)
     209            {
     210                this->nextIndex_ = 0;
     211                this->nextLevel_ = this->availableLevels_.begin();
     212            }
     213            while(this->nextIndex_ != index)
     214            {
     215                this->nextIndex_++;
     216                this->nextLevel_++;
     217            }
     218            this->nextIndex_++;
     219            std::set<LevelInfoItem*, LevelInfoCompare>::iterator it = this->nextLevel_;
     220            this->nextLevel_++;
     221            return *it;
     222        }
     223    }
     224
     225    /**
     226    @brief
     227        Compile the list of available Levels.
     228        Iterates over all *.oxw files, loads the LevelInfo objects in them and from that it creates the LevelInfoItems which are inserted in a list.
     229    */
    150230    void LevelManager::compileAvailableLevelList()
    151231    {
     
    155235        for (Ogre::StringVector::const_iterator it = levels->begin(); it != levels->end(); ++it)
    156236        {
    157             //TODO: Replace with tag,
     237            //TODO: Replace with tag?
    158238            if (it->find("old/") != 0)
    159239            {
    160240                size_t pos = it->find(".oxw");
    161241
     242                // Load the LevelInfo object from the level file.
    162243                bool infoExists = false;
    163                 // Load the LevelInfo object from the level file.
    164244                XMLFile file = XMLFile(*it);
    165245                ClassTreeMask mask = ClassTreeMask();
     
    167247                mask.include(ClassIdentifier<LevelInfo>::getIdentifier());
    168248                Loader::load(&file, mask, false);
     249                // Iterate over all LevelInfos.
    169250                for(ObjectList<LevelInfo>::iterator item = ObjectList<LevelInfo>::begin(); item != ObjectList<LevelInfo>::end(); ++item)
    170251                {
    171252                    LevelInfoItem* info = item->copy();
    172                     if(info->getXMLFilename() == *it)
     253                    if(info->getXMLFilename() == *it) // If the LevelInfo for this level exists we insert it into the list of available levels.
    173254                    {
    174                         this->infos_.insert(std::pair<std::string, LevelInfoItem*>(it->substr(0, pos),info));
     255                        this->availableLevels_.insert(info);
    175256                        infoExists = true;
    176257                    }
    177258                }
    178259                Loader::unload(&file, mask);
    179                 if(!infoExists)
    180                 {
    181                     this->infos_.insert(std::pair<std::string, LevelInfoItem*>(it->substr(0, pos), new LevelInfoItem(it->substr(0, pos), *it)));
    182                 }
    183 
    184                 this->availableLevels_.push_back(it->substr(0, pos));
    185             }
    186         }
    187     }
    188 
     260                if(!infoExists) // If the LevelInfo for this level doesn't exist, we create a new one and insert it into the list of available levels.
     261                    this->availableLevels_.insert(new LevelInfoItem(it->substr(0, pos), *it));
     262            }
     263        }
     264    }
     265
     266    /**
     267    @brief
     268        Update the list of available Levels.
     269    */
    189270    void LevelManager::updateAvailableLevelList(void)
    190271    {
Note: See TracChangeset for help on using the changeset viewer.