Added GameManager class to keep track of the World objects, should fix the crashing...
authorIngo Ruhnke <grumbel@gmail.com>
Sat, 9 Aug 2014 04:51:47 +0000 (06:51 +0200)
committerIngo Ruhnke <grumbel@gmail.com>
Sat, 9 Aug 2014 04:51:47 +0000 (06:51 +0200)
src/supertux/game_manager.cpp [new file with mode: 0644]
src/supertux/game_manager.hpp [new file with mode: 0644]
src/supertux/main.cpp
src/supertux/menu/contrib_menu.cpp
src/supertux/menu/contrib_world_menu.cpp
src/supertux/menu/contrib_world_menu.hpp
src/supertux/menu/main_menu.cpp
src/supertux/title_screen.cpp
src/supertux/title_screen.hpp
src/supertux/world.cpp

diff --git a/src/supertux/game_manager.cpp b/src/supertux/game_manager.cpp
new file mode 100644 (file)
index 0000000..3b615f1
--- /dev/null
@@ -0,0 +1,76 @@
+//  SuperTux
+//  Copyright (C) 2013 Ingo Ruhnke <grumbel@gmx.de>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/game_manager.hpp"
+
+#include <sstream>
+
+#include "gui/menu_manager.hpp"
+#include "supertux/game_session.hpp"
+#include "supertux/gameconfig.hpp"
+#include "supertux/globals.hpp"
+#include "supertux/screen.hpp"
+#include "supertux/screen_fade.hpp"
+#include "supertux/screen_manager.hpp"
+#include "supertux/world.hpp"
+#include "util/file_system.hpp"
+#include "util/log.hpp"
+
+GameManager::GameManager() :
+  m_world()
+{
+}
+
+GameManager::~GameManager()
+{
+}
+
+void
+GameManager::start_level(std::unique_ptr<World> world, int index)
+{
+  m_world = std::move(world);
+
+  std::unique_ptr<Screen> screen(new GameSession(m_world->get_level_filename(index), 
+                                                 m_world->get_player_status()));
+  g_screen_manager->push_screen(std::move(screen));
+}
+
+void
+GameManager::start_game(std::unique_ptr<World> world)
+{
+  m_world = std::move(world);
+
+  MenuManager::instance().clear_menu_stack();
+
+  std::string basename = m_world->get_basedir();
+  basename = basename.substr(0, basename.length()-1);
+  std::string worlddirname = FileSystem::basename(basename);
+  std::ostringstream stream;
+  stream << "profile" << g_config->profile << "/" << worlddirname << ".stsg";
+  std::string slotfile = stream.str();
+
+  try
+  {
+    m_world->set_savegame_filename(slotfile);
+    m_world->run();
+  }
+  catch(std::exception& e)
+  {
+    log_fatal << "Couldn't start world: " << e.what() << std::endl;
+  }
+}
+
+/* EOF */
diff --git a/src/supertux/game_manager.hpp b/src/supertux/game_manager.hpp
new file mode 100644 (file)
index 0000000..1b27fb5
--- /dev/null
@@ -0,0 +1,45 @@
+//  SuperTux
+//  Copyright (C) 2013 Ingo Ruhnke <grumbel@gmx.de>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_GAME_MANAGER_HPP
+#define HEADER_SUPERTUX_SUPERTUX_GAME_MANAGER_HPP
+
+#include <memory>
+
+#include "util/currenton.hpp"
+
+class World;
+
+class GameManager : public Currenton<GameManager>
+{
+private:
+  std::unique_ptr<World> m_world;
+
+public:
+  GameManager();
+  ~GameManager();
+
+  void start_game(std::unique_ptr<World> world);
+  void start_level(std::unique_ptr<World> world, int index);
+
+private:
+  GameManager(const GameManager&) = delete;
+  GameManager& operator=(const GameManager&) = delete;
+};
+
+#endif
+
+/* EOF */
index 40fab4c..eee10dc 100644 (file)
@@ -14,6 +14,8 @@
 //  You should have received a copy of the GNU General Public License
 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+#include "supertux/main.hpp"
+
 #include <config.h>
 #include <version.h>
 
