ougge/src/Engine.cpp

103 lines
2.9 KiB
C++

#include "Engine.hpp"
#include "common/UsefulException.hpp"
#include "common/ougge_format.hpp"
#include "common/time.hpp"
#include <SDL2/SDL.h>
#include <iostream>
namespace ougge {
IEngineModule::IEngineModule(Engine& engine)
: engine(engine)
{}
void IEngineModule::beginFrame() {}
void IEngineModule::endFrame() {}
void Engine::startLoop()
{
if(loop_running)
throw UsefulException("loop is running already");
nsec_t prev_update_time_ns = getMonotonicTimeNsec();
loop_running=true;
// main loop
while(loop_running){
nsec_t update_time_ns = getMonotonicTimeNsec();
if(update_time_ns < prev_update_time_ns)
throw UsefulException("monotonic clock returned unexpected value");
f64 delta_time_s = (f64)(update_time_ns - prev_update_time_ns) / 1e9;
prev_update_time_ns = update_time_ns;
deltaTime = delta_time_s;
tryDrawFrame();
nsec_t after_update_time_ns = getMonotonicTimeNsec();
nsec_t frame_delay_ns = (nsec_t)1e9 / fps_max - (after_update_time_ns - update_time_ns);
if(frame_delay_ns > 0){
SDL_Delay(frame_delay_ns / 1e6);
}
}
}
void Engine::stopLoop(){
loop_running = false;
}
void Engine::handleModuleError(IEngineModule& module, const char* type, const char* method, const char* error){
std::string error_message = ougge_format(
"Catched %s at %s.%s(): %s",
type, module.getName(), method, error);
std::cerr<<error_message<<std::endl;
error_messages.push_back(error_message);
}
void Engine::tryDrawFrame(){
auto it = modules.begin();
while(it != modules.end())
{
IEngineModule& module = **it;
it++;
try {
module.beginFrame();
}
catch(const std::exception& e){
handleModuleError(module, "exception", "beginFrame", e.what());
}
catch(const char* cstr){
handleModuleError(module, "error message (const char*)", "beginFrame", cstr);
}
catch(const std::string& str){
handleModuleError(module, "error message (std::string)", "beginFrame", str.c_str());
}
catch(...){
handleModuleError(module, "unknown", "beginFrame", "unknown");
}
}
it = modules.end();
while(it != modules.begin())
{
it--;
IEngineModule& module = **it;
try {
module.endFrame();
}
catch(const std::exception& e){
handleModuleError(module, "exception", "endFrame", e.what());
}
catch(const char* cstr){
handleModuleError(module, "error message (const char*)", "endFrame", cstr);
}
catch(const std::string& str){
handleModuleError(module, "error message (std::string)", "endFrame", str.c_str());
}
catch(...){
handleModuleError(module, "unknown", "endFrame", "unknown");
}
}
}
}