Expose Objects on Worldmap in squirrel table "worldmap"
[supertux.git] / src / worldmap / worldmap.cpp
index cc4ec20..2a6b255 100644 (file)
@@ -36,6 +36,7 @@
 #include "shrinkfade.hpp"
 #include "video/surface.hpp"
 #include "video/drawing_context.hpp"
+#include "sprite/sprite.hpp"
 #include "sprite/sprite_manager.hpp"
 #include "audio/sound_manager.hpp"
 #include "lisp/parser.hpp"
@@ -153,8 +154,6 @@ WorldMap::WorldMap(const std::string& filename, const std::string& force_spawnpo
   worldmap_menu->add_hl();
   worldmap_menu->add_entry(MNID_QUITWORLDMAP, _("Quit World"));
 
-  load(filename);
-
   // create a new squirrel table for the worldmap
   using namespace Scripting;
 
@@ -170,6 +169,9 @@ WorldMap::WorldMap(const std::string& filename, const std::string& force_spawnpo
 
   sq_addref(global_vm, &worldmap_table);
   sq_pop(global_vm, 1);
+  
+  // load worldmap objects
+  load(filename);
 }
 
 WorldMap::~WorldMap()
@@ -178,6 +180,18 @@ WorldMap::~WorldMap()
 
   save_state();
 
+  for(GameObjects::iterator i = game_objects.begin();
+      i != game_objects.end(); ++i) {
+    GameObject* object = *i;
+    try_unexpose(object);
+    object->unref();
+  }
+
+  for(SpawnPoints::iterator i = spawn_points.begin();
+      i != spawn_points.end(); ++i) {
+    delete *i;
+  }
+
   for(ScriptList::iterator i = scripts.begin();
       i != scripts.end(); ++i) {
     HSQOBJECT& object = *i;
@@ -189,17 +203,6 @@ WorldMap::~WorldMap()
 
   if(current_ == this)
     current_ = NULL;
-
-  for(GameObjects::iterator i = game_objects.begin();
-      i != game_objects.end(); ++i) {
-    GameObject* object = *i;
-    object->unref();
-  }
-
-  for(SpawnPoints::iterator i = spawn_points.begin();
-      i != spawn_points.end(); ++i) {
-    delete *i;
-  }
 }
 
 void
@@ -211,10 +214,40 @@ WorldMap::add_object(GameObject* object)
   }
 
   object->ref();
+  try_expose(object);
   game_objects.push_back(object);
 }
 
 void
+WorldMap::try_expose(GameObject* object)
+{
+  ScriptInterface* interface = dynamic_cast<ScriptInterface*> (object);
+  if(interface != NULL) {
+    HSQUIRRELVM vm = Scripting::global_vm;
+    sq_pushobject(vm, worldmap_table);
+    interface->expose(vm, -1);
+    sq_pop(vm, 1);
+  }
+}
+
+void
+WorldMap::try_unexpose(GameObject* object)
+{
+  ScriptInterface* interface = dynamic_cast<ScriptInterface*> (object);
+  if(interface != NULL) {
+    HSQUIRRELVM vm = Scripting::global_vm;
+    SQInteger oldtop = sq_gettop(vm);
+    sq_pushobject(vm, worldmap_table);
+    try {
+      interface->unexpose(vm, -1);
+    } catch(std::exception& e) {
+      log_warning << "Couldn't unregister object: " << e.what() << std::endl;
+    }
+    sq_settop(vm, oldtop);
+  }
+}
+
+void
 WorldMap::move_to_spawnpoint(const std::string& spawnpoint)
 {
   for(SpawnPoints::iterator i = spawn_points.begin(); i != spawn_points.end(); ++i) {
@@ -247,7 +280,7 @@ WorldMap::load(const std::string& filename)
 
   try {
     lisp::Parser parser;
-    std::auto_ptr<lisp::Lisp> root (parser.parse(map_filename));
+    const lisp::Lisp* root = parser.parse(map_filename);
 
     const lisp::Lisp* lisp = root->get_lisp("supertux-level");
     if(!lisp)
@@ -323,7 +356,7 @@ WorldMap::get_level_title(LevelTile& level)
 
   try {
     lisp::Parser parser;
-    std::auto_ptr<lisp::Lisp> root (parser.parse(levels_path + level.get_name()));
+    const lisp::Lisp* root = parser.parse(levels_path + level.get_name());
 
     const lisp::Lisp* level_lisp = root->get_lisp("supertux-level");
     if(!level_lisp)
@@ -511,6 +544,7 @@ WorldMap::update(float delta)
         i != game_objects.end(); ) {
       GameObject* object = *i;
       if(!object->is_valid()) {
+        try_unexpose(object);
         object->unref();
         i = game_objects.erase(i);
       } else {