load default.nut for all scripts, have own roottable for console and load console...
authorMatthias Braun <matze@braunis.de>
Thu, 13 Apr 2006 19:41:00 +0000 (19:41 +0000)
committerMatthias Braun <matze@braunis.de>
Thu, 13 Apr 2006 19:41:00 +0000 (19:41 +0000)
SVN-Revision: 3330

data/script/default.nut [deleted file]
data/scripts/console.nut [new file with mode: 0644]
data/scripts/default.nut [new file with mode: 0644]
src/console.cpp
src/console.hpp
src/main.cpp
src/script_manager.cpp
src/scripting/functions.hpp

diff --git a/data/script/default.nut b/data/script/default.nut
deleted file mode 100644 (file)
index f3543af..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-
-function end_level()
-{
-  Sound.play_music("music/leveldone.ogg");
-  Tux.deactivate();
-  wait(6);
-  Effect.fade_out(2);
-  wait(2);
-  Level.finish(true);
-}
-
-function levelflip()
-{
-  Effect.fade_out(1);
-  wait(1);
-  Level.flip_vertically();
-  Effect.fade_in(1);
-}
diff --git a/data/scripts/console.nut b/data/scripts/console.nut
new file mode 100644 (file)
index 0000000..9170e45
--- /dev/null
@@ -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/scripts/default.nut b/data/scripts/default.nut
new file mode 100644 (file)
index 0000000..fbfc8a8
--- /dev/null
@@ -0,0 +1,23 @@
+/**
+ * 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()
+{
+  Sound.play_music("music/leveldone.ogg");
+  Tux.deactivate();
+  wait(6);
+  Effect.fade_out(2);
+  wait(2);
+  Level.finish(true);
+}
+
+function levelflip()
+{
+  Effect.fade_out(1);
+  wait(1);
+  Level.flip_vertically();
+  Effect.fade_in(1);
+}
+
index 3b1633b..abb10d6 100644 (file)
 #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");
 
index e458926..ff93571 100644 (file)
@@ -26,6 +26,7 @@
 #include <string>
 #include <sstream>
 #include <iostream>
+#include <squirrel.h>
 
 class Console;
 class ConsoleStreamBuffer;
@@ -87,6 +88,9 @@ private:
   
   std::auto_ptr<Surface> background; /**< console background image */
   std::auto_ptr<Surface> 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 */
index 6d5d911..0520a31 100644 (file)
@@ -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();
index d990d87..14e6599 100644 (file)
@@ -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)
index eec7465..c374d44 100644 (file)
@@ -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
  */