]> git.localhorst.tv Git - blobs.git/commitdiff
more stolen stuff
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Sat, 4 Nov 2017 20:13:52 +0000 (21:13 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Sat, 4 Nov 2017 20:13:52 +0000 (21:13 +0100)
src/app/Application.hpp [new file with mode: 0644]
src/app/State.hpp [new file with mode: 0644]
src/app/app.cpp [new file with mode: 0644]
src/app/init.cpp
src/app/init.hpp
src/blobs.cpp
src/world/Planet.hpp [new file with mode: 0644]
src/world/Tile.hpp [new file with mode: 0644]
src/world/world.cpp [new file with mode: 0644]

diff --git a/src/app/Application.hpp b/src/app/Application.hpp
new file mode 100644 (file)
index 0000000..4ed4b76
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef BLOBS_APP_APPLICATION_HPP_
+#define BLOBS_APP_APPLICATION_HPP_
+
+#include <stack>
+
+
+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<State *> states;
+
+};
+
+}
+}
+
+#endif
diff --git a/src/app/State.hpp b/src/app/State.hpp
new file mode 100644 (file)
index 0000000..4462904
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef BLOBS_APP_STATE_HPP_
+#define BLOBS_APP_STATE_HPP_
+
+#include <SDL.h>
+
+
+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 (file)
index 0000000..a7bbf39
--- /dev/null
@@ -0,0 +1,128 @@
+#include "Application.hpp"
+#include "State.hpp"
+
+#include <SDL.h>
+
+
+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();
+}
+
+}
+}
index 34e0393db02c2bd7e3d335ee790bdd50c330539d..721452f466ff81ee16fe09243676dc6048ded620 100644 (file)
@@ -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)
 }
 
 }
+}
index ba263c4b38138a6dec54aaaf24cd177f0bc93868..63334e89aa46d403ab7930ba5dd3ba586f5b90f8 100644 (file)
@@ -8,6 +8,7 @@
 
 
 namespace blobs {
+namespace app {
 
 class AlutError
 : public std::runtime_error {
@@ -195,6 +196,7 @@ struct Init {
 
 };
 
+}
 }
 
 #endif
index 30571ac0430ef12a9d3e970213cb14110a7989c2..6aa0aa4a6dcfabf30cdd33f2cde09fae033698b6 100644 (file)
@@ -1,10 +1,16 @@
+#include "app/Application.hpp"
 #include "app/init.hpp"
+#include "world/Planet.hpp"
 
 #include <exception>
 #include <iostream>
 
+
 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 (file)
index 0000000..6106ccf
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef BLOBS_WORLD_PLANET_HPP_
+#define BLOBS_WORLD_PLANET_HPP_
+
+#include "Tile.hpp"
+
+#include <cassert>
+#include <memory>
+
+
+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<Tile []> tiles;
+
+};
+
+void GenerateTest(Planet &);
+
+}
+}
+
+#endif
diff --git a/src/world/Tile.hpp b/src/world/Tile.hpp
new file mode 100644 (file)
index 0000000..e8faf7d
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef BLOBS_WORLD_TILE_HPP_
+#define BLOBS_WORLD_TILE_HPP_
+
+#include <cstdint>
+
+
+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 (file)
index 0000000..cd18fb2
--- /dev/null
@@ -0,0 +1,42 @@
+#include "Planet.hpp"
+#include "Tile.hpp"
+
+#include <algorithm>
+
+
+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);
+                       }
+               }
+       }
+}
+
+}
+}