]> git.localhorst.tv Git - blank.git/commitdiff
try to get every chunk change saved to disk
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 10 Aug 2015 15:35:46 +0000 (17:35 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 10 Aug 2015 15:35:46 +0000 (17:35 +0200)
TODO
src/app/PreloadState.cpp
src/app/UnloadState.cpp [new file with mode: 0644]
src/app/UnloadState.hpp [new file with mode: 0644]
src/app/WorldState.cpp
src/app/app.cpp
src/world/ChunkLoader.hpp
src/world/chunk.cpp

diff --git a/TODO b/TODO
index 4377b24c543f90d6dff8e8c79e4b61c56d14de3d..33a5c8de0e9bfbb26ab7e204c46ba9767158aab9 100644 (file)
--- a/TODO
+++ b/TODO
@@ -27,7 +27,8 @@ command line
 
 persistence
 
-       add world shutdown state to save dirty chunks when exiting
+       merge IO counters, so number of operations per frame is kept
+       low, no matter what exactly is done
 
        store some kind of byte order mark?
 
index 32d0b3a7fb86b8f630753fdfa854f29250bd6af5..389d331bd6034167e755edaad1470d908df17c17 100644 (file)
@@ -3,8 +3,6 @@
 #include "Environment.hpp"
 #include "../world/ChunkLoader.hpp"
 
-#include <iostream>
-
 
 namespace blank {
 
@@ -20,7 +18,10 @@ PreloadState::PreloadState(Environment &env, ChunkLoader &loader)
 }
 
 
-void PreloadState::Handle(const SDL_Event &) {
+void PreloadState::Handle(const SDL_Event &e) {
+       if (e.type == SDL_QUIT) {
+               env.state.PopAll();
+       }
 }
 
 void PreloadState::Update(int dt) {
diff --git a/src/app/UnloadState.cpp b/src/app/UnloadState.cpp
new file mode 100644 (file)
index 0000000..49801bf
--- /dev/null
@@ -0,0 +1,46 @@
+#include "UnloadState.hpp"
+
+#include "Environment.hpp"
+#include "../world/ChunkLoader.hpp"
+#include "../world/WorldSave.hpp"
+
+
+namespace blank {
+
+UnloadState::UnloadState(Environment &env, ChunkLoader &loader)
+: env(env)
+, loader(loader)
+, font(env.assets.LoadFont("DejaVuSans", 24))
+, progress(font)
+, cur(loader.Loaded().begin())
+, end(loader.Loaded().end())
+, done(0)
+, total(loader.Loaded().size())
+, per_update(64) {
+       progress.Position(glm::vec3(0.0f), Gravity::CENTER);
+       progress.Template("Unloading chunks: %d/%d (%d%%)");
+}
+
+
+void UnloadState::Handle(const SDL_Event &) {
+       // ignore everything
+}
+
+void UnloadState::Update(int dt) {
+       for (std::size_t i = 0; i < per_update && cur != end; ++i, ++cur, ++done) {
+               if (cur->ShouldUpdateSave()) {
+                       loader.SaveFile().Write(*cur);
+               }
+       }
+       if (cur == end) {
+               env.state.PopAll();
+       } else {
+               progress.Update(done, total);
+       }
+}
+
+void UnloadState::Render(Viewport &viewport) {
+       progress.Render(viewport);
+}
+
+}
diff --git a/src/app/UnloadState.hpp b/src/app/UnloadState.hpp
new file mode 100644 (file)
index 0000000..56394bb
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef BLANK_APP_PRELOADSTATE_HPP_
+#define BLANK_APP_PRELOADSTATE_HPP_
+
+#include "State.hpp"
+
+#include "../ui/Progress.hpp"
+#include "../graphics/Font.hpp"
+
+#include <cstddef>
+#include <list>
+
+
+namespace blank {
+
+class Chunk;
+class ChunkLoader;
+class Environment;
+
+class UnloadState
+: public State {
+
+public:
+       UnloadState(Environment &, ChunkLoader &);
+
+       void Handle(const SDL_Event &) override;
+       void Update(int dt) override;
+       void Render(Viewport &) override;
+
+private:
+       Environment &env;
+       ChunkLoader &loader;
+       Font font;
+       Progress progress;
+       std::list<Chunk>::iterator cur;
+       std::list<Chunk>::iterator end;
+       std::size_t done;
+       std::size_t total;
+       std::size_t per_update;
+
+};
+
+}
+
+#endif
index 12e142ac5a4cfe086f50e084d725162144a464d3..86e3eac93bdaa619fd344d7709f92b6ff4a65421 100644 (file)
@@ -1,6 +1,7 @@
 #include "WorldState.hpp"
 
 #include "Environment.hpp"
+#include "UnloadState.hpp"
 
 #include <SDL.h>
 
@@ -41,6 +42,10 @@ void WorldState::Handle(const SDL_Event &event) {
                case SDL_MOUSEWHEEL:
                        interface.Handle(event.wheel);
                        break;
+               case SDL_QUIT:
+                       // don't care about this leak just now
+                       env.state.Switch(new UnloadState(env, world.Loader()));
+                       break;
                default:
                        break;
        }
index f3c9115faedf3b50c96002efe1c231ee0e0547ed..4a4769b4c688ae4cd7462e983040474536fd4ee3 100644 (file)
@@ -96,9 +96,6 @@ void Application::HandleEvents() {
 
 void Application::Handle(const SDL_Event &event) {
        switch (event.type) {
-               case SDL_QUIT:
-                       env.state.PopAll();
-                       break;
                case SDL_WINDOWEVENT:
                        Handle(event.window);
                        break;
index 81e7178a5f4c4bb203b1a8a5ce72317d8e67823d..7cc8dfca917cce00ad8234d9f4339126173f2c7f 100644 (file)
@@ -33,6 +33,7 @@ public:
        void QueueSurrounding(const Chunk::Pos &);
 
        std::list<Chunk> &Loaded() noexcept { return loaded; }
+       const WorldSave &SaveFile() const noexcept { return save; }
 
        Chunk *Loaded(const Chunk::Pos &) noexcept;
        bool Queued(const Chunk::Pos &) noexcept;
index 2d5b7cec853272f1868da71b069760156ab8ca74..31dfe80b3134bb1a9dea1ba29a4df28c2df317e8 100644 (file)
@@ -772,6 +772,10 @@ std::list<Chunk>::iterator ChunkLoader::Remove(std::list<Chunk>::iterator chunk)
        ++next;
        // unlink neighbors so they won't reference a dead chunk
        chunk->ClearNeighbors();
+       // if it should be saved, do it now
+       if (chunk->ShouldUpdateSave()) {
+               save.Write(*chunk);
+       }
        // and move it from loaded to free list
        to_free.splice(to_free.end(), loaded, chunk);
        return next;