From: Daniel Karbach Date: Sat, 4 Nov 2017 20:13:52 +0000 (+0100) Subject: more stolen stuff X-Git-Url: http://git.localhorst.tv/?p=blobs.git;a=commitdiff_plain;h=91dfd6cd62ea0723c3c83572b4ebfa4ef7b4ac5f more stolen stuff --- diff --git a/src/app/Application.hpp b/src/app/Application.hpp new file mode 100644 index 0000000..4ed4b76 --- /dev/null +++ b/src/app/Application.hpp @@ -0,0 +1,46 @@ +#ifndef BLOBS_APP_APPLICATION_HPP_ +#define BLOBS_APP_APPLICATION_HPP_ + +#include + + +namespace blobs { +namespace app { + +class State; + +class Application { + +public: + Application(); + ~Application(); + + Application(const Application &) = delete; + Application &operator =(const Application &) = delete; + + Application(Application &&) = delete; + Application &operator =(Application &&) = delete; + +public: + void PushState(State *); + State *PopState(); + State *SwitchState(State *); + State &GetState(); + bool HasState() const noexcept; + + /// Loop until states is empty. + void Run(); + /// Evaluate a single frame of dt milliseconds. + void Loop(int dt); + /// Process all events in queue. + void HandleEvents(); + +private: + std::stack states; + +}; + +} +} + +#endif diff --git a/src/app/State.hpp b/src/app/State.hpp new file mode 100644 index 0000000..4462904 --- /dev/null +++ b/src/app/State.hpp @@ -0,0 +1,41 @@ +#ifndef BLOBS_APP_STATE_HPP_ +#define BLOBS_APP_STATE_HPP_ + +#include + + +namespace blobs { +namespace app { + +class Application; + +class State { + + friend class Application; + + void Handle(const SDL_Event &); + void Handle(const SDL_WindowEvent &); + void Update(int dt); + void Render(); + + virtual void OnEnter() { } + virtual void OnResume() { } + virtual void OnPause() { } + virtual void OnExit() { } + + virtual void OnFocus() { } + virtual void OnBlur() { } + virtual void OnResize() { } + + virtual void OnEvent(const SDL_Event &); + virtual void OnUpdate(int dt); + virtual void OnRender(); + + int ref_count = 0; + +}; + +} +} + +#endif diff --git a/src/app/app.cpp b/src/app/app.cpp new file mode 100644 index 0000000..a7bbf39 --- /dev/null +++ b/src/app/app.cpp @@ -0,0 +1,128 @@ +#include "Application.hpp" +#include "State.hpp" + +#include + + +namespace blobs { +namespace app { + +Application::Application() +: states() { +} + +Application::~Application() { +} + + +void Application::PushState(State *s) { + if (!states.empty()) { + states.top()->OnPause(); + } + states.emplace(s); + ++s->ref_count; + if (s->ref_count == 1) { + s->OnEnter(); + } + s->OnResume(); +} + +State *Application::PopState() { + State *s = states.top(); + states.pop(); + s->OnPause(); + s->OnExit(); + if (!states.empty()) { + states.top()->OnResume(); + } + return s; +} + +State *Application::SwitchState(State *s_new) { + State *s_old = states.top(); + states.top() = s_new; + --s_old->ref_count; + ++s_new->ref_count; + s_old->OnPause(); + if (s_old->ref_count == 0) { + s_old->OnExit(); + } + if (s_new->ref_count == 1) { + s_new->OnEnter(); + } + s_new->OnResume(); + return s_old; +} + +State &Application::GetState() { + return *states.top(); +} + +bool Application::HasState() const noexcept { + return !states.empty(); +} + + +void Application::Run() { + Uint32 last = SDL_GetTicks(); + while (HasState()) { + Uint32 now = SDL_GetTicks(); + int delta = now - last; + Loop(delta); + last = now; + } +} + +void Application::Loop(int dt) { + HandleEvents(); + if (!HasState()) return; + GetState().Update(dt); + if (!HasState()) return; + GetState().Render(); +} + +void Application::HandleEvents() { + SDL_Event event; + while (HasState() && SDL_PollEvent(&event)) { + GetState().Handle(event); + } +} + +void State::Handle(const SDL_Event &event) { + switch (event.type) { + case SDL_WINDOWEVENT: + Handle(event.window); + break; + default: + OnEvent(event); + break; + } +} + +void State::Handle(const SDL_WindowEvent &event) { + switch (event.event) { + case SDL_WINDOWEVENT_FOCUS_GAINED: + OnFocus(); + break; + case SDL_WINDOWEVENT_FOCUS_LOST: + OnBlur(); + break; + case SDL_WINDOWEVENT_RESIZED: + //env.viewport.Resize(event.data1, event.data2); + OnResize(); + break; + default: + break; + } +} + +void State::Update(int dt) { + OnUpdate(dt); +} + +void State::Render() { + OnRender(); +} + +} +} diff --git a/src/app/init.cpp b/src/app/init.cpp index 34e0393..721452f 100644 --- a/src/app/init.cpp +++ b/src/app/init.cpp @@ -43,6 +43,7 @@ std::string alut_error_append(ALenum num, std::string msg) { } namespace blobs { +namespace app { AlutError::AlutError(ALenum num) : std::runtime_error(alutGetErrorString(num)) { @@ -263,3 +264,4 @@ Init::Init(bool double_buffer, int sample_size) } } +} diff --git a/src/app/init.hpp b/src/app/init.hpp index ba263c4..63334e8 100644 --- a/src/app/init.hpp +++ b/src/app/init.hpp @@ -8,6 +8,7 @@ namespace blobs { +namespace app { class AlutError : public std::runtime_error { @@ -195,6 +196,7 @@ struct Init { }; +} } #endif diff --git a/src/blobs.cpp b/src/blobs.cpp index 30571ac..6aa0aa4 100644 --- a/src/blobs.cpp +++ b/src/blobs.cpp @@ -1,10 +1,16 @@ +#include "app/Application.hpp" #include "app/init.hpp" +#include "world/Planet.hpp" #include #include + using namespace blobs; int main(int argc, char *argv[]) { - Init init; + app::Init init; + world::Planet planet(1); // r=1 should be a 3³ + + app::Application app; } diff --git a/src/world/Planet.hpp b/src/world/Planet.hpp new file mode 100644 index 0000000..6106ccf --- /dev/null +++ b/src/world/Planet.hpp @@ -0,0 +1,77 @@ +#ifndef BLOBS_WORLD_PLANET_HPP_ +#define BLOBS_WORLD_PLANET_HPP_ + +#include "Tile.hpp" + +#include +#include + + +namespace blobs { +namespace world { + +struct Tile; + +/// A planet has six surfaces, numbered 0 to 5, each with tiles from +/// +radius to -radius. +class Planet { + +public: + explicit Planet(int radius); + ~Planet(); + + Planet(Planet &&); + Planet &operator =(Planet &&); + + Planet(const Planet &) = delete; + Planet &operator =(const Planet &) = delete; + +public: + /// Get the tile at given surface and coordinates. + Tile &TileAt(int surface, int x, int y) { + return tiles[IndexOf(surface, x, y)]; + } + const Tile &TileAt(int surface, int x, int y) const { + return tiles[IndexOf(surface, x, y)]; + } + + /// Convert coordinates into a tile index. + int IndexOf(int surface, int x, int y) const { + assert(0 <= surface && surface <= 5); + assert(-radius <= x && x <= radius); + assert(-radius <= y && y <= radius); + return surface * SurfaceArea() + ToOffset(y) * SideLength() + ToOffset(x); + } + /// Convert coordinate into offset + int ToOffset(int c) const { + return c + radius; + } + /// The "radius" of the planet. + int Radius() const { + return radius; + } + /// The length of the side of each surface. + int SideLength() const { + return 2 * radius + 1; + } + /// The area (or number of tiles) of one surface + int SurfaceArea() const { + return SideLength() * SideLength(); + } + /// Total area of all surfaces combined. + int TotalArea() const { + return 6 * SurfaceArea(); + } + +private: + int radius; + std::unique_ptr tiles; + +}; + +void GenerateTest(Planet &); + +} +} + +#endif diff --git a/src/world/Tile.hpp b/src/world/Tile.hpp new file mode 100644 index 0000000..e8faf7d --- /dev/null +++ b/src/world/Tile.hpp @@ -0,0 +1,19 @@ +#ifndef BLOBS_WORLD_TILE_HPP_ +#define BLOBS_WORLD_TILE_HPP_ + +#include + + +namespace blobs { +namespace world { + +struct Tile { + + std::uint16_t type; + +}; + +} +} + +#endif diff --git a/src/world/world.cpp b/src/world/world.cpp new file mode 100644 index 0000000..cd18fb2 --- /dev/null +++ b/src/world/world.cpp @@ -0,0 +1,42 @@ +#include "Planet.hpp" +#include "Tile.hpp" + +#include + + +namespace blobs { +namespace world { + +Planet::Planet(int radius) +: radius(radius) +, tiles(new Tile[TotalArea()]) { + +} + +Planet::~Planet() { +} + +Planet::Planet(Planet &&other) +: radius(other.radius) +, tiles(other.tiles.release()) { +} + +Planet &Planet::operator =(Planet &&other) { + radius = other.radius; + std::swap(tiles, other.tiles); + return *this; +} + + +void GenerateTest(Planet &p) { + for (int surface = 0; surface <= 5; ++surface) { + for (int y = -p.Radius(); y <= p.Radius(); ++y) { + for (int x = -p.Radius(); x <= p.Radius(); ++x) { + p.TileAt(surface, x, y).type = (x == 0) + (y == 0); + } + } + } +} + +} +}