From 04270f0886aa08cb8fee7dba58d41975ddb1cb72 Mon Sep 17 00:00:00 2001 From: Ingo Ruhnke Date: Sun, 17 Aug 2014 21:51:26 +0200 Subject: [PATCH] Added Scripting class to bundle up all the Squirrel init code --- src/scripting/scripting.cpp | 139 +++++++++++++++++++++++++++++++++++++++ src/scripting/scripting.hpp | 46 +++++++++++++ src/scripting/squirrel_util.cpp | 99 ---------------------------- src/scripting/squirrel_util.hpp | 6 -- src/scripting/thread_queue.cpp | 1 + src/scripting/time_scheduler.cpp | 1 + src/supertux/console.cpp | 1 + src/supertux/game_session.cpp | 2 + src/supertux/main.cpp | 67 ++++++++++--------- src/supertux/main.hpp | 1 - src/supertux/savegame.cpp | 2 +- src/supertux/screen_manager.cpp | 3 +- src/supertux/sector.cpp | 1 + src/worldmap/worldmap.cpp | 6 +- 14 files changed, 231 insertions(+), 144 deletions(-) create mode 100644 src/scripting/scripting.cpp create mode 100644 src/scripting/scripting.hpp diff --git a/src/scripting/scripting.cpp b/src/scripting/scripting.cpp new file mode 100644 index 000000000..a70f2fda0 --- /dev/null +++ b/src/scripting/scripting.cpp @@ -0,0 +1,139 @@ +// SuperTux +// Copyright (C) 2014 Ingo Ruhnke +// +// 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 . + +#include "scripting/scripting.hpp" + +#include +#include +#include +#include +#include +#include + +#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 index 000000000..5f985b462 --- /dev/null +++ b/src/scripting/scripting.hpp @@ -0,0 +1,46 @@ +// SuperTux +// Copyright (C) 2014 Ingo Ruhnke +// +// 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 . + +#ifndef HEADER_SUPERTUX_SCRIPTING_SCRIPTING_HPP +#define HEADER_SUPERTUX_SCRIPTING_SCRIPTING_HPP + +#include + +#include "util/currenton.hpp" + +namespace scripting { + +extern HSQUIRRELVM global_vm; + +class Scripting : public Currenton +{ +private: +public: + Scripting(bool enable_debugger); + ~Scripting(); + + void update_debugger(); + +private: + Scripting(const Scripting&) = delete; + Scripting& operator=(const Scripting&) = delete; +}; + +} // namespace scripting + +#endif + +/* EOF */ diff --git a/src/scripting/squirrel_util.cpp b/src/scripting/squirrel_util.cpp index 9e80aedac..ddf671ce8 100644 --- a/src/scripting/squirrel_util.cpp +++ b/src/scripting/squirrel_util.cpp @@ -25,107 +25,8 @@ #include #include -#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; diff --git a/src/scripting/squirrel_util.hpp b/src/scripting/squirrel_util.hpp index aac6492f5..6658721e2 100644 --- a/src/scripting/squirrel_util.hpp +++ b/src/scripting/squirrel_util.hpp @@ -24,12 +24,6 @@ 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); diff --git a/src/scripting/thread_queue.cpp b/src/scripting/thread_queue.cpp index 86162431a..277eff12b 100644 --- a/src/scripting/thread_queue.cpp +++ b/src/scripting/thread_queue.cpp @@ -16,6 +16,7 @@ #include "scripting/thread_queue.hpp" +#include "scripting/scripting.hpp" #include "scripting/squirrel_util.hpp" #include "util/log.hpp" diff --git a/src/scripting/time_scheduler.cpp b/src/scripting/time_scheduler.cpp index b210371ff..836c18403 100644 --- a/src/scripting/time_scheduler.cpp +++ b/src/scripting/time_scheduler.cpp @@ -16,6 +16,7 @@ #include +#include "scripting/scripting.hpp" #include "scripting/squirrel_util.hpp" #include "scripting/time_scheduler.hpp" #include "util/log.hpp" diff --git a/src/supertux/console.cpp b/src/supertux/console.cpp index 6b866b25d..9f1726764 100644 --- a/src/supertux/console.cpp +++ b/src/supertux/console.cpp @@ -20,6 +20,7 @@ #include #include "physfs/ifile_stream.hpp" +#include "scripting/scripting.hpp" #include "scripting/squirrel_util.hpp" #include "supertux/gameconfig.hpp" #include "supertux/globals.hpp" diff --git a/src/supertux/game_session.cpp b/src/supertux/game_session.cpp index 8b0794c71..0dd39b829 100644 --- a/src/supertux/game_session.cpp +++ b/src/supertux/game_session.cpp @@ -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" diff --git a/src/supertux/main.cpp b/src/supertux/main.cpp index 43e684d6a..b1e75632f 100644 --- a/src/supertux/main.cpp +++ b/src/supertux/main.cpp @@ -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 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; diff --git a/src/supertux/main.hpp b/src/supertux/main.hpp index 7a2185f26..7e1b406d9 100644 --- a/src/supertux/main.hpp +++ b/src/supertux/main.hpp @@ -26,7 +26,6 @@ class Main { private: - void init_config(); void init_tinygettext(); void init_video(); diff --git a/src/supertux/savegame.cpp b/src/supertux/savegame.cpp index 18e80c0d4..df484ec59 100644 --- a/src/supertux/savegame.cpp +++ b/src/supertux/savegame.cpp @@ -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" diff --git a/src/supertux/screen_manager.cpp b/src/supertux/screen_manager.cpp index 8453cbc4b..4e7b520d3 100644 --- a/src/supertux/screen_manager.cpp +++ b/src/supertux/screen_manager.cpp @@ -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()) diff --git a/src/supertux/sector.cpp b/src/supertux/sector.cpp index a87b900f4..519a2f4c8 100644 --- a/src/supertux/sector.cpp +++ b/src/supertux/sector.cpp @@ -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" diff --git a/src/worldmap/worldmap.cpp b/src/worldmap/worldmap.cpp index 9f71f16eb..0b9a47751 100644 --- a/src/worldmap/worldmap.cpp +++ b/src/worldmap/worldmap.cpp @@ -40,18 +40,20 @@ #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 { -- 2.11.0