Fix extensive disk I/O when in worldmap (found using profiler)
[supertux.git] / src / worldmap / worldmap.cpp
index 09bb8b5..ef05003 100644 (file)
@@ -39,7 +39,7 @@
 #include "object/background.hpp"
 #include "object/decal.hpp"
 #include "object/tilemap.hpp"
-#include "physfs/ifile_stream.hpp"
+#include "physfs/ifile_streambuf.hpp"
 #include "scripting/squirrel_error.hpp"
 #include "scripting/squirrel_util.hpp"
 #include "sprite/sprite.hpp"
@@ -367,6 +367,11 @@ WorldMap::get_level_title(LevelTile& level)
 void
 WorldMap::get_level_target_time(LevelTile& level)
 {
+  if(last_position == tux->get_tile_pos()) {
+    level.target_time = last_target_time;
+    return;
+  }
+  
   try {
     lisp::Parser parser;
     const lisp::Lisp* root = parser.parse(levels_path + level.get_name());
@@ -376,6 +381,9 @@ WorldMap::get_level_target_time(LevelTile& level)
       return;
 
     level_lisp->get("target-time", level.target_time);
+
+    last_position = level.pos;
+    last_target_time = level.target_time;
   } catch(std::exception& e) {
     log_warning << "Problem when reading level target time: " << e.what() << std::endl;
     return;
@@ -482,7 +490,8 @@ WorldMap::finished_level(Level* gamelevel)
   get_level_target_time(*level);
   if(level->statistics.completed(level->statistics, level->target_time)) {
     level->perfect = true;
-    level->sprite->set_action("perfect");
+    if(level->sprite->has_action("perfect"))
+      level->sprite->set_action("perfect");
   }
 
   save_state();
@@ -926,7 +935,8 @@ WorldMap::setup()
 
   //Run default.nut just before init script
   try {
-    IFileStream in(levels_path + "/default.nut");
+    IFileStreambuf ins(levels_path + "default.nut");
+    std::istream in(&ins);
     run_script(in, "WorldMap::default.nut");
   } catch(std::exception& ) {
     // doesn't exist or erroneous; do nothing