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?
#include "Environment.hpp"
#include "../world/ChunkLoader.hpp"
-#include <iostream>
-
namespace blank {
}
-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) {
--- /dev/null
+#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);
+}
+
+}
--- /dev/null
+#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
#include "WorldState.hpp"
#include "Environment.hpp"
+#include "UnloadState.hpp"
#include <SDL.h>
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;
}
void Application::Handle(const SDL_Event &event) {
switch (event.type) {
- case SDL_QUIT:
- env.state.PopAll();
- break;
case SDL_WINDOWEVENT:
Handle(event.window);
break;
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;
++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;