Added Scripting class to bundle up all the Squirrel init code
authorIngo Ruhnke <grumbel@gmail.com>
Sun, 17 Aug 2014 19:51:26 +0000 (21:51 +0200)
committerIngo Ruhnke <grumbel@gmail.com>
Sun, 17 Aug 2014 20:34:31 +0000 (22:34 +0200)
14 files changed:
src/scripting/scripting.cpp [new file with mode: 0644]
src/scripting/scripting.hpp [new file with mode: 0644]
src/scripting/squirrel_util.cpp
src/scripting/squirrel_util.hpp
src/scripting/thread_queue.cpp
src/scripting/time_scheduler.cpp
src/supertux/console.cpp
src/supertux/game_session.cpp
src/supertux/main.cpp
src/supertux/main.hpp
src/supertux/savegame.cpp
src/supertux/screen_manager.cpp
src/supertux/sector.cpp
src/worldmap/worldmap.cpp

diff --git a/src/scripting/scripting.cpp b/src/scripting/scripting.cpp
new file mode 100644 (file)
index 0000000..a70f2fd
--- /dev/null
@@ -0,0 +1,139 @@
+//  SuperTux
+//  Copyright (C) 2014 Ingo Ruhnke <grumbel@gmail.com>
+//
+//  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 "scripting/scripting.hpp"
+
+#include <sqstdaux.h>
+#include <sqstdblob.h>
+#include <sqstdmath.h>
+#include <sqstdstring.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "physfs/ifile_stream.hpp"
+#include "scripting/squirrel_error.hpp"
+#include "scripting/wrapper.hpp"
+#include "squirrel_util.hpp"
+#include "supertux/console.hpp"
+#include "util/log.hpp"
+
+#ifdef ENABLE_SQDBG
+#  include "../../external/squirrel/sqdbg/sqrdbg.h"
+namespace {
+HSQREMOTEDBG debugger = NULL;
+} // namespace
+#endif
+
+namespace {
+
+void printfunc(HSQUIRRELVM, const char* str, ...)
+{
+  char buf[4096];
+  va_list arglist;
+  va_start(arglist, str);
+  vsnprintf(buf, sizeof(buf), str, arglist);
+  ConsoleBuffer::output << (const char*) buf << std::flush;
+  va_end(arglist);
+}
+
+} // namespace
+
+namespace scripting {
+
+HSQUIRRELVM global_vm = NULL;
+
+Scripting::Scripting(bool enable_debugger)
+{
+  global_vm = sq_open(64);
+  if(global_vm == NULL)
+    throw std::runtime_error("Couldn't initialize squirrel vm");
+
+  if(enable_debugger) {
+#ifdef ENABLE_SQDBG
+    sq_enabledebuginfo(global_vm, SQTrue);
+    debugger = sq_rdbg_init(global_vm, 1234, SQFalse);
+    if(debugger == NULL)
+      throw SquirrelError(global_vm, "Couldn't initialize squirrel debugger");
+
+    sq_enabledebuginfo(global_vm, SQTrue);
+    log_info << "Waiting for debug client..." << std::endl;
+    if(SQ_FAILED(sq_rdbg_waitforconnections(debugger)))
+      throw SquirrelError(global_vm, "Waiting for debug clients failed");
+    log_info << "debug client connected." << std::endl;
+#endif
+  }
+
+  sq_pushroottable(global_vm);
+  if(SQ_FAILED(sqstd_register_bloblib(global_vm)))
+    throw SquirrelError(global_vm, "Couldn't register blob lib");
+  if(SQ_FAILED(sqstd_register_mathlib(global_vm)))
+    throw SquirrelError(global_vm, "Couldn't register math lib");
+  if(SQ_FAILED(sqstd_register_stringlib(global_vm)))
+    throw SquirrelError(global_vm, "Couldn't register string lib");
+
+  // remove rand and srand calls from sqstdmath, we'll provide our own
+  sq_pushstring(global_vm, "srand", -1);
+  sq_deleteslot(global_vm, -2, SQFalse);
+  sq_pushstring(global_vm, "rand", -1);
+  sq_deleteslot(global_vm, -2, SQFalse);
+
+  // register supertux API
+  register_supertux_wrapper(global_vm);
+
+  sq_pop(global_vm, 1);
+
+  // register print function
+  sq_setprintfunc(global_vm, printfunc, printfunc);
+  // register default error handlers
+  sqstd_seterrorhandlers(global_vm);
+
+  // try to load default script
+  try {
+    std::string filename = "scripts/default.nut";
+    IFileStream stream(filename);
+    scripting::compile_and_run(global_vm, stream, filename);
+  } catch(std::exception& e) {
+    log_warning << "Couldn't load default.nut: " << e.what() << std::endl;
+  }
+}
+
+Scripting::~Scripting()
+{
+#ifdef ENABLE_SQDBG
+  if(debugger != NULL) {
+    sq_rdbg_shutdown(debugger);
+    debugger = NULL;
+  }
+#endif
+
+  if (global_vm)
+    sq_close(global_vm);
+
+  global_vm = NULL;
+}
+  
+void
+Scripting::update_debugger()
+{
+#ifdef ENABLE_SQDBG
+  if(debugger != NULL)
+    sq_rdbg_update(debugger);
+#endif
+}
+
+} // namespace scripting
+
+/* EOF */
diff --git a/src/scripting/scripting.hpp b/src/scripting/scripting.hpp
new file mode 100644 (file)
index 0000000..5f985b4
--- /dev/null
@@ -0,0 +1,46 @@
+//  SuperTux
+//  Copyright (C) 2014 Ingo Ruhnke <grumbel@gmail.com>
+//
+//  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_SCRIPTING_SCRIPTING_HPP
+#define HEADER_SUPERTUX_SCRIPTING_SCRIPTING_HPP
+
+#include <squirrel.h>
+
+#include "util/currenton.hpp"
+
+namespace scripting {
+
+extern HSQUIRRELVM global_vm;
+
+class Scripting : public Currenton<Scripting>
+{
+private:
+public:
+  Scripting(bool enable_debugger);
+  ~Scripting();
+  
+  void update_debugger();
+
+private:
+  Scripting(const Scripting&) = delete;
+  Scripting& operator=(const Scripting&) = delete;
+};
+
+} // namespace scripting
+
+#endif
+
+/* EOF */
index 9e80aed..ddf671c 100644 (file)
 #include <sqstdstring.h>
 #include <stdarg.h>
 
