From 22b25d4b9cc24e249bc8007757267cea00ab18d3 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Thu, 6 Aug 2015 12:34:56 +0200 Subject: [PATCH] simple preloader --- src/app/PreloadState.cpp | 39 +++++++++++++++++++++++++++++++++++++++ src/app/PreloadState.hpp | 33 +++++++++++++++++++++++++++++++++ src/app/WorldState.hpp | 2 ++ src/app/runtime.cpp | 8 ++++++-- src/world/ChunkLoader.hpp | 4 ++++ src/world/World.hpp | 3 ++- src/world/chunk.cpp | 15 +++++++++++++-- 7 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 src/app/PreloadState.cpp create mode 100644 src/app/PreloadState.hpp diff --git a/src/app/PreloadState.cpp b/src/app/PreloadState.cpp new file mode 100644 index 0000000..c56e4fe --- /dev/null +++ b/src/app/PreloadState.cpp @@ -0,0 +1,39 @@ +#include "PreloadState.hpp" + +#include "Environment.hpp" +#include "../world/ChunkLoader.hpp" + +#include + + +namespace blank { + +PreloadState::PreloadState(Environment &env, ChunkLoader &loader) +: env(env) +, loader(loader) +, per_update(256) { + +} + + +void PreloadState::Handle(const SDL_Event &) { +} + +void PreloadState::Update(int dt) { + loader.LoadN(per_update); + if (loader.ToLoad() == 0) { + std::cout << "preload: populating VBOs" << std::endl; + for (auto &chunk : loader.Loaded()) { + chunk.CheckUpdate(); + } + std::cout << "preload: complete" << std::endl; + env.state.Pop(); + } +} + +void PreloadState::Render(Viewport &) { + // TODO: make a nice progress bar or some other fancy shit + std::cout << "preload: " << loader.ToLoad() << " chunks remaining" << std::endl; +} + +} diff --git a/src/app/PreloadState.hpp b/src/app/PreloadState.hpp new file mode 100644 index 0000000..2c85f98 --- /dev/null +++ b/src/app/PreloadState.hpp @@ -0,0 +1,33 @@ +#ifndef BLANK_APP_PRELOADSTATE_HPP_ +#define BLANK_APP_PRELOADSTATE_HPP_ + +#include "State.hpp" + +#include + + +namespace blank { + +class ChunkLoader; +class Environment; + +class PreloadState +: public State { + +public: + PreloadState(Environment &, ChunkLoader &); + + void Handle(const SDL_Event &) override; + void Update(int dt) override; + void Render(Viewport &) override; + +private: + Environment &env; + ChunkLoader &loader; + std::size_t per_update; + +}; + +} + +#endif diff --git a/src/app/WorldState.hpp b/src/app/WorldState.hpp index 38922ff..e4edd12 100644 --- a/src/app/WorldState.hpp +++ b/src/app/WorldState.hpp @@ -25,6 +25,8 @@ public: void Update(int dt) override; void Render(Viewport &) override; + World &GetWorld() noexcept { return world; } + private: Environment &env; World world; diff --git a/src/app/runtime.cpp b/src/app/runtime.cpp index 37cca50..eaeea8d 100644 --- a/src/app/runtime.cpp +++ b/src/app/runtime.cpp @@ -1,5 +1,6 @@ #include "Application.hpp" #include "Environment.hpp" +#include "PreloadState.hpp" #include "Runtime.hpp" #include "WorldState.hpp" @@ -176,8 +177,11 @@ int Runtime::Execute() { Application app(env); - WorldState state(env, config.interface, config.world); - app.PushState(&state); + WorldState world_state(env, config.interface, config.world); + app.PushState(&world_state); + + PreloadState preloader(env, world_state.GetWorld().Loader()); + app.PushState(&preloader); switch (mode) { default: diff --git a/src/world/ChunkLoader.hpp b/src/world/ChunkLoader.hpp index c9fb8aa..6a8c2c1 100644 --- a/src/world/ChunkLoader.hpp +++ b/src/world/ChunkLoader.hpp @@ -39,6 +39,10 @@ public: void Rebase(const Chunk::Pos &); void Update(int dt); + std::size_t ToLoad() const noexcept { return to_generate.size(); } + void LoadOne(); + void LoadN(std::size_t n); + private: Chunk &Generate(const Chunk::Pos &pos); // link given chunk to all loaded neighbors diff --git a/src/world/World.hpp b/src/world/World.hpp index 10710fb..da02b1f 100644 --- a/src/world/World.hpp +++ b/src/world/World.hpp @@ -48,7 +48,8 @@ public: bool Intersection(const Entity &e, std::vector &); void Resolve(Entity &e, std::vector &); - BlockTypeRegistry &BlockTypes() { return blockType; } + BlockTypeRegistry &BlockTypes() noexcept { return blockType; } + ChunkLoader &Loader() noexcept { return chunks; } Entity &Player() { return *player; } Entity &AddEntity() { entities.emplace_back(); return entities.back(); } diff --git a/src/world/chunk.cpp b/src/world/chunk.cpp index 190fe3d..77899e7 100644 --- a/src/world/chunk.cpp +++ b/src/world/chunk.cpp @@ -842,9 +842,20 @@ void ChunkLoader::Update(int dt) { // check if a chunk generation is scheduled for this frame // and if there's a chunk waiting to be generated gen_timer.Update(dt); - if (!gen_timer.Hit() || to_generate.empty()) { - return; + if (gen_timer.Hit()) { + LoadOne(); + } +} + +void ChunkLoader::LoadN(std::size_t n) { + std::size_t end = std::min(n, ToLoad()); + for (std::size_t i = 0; i < end; ++i) { + LoadOne(); } +} + +void ChunkLoader::LoadOne() { + if (to_generate.empty()) return; // take position of next chunk in queue Chunk::Pos pos(to_generate.front()); -- 2.39.2