From 59a0c6591fed50fac5521f17cc8c78450691ad6d Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Thu, 13 Apr 2006 19:41:00 +0000 Subject: [PATCH] load default.nut for all scripts, have own roottable for console and load console.nut into it SVN-Revision: 3330 --- data/scripts/console.nut | 43 +++++++++++++++++++++++++++++++ data/{script => scripts}/default.nut | 5 ++++ src/console.cpp | 49 ++++++++++++++++++++++++++++++------ src/console.hpp | 4 +++ src/main.cpp | 4 +-- src/script_manager.cpp | 10 ++++++++ src/scripting/functions.hpp | 2 -- 7 files changed, 105 insertions(+), 12 deletions(-) create mode 100644 data/scripts/console.nut rename data/{script => scripts}/default.nut (63%) diff --git a/data/scripts/console.nut b/data/scripts/console.nut new file mode 100644 index 000000000..9170e458d --- /dev/null +++ b/data/scripts/console.nut @@ -0,0 +1,43 @@ +/** + * This script is loaded into the console script interpreter. + * You should define shortcuts and helper functions that are usefull for the + * console here + */ + +function flip() +{ + Level.flip_vertically(); +} + +function finish() +{ + Level.finish(true); +} + +function println(val) +{ + print(val); + print("\n"); +} + +/** + * Display a list of functions in the roottable (or in the table specified) + */ +function functions(...) +{ + local obj = this; + if(vargc == 1) + obj = vargv[0]; + if(::type(obj) == "instance") + obj = obj.getclass() + + while(obj != null) { + foreach(key, val in obj) { + if(::type(val) == "function") + println(key); + } + obj = obj.parent; + } +} + + diff --git a/data/script/default.nut b/data/scripts/default.nut similarity index 63% rename from data/script/default.nut rename to data/scripts/default.nut index f3543af00..fbfc8a875 100644 --- a/data/script/default.nut +++ b/data/scripts/default.nut @@ -1,3 +1,7 @@ +/** + * This script gets loaded into the squirrel root vm in supertux. So functions + * and variables you define here can be used in all threads + */ function end_level() { @@ -16,3 +20,4 @@ function levelflip() Level.flip_vertically(); Effect.fade_in(1); } + diff --git a/src/console.cpp b/src/console.cpp index 3b1633b0c..abb10d615 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -24,17 +24,19 @@ #include "video/surface.hpp" #include "scripting/squirrel_error.hpp" #include "scripting/wrapper_util.hpp" +#include "physfs/physfs_stream.hpp" #include "player_status.hpp" #include "script_manager.hpp" #include "main.hpp" +#include "log.hpp" #include "resources.hpp" /// speed (pixels/s) the console closes static const float FADE_SPEED = 1; Console::Console() - : backgroundOffset(0), height(0), alpha(1.0), offset(0), focused(false), - stayOpen(0) + : vm(NULL), backgroundOffset(0), height(0), alpha(1.0), offset(0), + focused(false), stayOpen(0) { font.reset(new Font("images/engine/fonts/white-small.png", "images/engine/fonts/shadow-small.png", 8, 9, 1)); @@ -44,6 +46,9 @@ Console::Console() Console::~Console() { + if(vm != NULL) { + sq_release(ScriptManager::instance->get_vm(), &vm_object); + } } void @@ -73,18 +78,46 @@ Console::execute_script(const std::string& command) { using namespace Scripting; - HSQUIRRELVM vm = ScriptManager::instance->get_vm(); - - if(command == "") - return; - + if(vm == NULL) { + vm = ScriptManager::instance->get_vm(); + HSQUIRRELVM new_vm = sq_newthread(vm, 16); + if(new_vm == NULL) + throw Scripting::SquirrelError(ScriptManager::instance->get_vm(), + "Couldn't create new VM thread for console"); + + // store reference to thread + sq_resetobject(&vm_object); + if(SQ_FAILED(sq_getstackobj(vm, -1, &vm_object))) + throw Scripting::SquirrelError(vm, "Couldn't get vm object for console"); + sq_addref(vm, &vm_object); + sq_pop(vm, 1); + + // create new roottable for thread + sq_newtable(new_vm); + sq_pushroottable(new_vm); + if(SQ_FAILED(sq_setdelegate(new_vm, -2))) + throw Scripting::SquirrelError(new_vm, "Couldn't set console_table delegate"); + + sq_setroottable(new_vm); + + vm = new_vm; + + try { + std::string filename = "scripts/console.nut"; + IFileStream stream(filename); + Scripting::compile_and_run(vm, stream, filename); + } catch(std::exception& e) { + log_warning << "Couldn't load console.nut: " << e.what() << std::endl; + } + } + int oldtop = sq_gettop(vm); try { if(SQ_FAILED(sq_compilebuffer(vm, command.c_str(), command.length(), "", SQTrue))) throw SquirrelError(vm, "Couldn't compile command"); - sq_pushroottable(vm); + sq_pushroottable(vm); if(SQ_FAILED(sq_call(vm, 1, SQTrue))) throw SquirrelError(vm, "Problem while executing command"); diff --git a/src/console.hpp b/src/console.hpp index e458926ce..ff9357126 100644 --- a/src/console.hpp +++ b/src/console.hpp @@ -26,6 +26,7 @@ #include #include #include +#include class Console; class ConsoleStreamBuffer; @@ -87,6 +88,9 @@ private: std::auto_ptr background; /**< console background image */ std::auto_ptr background2; /**< second, moving console background image */ + + HSQUIRRELVM vm; /**< squirrel thread for the console (with custom roottable */ + HSQOBJECT vm_object; int backgroundOffset; /**< current offset of scrolling background image */ float height; /**< height of the console in px */ diff --git a/src/main.cpp b/src/main.cpp index 6d5d9115b..0520a3119 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -540,8 +540,6 @@ int main(int argc, char** argv) main_loop = NULL; free_menu(); - delete ScriptManager::instance; - ScriptManager::instance = NULL; unload_shared(); quit_audio(); @@ -553,6 +551,8 @@ int main(int argc, char** argv) main_controller = NULL; delete Console::instance; Console::instance = NULL; + delete ScriptManager::instance; + ScriptManager::instance = NULL; delete texture_manager; texture_manager = NULL; SDL_Quit(); diff --git a/src/script_manager.cpp b/src/script_manager.cpp index d990d873c..14e659949 100644 --- a/src/script_manager.cpp +++ b/src/script_manager.cpp @@ -32,6 +32,7 @@ #include "timer.hpp" #include "console.hpp" +#include "log.hpp" #include "scripting/wrapper.hpp" #include "scripting/wrapper_util.hpp" #include "scripting/squirrel_error.hpp" @@ -75,6 +76,15 @@ ScriptManager::ScriptManager() sq_setprintfunc(vm, printfunc); // register default error handlers sqstd_seterrorhandlers(vm); + + // try to load default script + try { + std::string filename = "scripts/default.nut"; + IFileStream stream(filename); + Scripting::compile_and_run(vm, stream, filename); + } catch(std::exception& e) { + log_warning << "Couldn't load default.nut: " << e.what() << std::endl; + } } ScriptManager::ScriptManager(ScriptManager* parent) diff --git a/src/scripting/functions.hpp b/src/scripting/functions.hpp index eec7465d0..c374d440c 100644 --- a/src/scripting/functions.hpp +++ b/src/scripting/functions.hpp @@ -105,8 +105,6 @@ void debug_collrects(bool enable); */ void draw_solids_only(bool enable); -// ------- Items after this line were formerly in game_session.cpp - /** * speeds Tux up */ -- 2.11.0