@@ -28,10 +30,6 @@ extern "C" {
 #include <findlocale.h>
 }
 
-#include "video/renderer.hpp"
-#include "video/lightmap.hpp"
-#include "supertux/main.hpp"
-
 #include "addon/addon_manager.hpp"
 #include "audio/sound_manager.hpp"
 #include "control/input_manager.hpp"
@@ -40,6 +38,7 @@ extern "C" {
 #include "physfs/physfs_file_system.hpp"
 #include "physfs/physfs_sdl.hpp"
 #include "scripting/squirrel_util.hpp"
+#include "supertux/game_manager.hpp"
 #include "supertux/gameconfig.hpp"
 #include "supertux/globals.hpp"
 #include "supertux/player_status.hpp"
@@ -50,6 +49,8 @@ extern "C" {
 #include "util/file_system.hpp"
 #include "util/gettext.hpp"
 #include "video/drawing_context.hpp"
+#include "video/lightmap.hpp"
+#include "video/renderer.hpp"
 #include "worldmap/worldmap.hpp"
 
 namespace { DrawingContext *context_pointer; }
@@ -523,6 +524,7 @@ Main::run(int argc, char** argv)
 
     const std::unique_ptr<PlayerStatus> default_playerstatus(new PlayerStatus());
 
+    GameManager game_manager;
     g_screen_manager = new ScreenManager();
 
     init_rand();
index 8f26e68..6bf8fcf 100644 (file)
@@ -19,6 +19,7 @@
 #include <physfs.h>
 
 #include "gui/menu_manager.hpp"
+#include "supertux/game_manager.hpp"
 #include "supertux/menu/contrib_world_menu.hpp"
 #include "supertux/menu/menu_storage.hpp"
 #include "supertux/title_screen.hpp"
@@ -62,13 +63,10 @@ ContribMenu::ContribMenu() :
 
   add_hl();
   add_back(_("Back"));
-
-  std::cout << "ContribMenu" << std::endl;
 }
 
 ContribMenu::~ContribMenu()
 {
-  std::cout << "~ContribMenu" << std::endl;
 }
 
 void
@@ -78,14 +76,16 @@ ContribMenu::check_menu()
   if (index != -1)
   {
     World* world = m_contrib_worlds[index].get();
-    
     if (!world->is_levelset) 
     {
-      TitleScreen::start_game(world);
+      // FIXME: not the most elegant of solutions to std::move() the
+      // World, but the ContribMenu should get destructed after this,
+      // so it might be ok
+      GameManager::current()->start_game(std::move(m_contrib_worlds[index]));
     }
     else 
     {
-      MenuManager::instance().push_menu(std::unique_ptr<Menu>(new ContribWorldMenu(*world)));
+      MenuManager::instance().push_menu(std::unique_ptr<Menu>(new ContribWorldMenu(std::move(m_contrib_worlds[index]))));
     }
   }
 }
index b4ef4a5..e8d58ff 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "audio/sound_manager.hpp"
 #include "gui/menu_item.hpp"
+#include "supertux/game_manager.hpp"
 #include "supertux/globals.hpp"
 #include "supertux/screen_fade.hpp"
 #include "supertux/screen_manager.hpp"
 #include "supertux/world.hpp"
 #include "util/gettext.hpp"
 
-ContribWorldMenu::ContribWorldMenu(const World& current_world) :
-  m_current_world(current_world)
+ContribWorldMenu::ContribWorldMenu(std::unique_ptr<World> world) :
+  m_world(std::move(world))
 {
-  add_label(m_current_world.get_title());
+  add_label(m_world->get_title());
   add_hl();
 
-  for (unsigned int i = 0; i < m_current_world.get_num_levels(); ++i)
+  for (unsigned int i = 0; i < m_world->get_num_levels(); ++i)
   {
     /** get level's title */
-    std::string filename = m_current_world.get_level_filename(i);
+    std::string filename = m_world->get_level_filename(i);
     std::string title = TitleScreen::get_level_name(filename);
     add_entry(i, title);
   }
@@ -51,9 +52,7 @@ ContribWorldMenu::check_menu()
     if (get_item_by_id(index).kind == MN_ACTION) 
     {
       sound_manager->stop_music();
-      g_screen_manager->push_screen(
-        std::unique_ptr<Screen>(
-          new GameSession(m_current_world.get_level_filename(index), m_current_world.get_player_status())));
+      GameManager::current()->start_level(std::move(m_world), index);
     }
   }
 }
