115 lines
3.6 KiB
C++
115 lines
3.6 KiB
C++
#include "Engine.hpp"
|
|
#include "gui/gui.hpp"
|
|
|
|
namespace ougge {
|
|
|
|
Engine::Engine()
|
|
: gameObjectPool(GAMEOBJECTPOOL_SIZE)
|
|
{
|
|
}
|
|
|
|
void Engine::init(){
|
|
engineManagedAssembly = mono.loadAssembly("Ougge.dll");
|
|
gameObjectClass = engineManagedAssembly->getClass("Ougge", "GameObject");
|
|
gameObjectCtor = Mono::Method<void(u64, u32)>(gameObjectClass, ".ctor");
|
|
gameObjectInvokeUpdate = Mono::Method<void(f64)>(gameObjectClass, "InvokeUpdate");
|
|
gameObjectTryCreateComponent = Mono::Method<Mono::Bool(Mono::String)>(gameObjectClass, "TryCreateComponent_internal");
|
|
}
|
|
|
|
void Engine::openMainWindow(const std::string& window_title){
|
|
mainWindow.open(window_title);
|
|
}
|
|
|
|
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){
|
|
mainWindow.pollEvents(&loop_running);
|
|
if(!loop_running)
|
|
break;
|
|
|
|
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;
|
|
|
|
tryDrawFrame(delta_time_s);
|
|
|
|
nsec_t after_update_time_ns = getMonotonicTimeNsec();
|
|
nsec_t frame_delay_ns = (nsec_t)1e9 / mainWindow.fps_max - (after_update_time_ns - update_time_ns);
|
|
if(frame_delay_ns > 0){
|
|
SDL_Delay(frame_delay_ns / 1e6);
|
|
}
|
|
}
|
|
|
|
mainWindow.close();
|
|
}
|
|
|
|
void Engine::stopLoop(){
|
|
loop_running = false;
|
|
}
|
|
|
|
void Engine::tryDrawFrame(f64 deltaTime){
|
|
static std::string error_message;
|
|
static bool draw_error_window = false;
|
|
try {
|
|
mainWindow.beginFrame();
|
|
|
|
if(draw_error_window)
|
|
gui::drawErrorWindow(error_message, &draw_error_window);
|
|
else {
|
|
updateGameObjects(deltaTime);
|
|
if(!updateCallback.isNull())
|
|
updateCallback(deltaTime);
|
|
}
|
|
mainWindow.endFrame();
|
|
}
|
|
catch(const std::exception& e){
|
|
error_message = "Catched exception: " + std::string(e.what());
|
|
draw_error_window = true;
|
|
std::cerr<<error_message<<std::endl;
|
|
}
|
|
catch(const char* cstr){
|
|
error_message = "Catched error message (const char*): " + std::string(cstr);
|
|
draw_error_window = true;
|
|
std::cerr<<error_message<<std::endl;
|
|
}
|
|
catch(const std::string& str){
|
|
error_message = "Catched error message (std::string): " + str;
|
|
draw_error_window = true;
|
|
std::cerr<<error_message<<std::endl;
|
|
}
|
|
catch(...){
|
|
error_message = "Catched unknown error";
|
|
draw_error_window = true;
|
|
std::cerr<<error_message<<std::endl;
|
|
}
|
|
}
|
|
|
|
|
|
void Engine::updateGameObjects(f64 deltaTime){
|
|
for(auto pair : gameObjectPool){
|
|
gameObjectInvokeUpdate(pair.second.getObjectHandle().getObject(), deltaTime);
|
|
}
|
|
}
|
|
|
|
game::GameObject& Engine::createGameObject(){
|
|
auto pair = gameObjectPool.emplace(game::GameObject(mono.createObject(gameObjectClass)));
|
|
game::GameObject& obj = pair.second;
|
|
gameObjectCtor(obj.getObjectHandle().getObject(), ++obj_id, pair.first);
|
|
return obj;
|
|
}
|
|
|
|
bool Engine::tryCreateComponent(game::GameObject& obj, const std::string& componentClassName){
|
|
Mono::String componentClassNameManaged = mono.createString(componentClassName);
|
|
Mono::Bool created = gameObjectTryCreateComponent(obj.getObjectHandle().getObject(), componentClassNameManaged);
|
|
return created.wide_bool;
|
|
}
|
|
|
|
}
|