-#include "physfs/ifile_stream.hpp"
-#include "supertux/console.hpp"
-#include "util/log.hpp"
-
-#ifdef ENABLE_SQDBG
-#  include "../../external/squirrel/sqdbg/sqrdbg.h"
-static HSQREMOTEDBG debugger = NULL;
-#endif
-
 namespace scripting {
 
-HSQUIRRELVM global_vm = NULL;
-
-static void printfunc(HSQUIRRELVM, const char* str, ...)
-{
-  char buf[4096];
-  va_list arglist;
-  va_start(arglist, str);
-  vsnprintf(buf, sizeof(buf), str, arglist);
-  ConsoleBuffer::output << (const char*) buf << std::flush;
-  va_end(arglist);
-}
-
-void init_squirrel(bool enable_debugger)
-{
-  global_vm = sq_open(64);
-  if(global_vm == NULL)
-    throw std::runtime_error("Couldn't initialize squirrel vm");
-
-  if(enable_debugger) {
-#ifdef ENABLE_SQDBG
-    sq_enabledebuginfo(global_vm, SQTrue);
-    debugger = sq_rdbg_init(global_vm, 1234, SQFalse);
-    if(debugger == NULL)
-      throw SquirrelError(global_vm, "Couldn't initialize squirrel debugger");
-
-    sq_enabledebuginfo(global_vm, SQTrue);
-    log_info << "Waiting for debug client..." << std::endl;
-    if(SQ_FAILED(sq_rdbg_waitforconnections(debugger)))
-      throw SquirrelError(global_vm, "Waiting for debug clients failed");
-    log_info << "debug client connected." << std::endl;
-#endif
-  }
-
-  sq_pushroottable(global_vm);
-  if(SQ_FAILED(sqstd_register_bloblib(global_vm)))
-    throw SquirrelError(global_vm, "Couldn't register blob lib");
-  if(SQ_FAILED(sqstd_register_mathlib(global_vm)))
-    throw SquirrelError(global_vm, "Couldn't register math lib");
-  if(SQ_FAILED(sqstd_register_stringlib(global_vm)))
-    throw SquirrelError(global_vm, "Couldn't register string lib");
-
-  // remove rand and srand calls from sqstdmath, we'll provide our own
-  sq_pushstring(global_vm, "srand", -1);
-  sq_deleteslot(global_vm, -2, SQFalse);
-  sq_pushstring(global_vm, "rand", -1);
-  sq_deleteslot(global_vm, -2, SQFalse);
-
-  // register supertux API
-  register_supertux_wrapper(global_vm);
-
-  sq_pop(global_vm, 1);
-
-  // register print function
-  sq_setprintfunc(global_vm, printfunc, printfunc);
-  // register default error handlers
-  sqstd_seterrorhandlers(global_vm);
-
-  // try to load default script
-  try {
-    std::string filename = "scripts/default.nut";
-    IFileStream stream(filename);
-    scripting::compile_and_run(global_vm, stream, filename);
-  } catch(std::exception& e) {
-    log_warning << "Couldn't load default.nut: " << e.what() << std::endl;
-  }
-}
-
-void exit_squirrel()
-{
-#ifdef ENABLE_SQDBG
-  if(debugger != NULL) {
-    sq_rdbg_shutdown(debugger);
-    debugger = NULL;
-  }
-#endif
-
-  if (global_vm)
-    sq_close(global_vm);
-
-  global_vm = NULL;
-}
-
-void update_debugger()
-{
-#ifdef ENABLE_SQDBG
-  if(debugger != NULL)
-    sq_rdbg_update(debugger);
-#endif
-}
-
 std::string squirrel2string(HSQUIRRELVM v, SQInteger i)
 {
   std::ostringstream os;
index aac6492..6658721 100644 (file)
 
 namespace scripting {
 
-extern HSQUIRRELVM global_vm;
-
-void init_squirrel(bool enable_debugger);
-void exit_squirrel();
-void update_debugger();
-
 std::string squirrel2string(HSQUIRRELVM vm, SQInteger i);
 void print_squirrel_stack(HSQUIRRELVM vm);
 
index 8616243..277eff1 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "scripting/thread_queue.hpp"
 
+#include "scripting/scripting.hpp"
 #include "scripting/squirrel_util.hpp"
 #include "util/log.hpp"
 
index b210371..836c184 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <algorithm>
 
+#include "scripting/scripting.hpp"
 #include "scripting/squirrel_util.hpp"
 #include "scripting/time_scheduler.hpp"
 #include "util/log.hpp"
index 6b866b2..9f17267 100644 (file)
@@ -20,6 +20,7 @@
 #include <iostream>
 
 #include "physfs/ifile_stream.hpp"
+#include "scripting/scripting.hpp"
 #include "scripting/squirrel_util.hpp"
 #include "supertux/gameconfig.hpp"
 #include "supertux/globals.hpp"
index 8b0794c..0dd39b8 100644 (file)
@@ -30,6 +30,8 @@
 #include "object/endsequence_walkright.hpp"
 #include "object/level_time.hpp"
 #include "object/player.hpp"
+#include "scripting/scripting.hpp"
+#include "scripting/squirrel_util.hpp"
 #include "scripting/squirrel_util.hpp"
 #include "supertux/gameconfig.hpp"
 #include "supertux/globals.hpp"
index 43e684d..b1e7563 100644 (file)
@@ -38,6 +38,7 @@ extern "C" {
 #include "physfs/physfs_file_system.hpp"
 #include "physfs/physfs_sdl.hpp"
 #include "scripting/squirrel_util.hpp"
+#include "scripting/scripting.hpp"
 #include "sprite/sprite_manager.hpp"
 #include "supertux/command_line_arguments.hpp"
 #include "supertux/game_manager.hpp"
@@ -55,22 +56,36 @@ extern "C" {
 #include "video/renderer.hpp"
 #include "worldmap/worldmap.hpp"
 
-void
-Main::init_config()
+class ConfigSubsystem
 {
-  g_config.reset(new Config);
-  try {
-    g_config->load();
-  } catch(const std::exception& e) {
-    log_info << "Couldn't load config file: " << e.what() << ", using default settings" << std::endl;
+public:
+  ConfigSubsystem()
+  {
+    g_config.reset(new Config);
+    try {
+      g_config->load();
+    } 
+    catch(const std::exception& e) 
+    {
+      log_info << "Couldn't load config file: " << e.what() << ", using default settings" << std::endl;
+    }
+
+    // init random number stuff
+    g_config->random_seed = gameRandom.srand(g_config->random_seed);
+    graphicsRandom.srand(0);
+    //const char *how = config->random_seed? ", user fixed.": ", from time().";
+    //log_info << "Using random seed " << config->random_seed << how << std::endl;
   }
 
-  // init random number stuff
-  g_config->random_seed = gameRandom.srand(g_config->random_seed);
-  graphicsRandom.srand(0);
-  //const char *how = config->random_seed? ", user fixed.": ", from time().";
-  //log_info << "Using random seed " << config->random_seed << how << std::endl;
-}
+  ~ConfigSubsystem()
+  {
+    if (g_config)
+    {
+      g_config->save();
+    }
+    g_config.reset();  
+  }
+};
 
 void
 Main::init_tinygettext()
@@ -286,7 +301,7 @@ Main::launch_game()
   Console console(console_buffer);
 
   timelog("scripting");
-  scripting::init_squirrel(g_config->enable_script_debugger);
+  scripting::Scripting scripting(g_config->enable_script_debugger);
 
   timelog("resources");
   TileManager tile_manager;
@@ -325,8 +340,9 @@ Main::launch_game()
       std::unique_ptr<GameSession> session (
         new GameSession(FileSystem::basename(g_config->start_level), *default_savegame));
 
-      g_config->random_seed =session->get_demo_random_seed(g_config->start_demo);
-      init_rand();//initialise generator with seed from session
+      g_config->random_seed = session->get_demo_random_seed(g_config->start_demo);
+      g_config->random_seed = gameRandom.srand(g_config->random_seed);
+      graphicsRandom.srand(0);
 
       if(g_config->start_demo != "")
         session->play_demo(g_config->start_demo);
@@ -362,23 +378,12 @@ Main::run(int argc, char** argv)
     }
     catch(const std::exception& err)
     {
-      try
-      {
-        init_config();
-        args.merge_into(*g_config);
-        init_tinygettext();
-      }
-      catch(const std::exception& err_)
-      {
-        log_fatal << "failed to init config or tinygettext: " << err_.what() << std::endl;
-      }
-
       std::cout << "Error: " << err.what() << std::endl;
       return EXIT_FAILURE;
     }
 
     timelog("config");
-    init_config();
+    ConfigSubsystem config_subsystem;
     args.merge_into(*g_config);
 
     timelog("tinygettext");
@@ -414,12 +419,6 @@ Main::run(int argc, char** argv)
     result = 1;
   }
 
-  if(g_config)
-    g_config->save();
-  g_config.reset();
-
-  scripting::exit_squirrel();
-
   g_dictionary_manager.reset();
 
   return result;
index 7a2185f..7e1b406 100644 (file)
@@ -26,7 +26,6 @@
 class Main
 {
 private:
-  void init_config();
   void init_tinygettext();
   void init_video();
 
index 18e80c0..df484ec 100644 (file)
@@ -21,9 +21,9 @@
 #include "lisp/parser.hpp"
 #include "lisp/writer.hpp"
 #include "physfs/ifile_streambuf.hpp"
+#include "scripting/scripting.hpp"
 #include "scripting/serialize.hpp"
 #include "scripting/squirrel_util.hpp"
-#include "scripting/squirrel_util.hpp"
 #include "supertux/player_status.hpp"
 #include "util/file_system.hpp"
 #include "util/log.hpp"
index 8453cbc..4e7b520 100644 (file)
@@ -21,6 +21,7 @@
 #include "control/input_manager.hpp"
 #include "gui/menu.hpp"
 #include "gui/menu_manager.hpp"
+#include "scripting/scripting.hpp"
 #include "scripting/squirrel_util.hpp"
 #include "scripting/time_scheduler.hpp"
 #include "supertux/console.hpp"
@@ -169,7 +170,7 @@ ScreenManager::draw(DrawingContext& context)
 void
 ScreenManager::update_gamelogic(float elapsed_time)
 {
-  scripting::update_debugger();
+  scripting::Scripting::current()->update_debugger();
   scripting::TimeScheduler::instance->update(game_time);
 
   if (!m_screen_stack.empty())
index a87b900..519a2f4 100644 (file)
@@ -46,6 +46,7 @@
 #include "object/text_object.hpp"
 #include "object/tilemap.hpp"
 #include "physfs/ifile_streambuf.hpp"
+#include "scripting/scripting.hpp"
 #include "scripting/squirrel_util.hpp"
 #include "supertux/collision.hpp"
 #include "supertux/constants.hpp"
index 9f71f16..0b9a477 100644 (file)
 #include "object/decal.hpp"
 #include "object/tilemap.hpp"
 #include "physfs/ifile_streambuf.hpp"
+#include "scripting/scripting.hpp"
 #include "scripting/squirrel_error.hpp"
 #include "scripting/squirrel_util.hpp"
 #include "sprite/sprite.hpp"
 #include "sprite/sprite_manager.hpp"
 #include "supertux/game_session.hpp"
 #include "supertux/globals.hpp"
-#include "supertux/screen_manager.hpp"
 #include "supertux/menu/menu_storage.hpp"
 #include "supertux/menu/options_menu.hpp"
 #include "supertux/menu/worldmap_menu.hpp"
 #include "supertux/player_status.hpp"
 #include "supertux/resources.hpp"
+#include "supertux/savegame.hpp"
+#include "supertux/screen_manager.hpp"
 #include "supertux/sector.hpp"
 #include "supertux/shrinkfade.hpp"
 #include "supertux/spawn_point.hpp"
@@ -59,7 +61,6 @@
 #include "supertux/tile_manager.hpp"
 #include "supertux/tile_set.hpp"
 #include "supertux/world.hpp"
-#include "supertux/savegame.hpp"
 #include "util/file_system.hpp"
 #include "util/gettext.hpp"
 #include "util/log.hpp"
@@ -72,6 +73,7 @@
 #include "worldmap/tux.hpp"
 #include "worldmap/worldmap.hpp"
 
+
 static const float CAMERA_PAN_SPEED = 5.0;
 
 namespace worldmap {