summaryrefslogtreecommitdiffstats
path: root/src/control/RPGEdit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/control/RPGEdit.cpp')
-rw-r--r--src/control/RPGEdit.cpp95
1 files changed, 66 insertions, 29 deletions
diff --git a/src/control/RPGEdit.cpp b/src/control/RPGEdit.cpp
index 679796c..0c55a6b 100644
--- a/src/control/RPGEdit.cpp
+++ b/src/control/RPGEdit.cpp
@@ -28,62 +28,99 @@
#include "MapContext.hpp"
#include "../view/MapView.hpp"
-#include <SDL.h>
+namespace RPGEdit {
-#define MIN_FRAME_DELAY 10
+namespace Control {
+bool RPGEdit::handleSystemEvent(const SDL_Event &event) {
+ uint64_t time = timeProvider.now();
-namespace RPGEdit {
+ switch (event.type) {
+ case SDL_KEYDOWN:
+ eventBus.enqueue([=] { inputHandler.keyPressed(event.key.keysym.scancode, time); }, time);
+ break;
-namespace Control {
+ case SDL_KEYUP:
+ eventBus.enqueue([=] { inputHandler.keyReleased(event.key.keysym.scancode, time); }, time);
+ break;
-bool RPGEdit::systemIter(unsigned ticks) {
- int timeout = 0;
+ case SDL_QUIT:
+ return false;
+ }
- SDL_Event event;
- if (SDL_WaitEventTimeout(&event, timeout)) {
- switch (event.type) {
- case SDL_KEYDOWN:
- inputHandler.keyPressed(event.key.keysym.scancode);
- break;
+ return true;
+}
- case SDL_KEYUP:
- inputHandler.keyReleased(event.key.keysym.scancode);
- break;
+void RPGEdit::systemLoop() {
+ const int MIN_FRAME_DELAY = 10;
+
+ uint32_t lastFrameTicks = SDL_GetTicks();
+
+ while (true) {
+ uint32_t diff = SDL_GetTicks() - lastFrameTicks;
+ int timeout = std::max(MIN_FRAME_DELAY - int(diff), 0);
- case SDL_QUIT:
- return false;
+ SDL_Event event;
+ if (SDL_WaitEventTimeout(&event, timeout)) {
+ if (!handleSystemEvent(event))
+ return;
+
+ continue;
}
- }
- ctx->advance(&inputHandler, ticks);
+ lastFrameTicks = SDL_GetTicks();
- Model::Position pos = ctx->getViewPosition();
- mapView->render(pos.x, pos.y);
+ {
+ std::unique_lock<std::mutex> lock(modelMutex);
- return true;
+ uint64_t time = timeProvider.now();
+
+ while (time >= handledTime) {
+ modelCond.wait(lock);
+ time = timeProvider.now();
+ }
+
+ Model::Position pos = ctx->getViewPosition(time);
+ mapView->render(pos.x, pos.y, time);
+ }
+
+ SDL_RenderPresent(window->getRenderer());
+ }
}
-void RPGEdit::systemLoop() {
- uint32_t ticks1 = SDL_GetTicks();
- uint32_t ticks2 = ticks1;
+void RPGEdit::eventLoop() {
+ while (true) {
+ EventBus::EventEntry event = eventBus.get(&timeProvider);
- while (systemIter(ticks2 - ticks1)) {
- ticks1 = ticks2;
- ticks2 = SDL_GetTicks();
+ if (!event.second)
+ return;
+
+ {
+ std::lock_guard<std::mutex> lock(modelMutex);
+
+ event.second();
+
+ handledTime = eventBus.peek();
+ modelCond.notify_one();
+ }
}
}
void RPGEdit::run() {
std::shared_ptr<Model::Map> map = Model::Map::load("test");
- ctx = std::make_shared<MapContext>(&tileLoader, map);
+ ctx = std::make_shared<MapContext>(&eventBus, &inputHandler, &tileLoader, map);
window = std::make_shared<View::Window>();
mapView = ctx->initView(window);
+ eventThread = std::thread([this] { eventLoop(); });
+
systemLoop();
+
+ eventBus.enqueue(EventBus::Event(), timeProvider.now());
+ eventThread.join();
}
}