Main refactor and proper window management

This commit is contained in:
JackCarterSmith 2024-10-11 17:58:04 +02:00
parent 1496d03ead
commit 9ab9e476b9
Signed by: JackCarterSmith
GPG Key ID: 832E52F4E23F8F24
3 changed files with 60 additions and 43 deletions

View File

@ -1,14 +1,11 @@
#include "Game.hpp"
#include "icon.h"
#include <numeric>
#include <SFML/System.hpp>
#include <SFML/Window/ContextSettings.hpp>
#include <SFML/Window/Event.hpp>
#include "Engine/Utils/Perfs.hpp"
#include "Engine/Utils/Timers.hpp"
using std::make_shared;
using std::make_unique;
@ -19,9 +16,7 @@ using std::make_unique;
std::unique_ptr<SysTimer> mPerfsTimer = nullptr;
Game* Game::smInstance = nullptr;
Game::Game(bool dbgFlag) : mbDbgModeEnabled(dbgFlag) {
InitWindows();
Game::Game(std::shared_ptr<sf::RenderWindow> mainWnd, bool dbgFlag) : mbDbgModeEnabled(dbgFlag), mMainWindow(mainWnd) {
mCockpitUI = make_unique<CockpitUI>();
mWorldUI = make_unique<WorldUI>();
@ -32,32 +27,12 @@ Game::Game(bool dbgFlag) : mbDbgModeEnabled(dbgFlag) {
}
}
void Game::InitWindows() {
// Create default game window
sf::ContextSettings sWindowSettings;
sWindowSettings.depthBits = 0;
sWindowSettings.stencilBits = 0;
sWindowSettings.antialiasingLevel = 8;
sWindowSettings.sRgbCapable = true;
mMainWindow = make_shared<sf::RenderWindow>(
sf::VideoMode(1280, 720), "ProtoTank",
(sf::Style::Close | sf::Style::Titlebar),
sWindowSettings
);
mMainWindow->setVerticalSyncEnabled(false); // Never use simultaneously with framerate limiter
mMainWindow->setFramerateLimit(60);
mMainWindow->setKeyRepeatEnabled(false);
mMainWindow->setMouseCursorVisible(true);
mMainWindow->setIcon(64, 64, _aicon_bin);
}
GAME_STATUS Game::Tick(SysTimer& time) {
GAME_STATUS Game::Tick() {
static std::vector<double> msTicksMonitoring;
static double mPrevdelta = 0;
static double mLastCycleSleepDelta = 0;
static unsigned int mFrameCnt = 0;
double mDelta = time.GetDeltaTimeUs();
double mDelta = mSysTimer.GetDeltaTimeUs();
// Debug performance computations
if (mDbgUI != nullptr && mPerfsTimer != nullptr) {
@ -66,7 +41,7 @@ GAME_STATUS Game::Tick(SysTimer& time) {
// This average CPU/cycle_time method can monitor when CPU is in overload state (>0%) or in underload one (<0%)
double cpuUsage = 200 * std::accumulate(msTicksMonitoring.begin(), msTicksMonitoring.end(), (double)(0)) / msTicksMonitoring.size() - 100;
mDbgUI->UpdateDebugData(cpuUsage, (((1000000.f / TARGET_FPS) - mLastCycleSleepDelta) / 1000), ((-mPrevdelta + time.GetDeltaTimeUs()) / 1000), mFrameCnt, (PerfsGetVirtMem() / 1000), (PerfsGetPhysMem() / 1000));
mDbgUI->UpdateDebugData(cpuUsage, (((1000000.f / TARGET_FPS) - mLastCycleSleepDelta) / 1000), ((-mPrevdelta + mSysTimer.GetDeltaTimeUs()) / 1000), mFrameCnt, (PerfsGetVirtMem() / 1000), (PerfsGetPhysMem() / 1000));
mFrameCnt = 0;
msTicksMonitoring.clear();
@ -87,16 +62,16 @@ GAME_STATUS Game::Tick(SysTimer& time) {
//while(time.GetDeltaTime() < (1000/TARGET_FPS)) {}
// Process to the final rendering
if (time.GetDeltaTime() >= (1000/TARGET_FPS)) {
if (mSysTimer.GetDeltaTime() >= (1000/TARGET_FPS)) {
Render();
mFrameCnt++;
time.Reset();
mSysTimer.Reset();
mDelta = -mDelta;
}
mPrevdelta = mDelta;
// Sleep for remaining time to avoid useless CPU usage
mLastCycleSleepDelta = (1000000.f / TARGET_FPS) - (-mPrevdelta + time.GetDeltaTimeUs());
mLastCycleSleepDelta = (1000000.f / TARGET_FPS) - (-mPrevdelta + mSysTimer.GetDeltaTimeUs());
if (mLastCycleSleepDelta > 0)
sf::sleep(sf::microseconds(mLastCycleSleepDelta));
else

View File

@ -15,9 +15,9 @@ typedef enum eGameStatus {
class Game final {
public:
static Game& getInstance(bool dbgFlag) {
static Game& getInstance(std::shared_ptr<sf::RenderWindow> mainWnd, bool dbgFlag) {
if (smInstance == nullptr)
smInstance = new Game(dbgFlag);
smInstance = new Game(mainWnd, dbgFlag);
return *smInstance;
}
@ -28,20 +28,21 @@ public:
Game(Game const&) = delete;
Game& operator= (Game const&) = delete;
GAME_STATUS Tick(SysTimer& time);
GAME_STATUS Tick();
private:
Game(bool dbgFlag) noexcept(false);
Game(std::shared_ptr<sf::RenderWindow> mainWnd, bool dbgFlag) noexcept(false);
static Game* smInstance;
void InitWindows();
void Update();
void Render();
bool mbDbgModeEnabled;
std::unique_ptr<DebugUI> mDbgUI = nullptr;
std::shared_ptr<sf::RenderWindow> mMainWindow = nullptr;
SysTimer mSysTimer;
std::shared_ptr<sf::RenderWindow> mMainWindow;
std::unique_ptr<CockpitUI> mCockpitUI = nullptr;
std::unique_ptr<WorldUI> mWorldUI = nullptr;

View File

@ -1,18 +1,33 @@
#include <stdexcept>
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Window/ContextSettings.hpp>
#include "icon.h"
#include "Engine/Misc/Logger.hpp"
#include "Game.hpp"
static std::shared_ptr<sf::RenderWindow> InitWindow();
int main(int argc, char** argv) {
SysTimer mSysTimer;
Logger& log = Logger::getInstance();
log.PrintInfo(LOGGER_MSG_FT("Create main window"));
std::shared_ptr<sf::RenderWindow> mainWindow = nullptr;
try {
mainWindow = InitWindow();
} catch (const std::exception& ex) {
log.PrintCritical(std::string(ex.what()));
return EXIT_FAILURE;
}
log.PrintInfo(LOGGER_MSG_FT("Create game instance"));
Game& arcadeGame = Game::getInstance(mainWindow, true);
GAME_STATUS status = GAME_INIT;
log.PrintInfo(LOGGER_MSG_FT("Init game instance"));
Game& arcadeGame = Game::getInstance(true);
for ( ;; ) {
status = arcadeGame.Tick(mSysTimer);
status = arcadeGame.Tick();
if (status == GAME_QUIT)
break;
@ -21,3 +36,29 @@ int main(int argc, char** argv) {
log.PrintInfo(LOGGER_MSG_FT("Bye bye!"));
return EXIT_SUCCESS;
}
static std::shared_ptr<sf::RenderWindow> InitWindow() {
// Create default game window
sf::ContextSettings sWindowSettings;
sWindowSettings.depthBits = 0;
sWindowSettings.stencilBits = 0;
sWindowSettings.antialiasingLevel = 8;
sWindowSettings.sRgbCapable = true;
auto wnd = std::make_shared<sf::RenderWindow>(
sf::VideoMode(1280, 720), "ProtoTank",
(sf::Style::Close | sf::Style::Titlebar),
sWindowSettings
);
if (wnd == nullptr)
throw std::runtime_error("Failed to create the window");
wnd->setVerticalSyncEnabled(false); // Never use simultaneously with framerate limiter
wnd->setFramerateLimit(60); // Never use simultaneously with VSync
wnd->setKeyRepeatEnabled(false);
wnd->setMouseCursorVisible(true);
wnd->setIcon(64, 64, _aicon_bin);
return wnd;
}