Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Dec 25, 2010, 8:51:17 PM (14 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.

Location:
code/trunk/src/orxonox
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • code/trunk/src/orxonox/LevelInfo.h

    r7652 r7802  
    4040#include <set>
    4141#include <string>
     42#include "util/StringUtils.h"
    4243
    4344#include "core/BaseObject.h"
     
    7374            @return Returns the name of the Level.
    7475            */
    75             inline const std::string& getName(void) { return this->name_; } // tolua_export
     76            inline const std::string& getName(void) const { return this->name_; } // tolua_export
    7677
    7778            /**
     
    150151        @code
    151152        <LevelInfo
    152             name = "Levelname"
     153            name = "Levelname"lhs->compare(rhs) < 0
    153154            description = "This is just some awesome level."
    154155            tags = "test, awesome"
     
    197198
    198199    };
     200
     201    /**
     202    @brief
     203        Struct that overloads the compare operation between two @ref orxonox::LevelInfoItem "LevelInfoItem" pointers.
     204    */
     205    struct LevelInfoCompare
     206    {
     207        bool operator() (const LevelInfoItem* lhs, const LevelInfoItem* rhs) const
     208            { return getLowercase(lhs->getName()).compare(getLowercase(rhs->getName())) < 0; }
     209    };
     210   
    199211} // tolua_export
    200212
  • 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    {
  • code/trunk/src/orxonox/LevelManager.h

    r7648 r7802  
    2323 *      Fabian 'x3n' Landau
    2424 *   Co-authors:
    25  *      ...
     25 *      Damian 'Mozork' Frick
    2626 *
    2727 */
     
    3737#include <string>
    3838
     39#include "LevelInfo.h"
     40
    3941#include "util/Singleton.h"
    4042#include "core/OrxonoxClass.h"
     
    4345namespace orxonox
    4446{
     47
     48    /**
     49    @brief
     50        The LevelManager keeps track of @ref orxonox::Level "Levels" whose activity has been requested and serves as an access point to get a list of all available @ref orxonox::Level "Levels" (or rather their respective @ref orxonox::LevelInfoItem "LevelInfoItems").
     51
     52    @author
     53        Fabian 'x3n' Landau
     54
     55    @author
     56        Damian 'Mozork' Frick
     57    */
    4558    class _OrxonoxExport LevelManager
    4659    // tolua_end
     
    5265            virtual ~LevelManager();
    5366
    54             void setConfigValues();
     67            void setConfigValues(); //!< Set the config values for this object.
    5568
    56             void requestActivity(Level* level);
    57             void releaseActivity(Level* level);
    58             Level* getActiveLevel();
     69            void requestActivity(Level* level); //!< Request activity for the input Level.
     70            void releaseActivity(Level* level); //!< Release activity for the input Level.
     71            Level* getActiveLevel(); //!< Get the currently active Level.
    5972
    60             void setDefaultLevel(const std::string& levelName); //tolua_export
    61             const std::string& getDefaultLevel() const; //tolua_export
    62             unsigned int getNumberOfLevels(void); //tolua_export
    63             LevelInfoItem* getAvailableLevelListItem(unsigned int index) const; //tolua_export
     73            // tolua_begin
     74            void setDefaultLevel(const std::string& levelName); //!< Set the default Level.
     75            /**
     76            @brief Get the default level.
     77            @return Returns the filename of the default level.
     78            */
     79            const std::string& getDefaultLevel() const
     80                { return defaultLevelName_; }
     81            unsigned int getNumberOfLevels(void);
     82            LevelInfoItem* getAvailableLevelListItem(unsigned int index); //!< Get the LevelInfoItem at the given index in the list of available Levels.
    6483
    65             static LevelManager& getInstance()    { return Singleton<LevelManager>::getInstance(); } // tolua_export
     84            /**
     85            @brief Get the instance of the LevelManager.
     86            @return Returns the instance of the LevelManager.
     87            */
     88            static LevelManager& getInstance()
     89                { return Singleton<LevelManager>::getInstance(); }
     90            // tolua_end
    6691
    6792        private:
    6893            LevelManager(const LevelManager&);
    6994
    70             void activateNextLevel();
     95            void activateNextLevel(); //!< Activate the next level.
    7196
    72             void compileAvailableLevelList(void);
    73             void updateAvailableLevelList(void);
     97            void compileAvailableLevelList(void); //!< Compile the list of available Levels.
     98            void updateAvailableLevelList(void); //!< Update the list of available Levels.
    7499
    75             std::list<Level*> levels_s;
    76             std::vector<std::string> availableLevels_;
    77             std::map<std::string, LevelInfoItem*> infos_;
     100            std::list<Level*> levels_; //!< A list of all the Levels whose activity has been requested, in the order in which they will become active.
     101            std::set<LevelInfoItem*, LevelInfoCompare> availableLevels_; //!< The set of available Levels sorted alphabetically according to the name of the Level.
     102
     103            // Helpers to allow fast access to the availableLevels list.
     104            unsigned int nextIndex_; //! The next expected index to be accessed.
     105            std::set<LevelInfoItem*, LevelInfoCompare>::iterator nextLevel_; //! The nex expected Level to be accessed.
    78106
    79107            // config values
Note: See TracChangeset for help on using the changeset viewer.