outsourced application handling

This commit is contained in:
Lauchmelder 2021-12-13 00:25:13 +01:00
parent 5762d02b48
commit 71fdb2c053
10 changed files with 251 additions and 141 deletions

11
lib/CMakeLists.txt Normal file
View file

@ -0,0 +1,11 @@
add_library(nm_utils STATIC
"Window.cpp"
)
target_include_directories(nm_utils PUBLIC ${SDL2_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(nm_utils PUBLIC ${SDL2_LIBRARIES})
if(MSVC)
target_compile_definitions(nm_utils PUBLIC _CRT_SECURE_NO_WARNINGS)
endif()

150
lib/Window.cpp Normal file
View file

@ -0,0 +1,150 @@
#include "Window.hpp"
#include <iostream>
#include <SDL.h>
void Window::Launch()
{
SDL_ShowWindow(window);
while (!shouldClose)
{
HandleEvents();
Update();
Render();
}
SDL_HideWindow(window);
}
Window::Window(int width, int height, const std::string& title)
{
window = nullptr;
renderer = nullptr;
window = SDL_CreateWindow(
title.c_str(),
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
width, height,
SDL_WINDOW_HIDDEN
);
if (window == nullptr)
{
char errbuf[512];
SDL_GetErrorMsg(errbuf, 512);
std::cerr << "Failed to create SDL Window: " << std::endl
<< errbuf << std::endl;
return;
}
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == nullptr)
{
char errbuf[512];
SDL_GetErrorMsg(errbuf, 512);
std::cerr << "Failed to create SDL Renderer: " << std::endl
<< errbuf << std::endl;
return;
}
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
startOfLastFrame = std::chrono::steady_clock::now();
}
Window::Window(const Window& other)
{
*this = other;
}
Window& Window::operator=(const Window& other)
{
const char* title = SDL_GetWindowTitle(other.window);
int width, height;
SDL_GetWindowSize(other.window, &width, &height);
window = SDL_CreateWindow(
title,
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
width, height,
SDL_WINDOW_HIDDEN
);
if (window == nullptr)
{
char errbuf[512];
SDL_GetErrorMsg(errbuf, 512);
std::cerr << "Failed to create SDL Window: " << std::endl
<< errbuf << std::endl;
throw std::runtime_error("");
}
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == nullptr)
{
char errbuf[512];
SDL_GetErrorMsg(errbuf, 512);
std::cerr << "Failed to create SDL Renderer: " << std::endl
<< errbuf << std::endl;
throw std::runtime_error("");
}
startOfLastFrame = std::chrono::steady_clock::now();
return *this;
}
Window::~Window()
{
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
}
void Window::HandleEvents()
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_WINDOWEVENT:
{
switch (event.window.event)
{
case SDL_WINDOWEVENT_CLOSE:
shouldClose = true;
break;
}
} break;
}
}
}
void Window::Update()
{
double dt = std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::steady_clock::now() - startOfLastFrame).count();
startOfLastFrame = std::chrono::steady_clock::now();
OnUpdate(dt);
}
void Window::Render()
{
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
OnRender(renderer);
if (renderer == nullptr)
throw std::runtime_error("Client window left renderer in an invalid state");
SDL_RenderPresent(renderer);
}

37
lib/Window.hpp Normal file
View file

@ -0,0 +1,37 @@
#pragma once
#include <string>
#include <chrono>
struct SDL_Renderer;
struct SDL_Window;
class Window
{
public:
void Launch();
protected:
Window(int width, int height, const std::string& title);
Window(const Window& other);
Window& operator=(const Window& other);
~Window();
virtual void OnUpdate(double dt) {}
virtual void OnRender(SDL_Renderer* renderer) {}
private:
void HandleEvents();
void Update();
void Render();
protected:
SDL_Window* window;
private:
SDL_Renderer* renderer;
bool shouldClose = false;
std::chrono::steady_clock::time_point startOfLastFrame;
};