Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jun 28, 2009, 6:22:40 PM (15 years ago)
Author:
rgrieder
Message:

Moved GameState construction from pre-main() to after Core creation. That makes it possible to use Core features (like configValues) in the GameState constructor.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/core4/src/core/Game.cc

    r3238 r3243  
    5454    using boost::weak_ptr;
    5555
    56     std::map<std::string, GameState*> Game::allStates_s;
    57     Game* Game::singletonRef_s = 0;
    58 
    5956    static void stop_game()
    6057        { Game::getInstance().stop(); }
    6158    SetConsoleCommandShortcutExternAlias(stop_game, "exit");
    62     // Add an empty gamestate that serves as internal root state
    63     AddGameState(GameState, "emptyRootGameState");
    6459
    6560    struct _CoreExport GameStateTreeNode
     
    6964        std::vector<shared_ptr<GameStateTreeNode> > children_;
    7065    };
     66
     67    std::map<std::string, Game::GameStateInfo> Game::gameStateDeclarations_s;
     68    Game* Game::singletonRef_s = 0;
    7169
    7270    /**
     
    7674    Game::Game(int argc, char** argv)
    7775    {
    78         assert(singletonRef_s == 0);
     76        if (singletonRef_s != 0)
     77        {
     78            COUT(0) << "Error: The Game singleton cannot be recreated! Shutting down." << std::endl;
     79            abort();
     80        }
    7981        singletonRef_s = this;
    8082
    8183        this->bAbort_ = false;
    8284        bChangingState_ = false;
    83         // The empty root state is ALWAYS loaded!
    84         this->rootStateNode_ = shared_ptr<GameStateTreeNode>(new GameStateTreeNode());
    85         this->rootStateNode_->state_ = getState("emptyRootGameState");
    86         this->activeStateNode_ = this->rootStateNode_;
    87         this->activeStates_.push_back(this->rootStateNode_->state_);
     85
     86        // Create an empty root state
     87        declareGameState<GameState>("GameState", "emptyRootGameState", true, false);
    8888
    8989        // reset statistics
     
    9898        this->gameClock_ = new Clock();
    9999
     100        // Create the Core
    100101        this->core_ = new orxonox::Core();
    101102        this->core_->initialise(argc, argv);
    102103
     104        // After the core has been created, we can safely instantiate the GameStates
     105        for (std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.begin();
     106            it != gameStateDeclarations_s.end(); ++it)
     107        {
     108            // Only create the states appropriate for the game mode
     109            //if (GameMode::showsGraphics || !it->second.bGraphicsMode)
     110            GameStateConstrParams params = { it->second.stateName, it->second.bIgnoreTickTime };
     111            gameStates_[getLowercase(it->second.stateName)] = GameStateFactory::fabricate(it->second.className, params);
     112        }
     113
     114        // The empty root state is ALWAYS loaded!
     115        this->rootStateNode_ = shared_ptr<GameStateTreeNode>(new GameStateTreeNode());
     116        this->rootStateNode_->state_ = getState("emptyRootGameState");
     117        this->activeStateNode_ = this->rootStateNode_;
     118        this->activeStates_.push_back(this->rootStateNode_->state_);
     119
     120        // Do this after Core creation!
    103121        RegisterRootObject(Game);
    104122        this->setConfigValues();
     
    110128    Game::~Game()
    111129    {
    112         // Destroy pretty much everyhting left
     130        // Destroy the GameStates (note that the nodes still point to them, but doesn't matter)
     131        for (std::map<std::string, GameState*>::const_iterator it = gameStates_.begin();
     132            it != gameStates_.end(); ++it)
     133            delete it->second;
     134
     135        // Destroy the Core and with it almost everything
    113136        delete this->core_;
    114 
    115137        delete this->gameClock_;
    116138
    117         assert(singletonRef_s);
    118         singletonRef_s = 0;
     139        // Also, take care of the GameStateFactories
     140        GameStateFactory::destroyFactories();
     141
     142        // Don't assign singletonRef_s with NULL! Recreation is not supported
    119143    }
    120144
     
    165189
    166190            // STATISTICS
    167             statisticsTickInfo tickInfo = {currentTime, 0};
     191            StatisticsTickInfo tickInfo = {currentTime, 0};
    168192            statisticsTickTimes_.push_back(tickInfo);
    169193            this->periodTime_ += this->gameClock_->getDeltaTimeMicroseconds();
     
    240264            if (this->periodTime_ > statisticsRefreshCycle_)
    241265            {
    242                 std::list<statisticsTickInfo>::iterator it = this->statisticsTickTimes_.begin();
     266                std::list<StatisticsTickInfo>::iterator it = this->statisticsTickTimes_.begin();
    243267                assert(it != this->statisticsTickTimes_.end());
    244268                int64_t lastTime = currentTime - this->statisticsAvgLength_;
     
    356380    GameState* Game::getState(const std::string& name)
    357381    {
    358         std::map<std::string, GameState*>::const_iterator it = allStates_s.find(getLowercase(name));
    359         if (it != allStates_s.end())
     382        std::map<std::string, GameState*>::const_iterator it = gameStates_.find(getLowercase(name));
     383        if (it != gameStates_.end())
    360384            return it->second;
    361385        else
     
    448472    }
    449473
    450     /*static*/ bool Game::addGameState(GameState* state)
    451     {
    452         std::map<std::string, GameState*>::const_iterator it = allStates_s.find(getLowercase(state->getName()));
    453         if (it == allStates_s.end())
    454             allStates_s[getLowercase(state->getName())] = state;
    455         else
    456             ThrowException(GameState, "Cannot add two GameStates with the same name to 'Game'.");
    457 
    458         // just a required dummy return value
    459         return true;
    460     }
    461 
    462     /*static*/ void Game::destroyStates()
    463     {
    464         // Delete all GameStates created by the macros
    465         for (std::map<std::string, GameState*>::const_iterator it = allStates_s.begin(); it != allStates_s.end(); ++it)
     474    std::map<std::string, Game::GameStateFactory*> Game::GameStateFactory::factories_s;
     475
     476    /*static*/ GameState* Game::GameStateFactory::fabricate(const std::string& className, const GameStateConstrParams& params)
     477    {
     478        std::map<std::string, GameStateFactory*>::const_iterator it = factories_s.find(className);
     479        assert(it != factories_s.end());
     480        return it->second->fabricate(params);
     481    }
     482
     483    /*static*/ void Game::GameStateFactory::destroyFactories()
     484    {
     485        for (std::map<std::string, GameStateFactory*>::const_iterator it = factories_s.begin(); it != factories_s.end(); ++it)
    466486            delete it->second;
    467         allStates_s.clear();
     487        factories_s.clear();
    468488    }
    469489}
Note: See TracChangeset for help on using the changeset viewer.