aboutsummaryrefslogtreecommitdiff
path: root/src/crepe/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/crepe/api')
-rw-r--r--src/crepe/api/LoopManager.cpp36
-rw-r--r--src/crepe/api/LoopManager.h29
-rw-r--r--src/crepe/api/LoopTimer.cpp45
-rw-r--r--src/crepe/api/LoopTimer.h27
4 files changed, 65 insertions, 72 deletions
diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp
index 731cfb7..040cb93 100644
--- a/src/crepe/api/LoopManager.cpp
+++ b/src/crepe/api/LoopManager.cpp
@@ -1,9 +1,12 @@
+#include "../facade/SDLContext.h"
+
#include "../system/AnimatorSystem.h"
#include "../system/CollisionSystem.h"
#include "../system/ParticleSystem.h"
#include "../system/PhysicsSystem.h"
#include "../system/RenderSystem.h"
#include "../system/ScriptSystem.h"
+#include "../manager/EventManager.h"
#include "LoopManager.h"
@@ -11,15 +14,17 @@ using namespace crepe;
using namespace std;
LoopManager::LoopManager() {
- this->mediator.component_manager = this->component_manager;
- this->mediator.scene_manager = this->scene_manager;
-
this->load_system<AnimatorSystem>();
this->load_system<CollisionSystem>();
this->load_system<ParticleSystem>();
this->load_system<PhysicsSystem>();
this->load_system<RenderSystem>();
this->load_system<ScriptSystem>();
+ EventManager::get_instance().subscribe<ShutDownEvent>([this](const ShutDownEvent& event) {
+ return this->on_shutdown(event);
+ });
+ this->loop_timer = make_unique<LoopTimer>();
+ this->mediator.loop_timer = *loop_timer;
}
void LoopManager::process_input() { this->sdl_context.handle_events(this->game_running); }
@@ -28,36 +33,33 @@ void LoopManager::start() {
this->setup();
this->loop();
}
-void LoopManager::set_running(bool running) { this->game_running = running; }
void LoopManager::fixed_update() {}
void LoopManager::loop() {
- LoopTimer & timer = this->loop_timer;
- timer.start();
+ this->loop_timer->start();
while (game_running) {
- timer.update();
-
- while (timer.get_lag() >= timer.get_fixed_delta_time()) {
+ this->loop_timer->update();
+
+ while (this->loop_timer->get_lag() >= this->loop_timer->get_fixed_delta_time()) {
this->process_input();
this->fixed_update();
- timer.advance_fixed_update();
+ this->loop_timer->advance_fixed_update();
}
this->update();
this->render();
-
- timer.enforce_frame_rate();
+ this->loop_timer->enforce_frame_rate();
}
}
void LoopManager::setup() {
- LoopTimer & timer = this->loop_timer;
+
this->game_running = true;
- timer.start();
- timer.set_fps(200);
+ this->loop_timer->start();
+ this->loop_timer->set_target_fps(200);
}
void LoopManager::render() {
@@ -65,5 +67,9 @@ void LoopManager::render() {
this->get_system<RenderSystem>().update();
}
+bool LoopManager::on_shutdown(const ShutDownEvent & e){
+ this->game_running = false;
+ return false;
+}
void LoopManager::update() {}
diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h
index d8910a0..17bddd1 100644
--- a/src/crepe/api/LoopManager.h
+++ b/src/crepe/api/LoopManager.h
@@ -6,11 +6,12 @@
#include "../manager/ComponentManager.h"
#include "../manager/SceneManager.h"
#include "../system/System.h"
+#include "manager/SceneManager.h"
-#include "LoopTimer.h"
+#include "api/Event.h"
+#include "api/LoopTimer.h"
namespace crepe {
-
/**
* \brief Main game loop manager
*
@@ -18,6 +19,12 @@ namespace crepe {
*/
class LoopManager {
public:
+ /**
+ * \brief Start the gameloop
+ *
+ * This is the start of the engine where the setup is called and then the loop keeps running until the game stops running.
+ * Developers need to call this function to run the game.
+ */
void start();
LoopManager();
@@ -70,14 +77,6 @@ private:
* This function updates physics and game logic based on LoopTimer's fixed_delta_time.
*/
void fixed_update();
-
- /**
- * \brief Set game running variable
- *
- * \param running running (false = game shutdown, true = game running)
- */
- void set_running(bool running);
-
/**
* \brief Function for executing render-related systems.
*
@@ -98,15 +97,17 @@ private:
//! SDL context \todo no more singletons!
SDLContext & sdl_context = SDLContext::get_instance();
- //! Loop timer \todo no more singletons!
- LoopTimer & loop_timer = LoopTimer::get_instance();
-
+ //! loop timer instance
+ std::unique_ptr<LoopTimer> loop_timer;
private:
+
+ //! callback function for shutdown event
+ bool on_shutdown(const ShutDownEvent & e);
/**
* \brief Collection of System instances
*
* This map holds System instances indexed by the system's class typeid. It is filled in the
- * constructor of \c LoopManager using LoopManager::load_system.
+ * constructor of LoopManager using LoopManager::load_system.
*/
std::unordered_map<std::type_index, std::unique_ptr<System>> systems;
/**
diff --git a/src/crepe/api/LoopTimer.cpp b/src/crepe/api/LoopTimer.cpp
index 15a0e3a..07f0f75 100644
--- a/src/crepe/api/LoopTimer.cpp
+++ b/src/crepe/api/LoopTimer.cpp
@@ -1,4 +1,5 @@
#include <chrono>
+#include <thread>
#include "../facade/SDLContext.h"
#include "../util/Log.h"
@@ -9,15 +10,13 @@ using namespace crepe;
LoopTimer::LoopTimer() { dbg_trace(); }
-LoopTimer & LoopTimer::get_instance() {
- static LoopTimer instance;
- return instance;
-}
void LoopTimer::start() {
this->last_frame_time = std::chrono::steady_clock::now();
+
this->elapsed_time = std::chrono::milliseconds(0);
- this->elapsed_fixed_time = std::chrono::milliseconds(0);
+ // by starting the elapsed_fixed_time at (0 - fixed_delta_time) in milliseconds it calls a fixed update at the start of the loop.
+ this->elapsed_fixed_time = -std::chrono::duration_cast<std::chrono::milliseconds>(fixed_delta_time);
this->delta_time = std::chrono::milliseconds(0);
}
@@ -30,7 +29,8 @@ void LoopTimer::update() {
if (this->delta_time > this->maximum_delta_time) {
this->delta_time = this->maximum_delta_time;
}
-
+ this->actual_fps = 1.0 / this->delta_time.count();
+
this->delta_time *= this->game_scale;
this->elapsed_time += this->delta_time;
this->last_frame_time = current_frame_time;
@@ -44,34 +44,29 @@ void LoopTimer::advance_fixed_update() { this->elapsed_fixed_time += this->fixed
double LoopTimer::get_fixed_delta_time() const { return this->fixed_delta_time.count(); }
-void LoopTimer::set_fps(int fps) {
- this->fps = fps;
+void LoopTimer::set_target_fps(int fps) {
+ this->target_fps = fps;
// target time per frame in seconds
- this->frame_target_time = std::chrono::duration<double>(1.0) / fps;
+ this->frame_target_time = std::chrono::duration<double>(1.0) / target_fps;
}
-int LoopTimer::get_fps() const { return this->fps; }
+int LoopTimer::get_fps() const { return this->actual_fps; }
void LoopTimer::set_game_scale(double value) { this->game_scale = value; }
double LoopTimer::get_game_scale() const { return this->game_scale; }
void LoopTimer::enforce_frame_rate() {
- std::chrono::steady_clock::time_point current_frame_time
- = std::chrono::steady_clock::now();
- std::chrono::milliseconds frame_duration
- = std::chrono::duration_cast<std::chrono::milliseconds>(current_frame_time
- - this->last_frame_time);
-
- if (frame_duration < this->frame_target_time) {
- std::chrono::milliseconds delay_time
- = std::chrono::duration_cast<std::chrono::milliseconds>(this->frame_target_time
- - frame_duration);
- if (delay_time.count() > 0) {
- SDLContext::get_instance().delay(delay_time.count());
- }
- }
+ auto current_frame_time = std::chrono::steady_clock::now();
+ auto frame_duration = current_frame_time - this->last_frame_time;
- this->last_frame_time = current_frame_time;
+ // Check if frame duration is less than the target frame time
+ if (frame_duration < this->frame_target_time) {
+ auto delay_time = std::chrono::duration_cast<std::chrono::microseconds>(this->frame_target_time - frame_duration);
+
+ if (delay_time.count() > 0) {
+ std::this_thread::sleep_for(delay_time);
+ }
+ }
}
double LoopTimer::get_lag() const {
diff --git a/src/crepe/api/LoopTimer.h b/src/crepe/api/LoopTimer.h
index 9393439..e348628 100644
--- a/src/crepe/api/LoopTimer.h
+++ b/src/crepe/api/LoopTimer.h
@@ -6,13 +6,7 @@ namespace crepe {
class LoopTimer {
public:
- /**
- * \brief Get the singleton instance of LoopTimer.
- *
- * \return A reference to the LoopTimer instance.
- */
- static LoopTimer & get_instance();
-
+ LoopTimer();
/**
* \brief Get the current delta time for the current frame.
*
@@ -35,7 +29,7 @@ public:
*
* \param fps The desired frames rendered per second.
*/
- void set_fps(int fps);
+ void set_target_fps(int fps);
/**
* \brief Get the current frames per second (FPS).
@@ -68,7 +62,6 @@ private:
* Initializes the timer to begin tracking frame times.
*/
void start();
-
/**
* \brief Enforce the frame rate limit.
*
@@ -97,12 +90,7 @@ private:
*/
double get_lag() const;
- /**
- * \brief Construct a new LoopTimer object.
- *
- * Private constructor for singleton pattern to restrict instantiation outside the class.
- */
- LoopTimer();
+
/**
* \brief Update the timer to the current frame.
@@ -121,8 +109,10 @@ private:
void advance_fixed_update();
private:
- //! Current frames per second
- int fps = 50;
+ //! Target frames per second
+ int target_fps = 50;
+ //! Actual frames per second
+ int actual_fps = 0;
//! Current game scale
double game_scale = 1;
//! Maximum delta time in seconds to avoid large jumps
@@ -130,7 +120,7 @@ private:
//! Delta time for the current frame in seconds
std::chrono::duration<double> delta_time{0.0};
//! Target time per frame in seconds
- std::chrono::duration<double> frame_target_time = std::chrono::duration<double>(1.0) / fps;
+ std::chrono::duration<double> frame_target_time = std::chrono::duration<double>(1.0) / target_fps;
//! Fixed delta time for fixed updates in seconds
std::chrono::duration<double> fixed_delta_time = std::chrono::duration<double>(1.0) / 50.0;
//! Total elapsed game time in seconds
@@ -139,6 +129,7 @@ private:
std::chrono::duration<double> elapsed_fixed_time{0.0};
//! Time of the last frame
std::chrono::steady_clock::time_point last_frame_time;
+
};
} // namespace crepe