index bfe55cd..98abc39 100644 (file)
@@ -24,10 +24,10 @@ class World;
 class ContribWorldMenu : public Menu
 {
 private:
-  const World& m_current_world;
+  std::unique_ptr<World> m_world;
 
 public:
-  ContribWorldMenu(const World& current_world);
+  ContribWorldMenu(std::unique_ptr<World> current_world);
 
   void check_menu();
 
index eb35da1..b4974a4 100644 (file)
 #include "audio/sound_manager.hpp"
 #include "gui/menu_manager.hpp"
 #include "supertux/fadeout.hpp"
+#include "supertux/game_manager.hpp"
 #include "supertux/globals.hpp"
-#include "supertux/menu/menu_storage.hpp"
 #include "supertux/menu/addon_menu.hpp"
-#include "supertux/menu/options_menu.hpp"
 #include "supertux/menu/contrib_menu.hpp"
+#include "supertux/menu/menu_storage.hpp"
+#include "supertux/menu/options_menu.hpp"
 #include "supertux/screen_fade.hpp"
 #include "supertux/screen_manager.hpp"
 #include "supertux/textscroller.hpp"
@@ -31,8 +32,7 @@
 #include "supertux/world.hpp"
 #include "util/gettext.hpp"
 
-MainMenu::MainMenu() :
-  m_main_world()
+MainMenu::MainMenu()
 {
   set_pos(SCREEN_WIDTH/2, SCREEN_HEIGHT/2 + 35);
   add_entry(MNID_STARTGAME, _("Start Game"));
@@ -52,7 +52,7 @@ MainMenu::check_menu()
       {
         std::unique_ptr<World> world(new World);
         world->load("levels/world1/info");
-        TitleScreen::start_game(std::move(world));
+        GameManager::current()->start_game(std::move(world));
       }
       break;
 
index fcd3424..ae5cd23 100644 (file)
@@ -170,27 +170,4 @@ TitleScreen::update(float elapsed_time)
   }
 }
 
-void
-TitleScreen::start_game(std::unique_ptr<World> world)
-{
-  MenuManager::instance().clear_menu_stack();
-
-  std::string basename = world->get_basedir();
-  basename = basename.substr(0, basename.length()-1);
-  std::string worlddirname = FileSystem::basename(basename);
-  std::ostringstream stream;
-  stream << "profile" << g_config->profile << "/" << worlddirname << ".stsg";
-  std::string slotfile = stream.str();
-
-  try
-  {
-    world->set_savegame_filename(slotfile);
-    world->run();
-  }
-  catch(std::exception& e)
-  {
-    log_fatal << "Couldn't start world: " << e.what() << std::endl;
-  }
-}
-
 /* EOF */
index 363cd9c..69354c1 100644 (file)
@@ -47,9 +47,6 @@ public:
 
   virtual void update(float elapsed_time);
 
-public:
-  static void start_game(std::unique_ptr<World> world);
-
 private:
   void make_tux_jump();
   
index be81688..f2e8300 100644 (file)
@@ -126,8 +126,6 @@ World::load(const std::string& filename)
 void
 World::run()
 {
-  using namespace scripting;
-
   current_ = this;
 
   // create new squirrel table for persistent game state
@@ -147,9 +145,9 @@ World::run()
     IFileStreambuf ins(filename);
     std::istream in(&ins);
 
-    sq_release(global_vm, &world_thread);
-    world_thread = create_thread(global_vm);
-    compile_and_run(object_to_vm(world_thread), in, filename);
+    sq_release(scripting::global_vm, &world_thread);
+    world_thread = scripting::create_thread(scripting::global_vm);
+    scripting::compile_and_run(scripting::object_to_vm(world_thread), in, filename);
   } catch(std::exception& ) {
     // fallback: try to load worldmap worldmap.stwm
     using namespace worldmap;