From 4bafad708e60bf111d124843c22b338cc896b466 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 9 Nov 2025 19:09:35 +0300 Subject: [PATCH] move window-related code from Engine.cpp to WindowControl --- src/engine/Engine.cpp | 63 ++++------------------------ src/engine/Engine.hpp | 4 +- src/engine/WindowControl.cpp | 81 ++++++++++++++++++++++++++++++++++++ src/engine/WindowControl.hpp | 24 +++++++++++ src/io/engine_paths.cpp | 2 +- src/io/engine_paths.hpp | 2 +- 6 files changed, 116 insertions(+), 60 deletions(-) create mode 100644 src/engine/WindowControl.cpp create mode 100644 src/engine/WindowControl.hpp diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 1b8cd440..7f920833 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -8,8 +8,6 @@ #include "assets/AssetsLoader.hpp" #include "audio/audio.hpp" #include "coders/GLSLExtension.hpp" -#include "coders/imageio.hpp" -#include "coders/json.hpp" #include "coders/toml.hpp" #include "coders/commons.hpp" #include "devtools/Editor.hpp" @@ -23,23 +21,21 @@ #include "frontend/screens/Screen.hpp" #include "graphics/render/ModelsGenerator.hpp" #include "graphics/core/DrawContext.hpp" -#include "graphics/core/ImageData.hpp" #include "graphics/core/Shader.hpp" #include "graphics/ui/GUI.hpp" #include "graphics/ui/elements/Menu.hpp" -#include "objects/rigging.hpp" #include "logic/EngineController.hpp" #include "logic/CommandsInterpreter.hpp" #include "logic/scripting/scripting.hpp" #include "logic/scripting/scripting_hud.hpp" #include "network/Network.hpp" #include "util/platform.hpp" -#include "window/Camera.hpp" #include "window/input.hpp" #include "window/Window.hpp" #include "world/Level.hpp" #include "Mainloop.hpp" #include "ServerMainloop.hpp" +#include "WindowControl.hpp" #include #include @@ -50,18 +46,6 @@ static debug::Logger logger("engine"); -static std::unique_ptr load_icon() { - try { - auto file = "res:textures/misc/icon.png"; - if (io::exists(file)) { - return imageio::read(file); - } - } catch (const std::exception& err) { - logger.error() << "could not load window icon: " << err.what(); - } - return nullptr; -} - static std::unique_ptr load_project_client_script() { io::path scriptFile = "project:project_client.lua"; if (io::exists(scriptFile)) { @@ -119,29 +103,9 @@ void Engine::onContentLoad() { } void Engine::initializeClient() { - std::string title = project->title; - if (title.empty()) { - title = "VoxelCore v" + - std::to_string(ENGINE_VERSION_MAJOR) + "." + - std::to_string(ENGINE_VERSION_MINOR); - } - if (ENGINE_DEBUG_BUILD) { - title += " [debug]"; - } - if (debuggingServer) { - title = "[debugging] " + title; - } - auto [window, input] = Window::initialize(&settings.display, title); - if (!window || !input){ - throw initialize_error("could not initialize window"); - } - window->setFramerate(settings.display.framerate.get()); + windowControl = std::make_unique(*this); + auto [window, input] = windowControl->initialize(); - time.set(window->time()); - if (auto icon = load_icon()) { - icon->flipY(); - window->setIcon(icon.get()); - } this->window = std::move(window); this->input = std::move(input); @@ -270,7 +234,7 @@ void Engine::loadControls() { void Engine::updateHotkeys() { if (input->jpressed(Keycode::F2)) { - saveScreenshot(); + windowControl->saveScreenshot(); } if (input->pressed(Keycode::LEFT_CONTROL) && input->pressed(Keycode::F3) && input->jpressed(Keycode::U)) { @@ -285,14 +249,6 @@ void Engine::updateHotkeys() { } } -void Engine::saveScreenshot() { - auto image = window->takeScreenshot(); - image->flipY(); - io::path filename = paths.getNewScreenshotFile("png"); - imageio::write(filename.string(), image.get()); - logger.info() << "saved screenshot as " << filename.string(); -} - void Engine::run() { if (params.headless) { ServerMainloop(*this).run(); @@ -331,13 +287,7 @@ void Engine::updateFrontend() { } void Engine::nextFrame() { - window->setFramerate( - window->isIconified() && settings.display.limitFpsIconified.get() - ? 20 - : settings.display.framerate.get() - ); - window->swapBuffers(); - input->pollEvents(); + windowControl->nextFrame(); } void Engine::startPauseLoop() { @@ -437,7 +387,8 @@ void Engine::loadAssets() { // no need // correct log messages order is more useful - bool threading = false; // look at two upper lines + // todo: before setting to true, check if GLSLExtension thread safe + bool threading = false; // look at three upper lines if (threading) { auto task = loader.startTask([=](){}); task->waitForEnd(); diff --git a/src/engine/Engine.hpp b/src/engine/Engine.hpp index 468563d0..2049258f 100644 --- a/src/engine/Engine.hpp +++ b/src/engine/Engine.hpp @@ -14,6 +14,7 @@ #include class Window; +class WindowControl; class Assets; class Level; class Screen; @@ -75,6 +76,7 @@ class Engine : public util::ObjectsKeeper { std::unique_ptr gui; std::unique_ptr editor; std::unique_ptr debuggingServer; + std::unique_ptr windowControl; PostRunnables postRunnables; Time time; OnWorldOpen levelConsumer; @@ -144,8 +146,6 @@ public: postRunnables.postRunnable(callback); } - void saveScreenshot(); - EngineController* getController(); void setLevelConsumer(OnWorldOpen levelConsumer); diff --git a/src/engine/WindowControl.cpp b/src/engine/WindowControl.cpp new file mode 100644 index 00000000..edf0a6e7 --- /dev/null +++ b/src/engine/WindowControl.cpp @@ -0,0 +1,81 @@ +#include "WindowControl.hpp" + +#include "Engine.hpp" +#include "devtools/Project.hpp" +#include "coders/imageio.hpp" +#include "window/Window.hpp" +#include "window/input.hpp" +#include "debug/Logger.hpp" +#include "graphics/core/ImageData.hpp" + +static debug::Logger logger("window-control"); + +namespace { + static std::unique_ptr load_icon() { + try { + auto file = "res:textures/misc/icon.png"; + if (io::exists(file)) { + return imageio::read(file); + } + } catch (const std::exception& err) { + logger.error() << "could not load window icon: " << err.what(); + } + return nullptr; + } +} + +WindowControl::WindowControl(Engine& engine) : engine(engine) {} + +WindowControl::Result WindowControl::initialize() { + const auto& project = engine.getProject(); + auto& settings = engine.getSettings(); + + std::string title = project.title; + if (title.empty()) { + title = "VoxelCore v" + + std::to_string(ENGINE_VERSION_MAJOR) + "." + + std::to_string(ENGINE_VERSION_MINOR); + } + if (ENGINE_DEBUG_BUILD) { + title += " [debug]"; + } + if (engine.getDebuggingServer()) { + title = "[debugging] " + title; + } + + auto [window, input] = Window::initialize(&settings.display, title); + if (!window || !input){ + throw initialize_error("could not initialize window"); + } + window->setFramerate(settings.display.framerate.get()); + if (auto icon = load_icon()) { + icon->flipY(); + window->setIcon(icon.get()); + } + + return Result {std::move(window), std::move(input)}; +} + +void WindowControl::saveScreenshot() { + auto& window = engine.getWindow(); + const auto& paths = engine.getPaths(); + + auto image = window.takeScreenshot(); + image->flipY(); + io::path filename = paths.getNewScreenshotFile("png"); + imageio::write(filename.string(), image.get()); + logger.info() << "saved screenshot as " << filename.string(); +} + +void WindowControl::nextFrame() { + const auto& settings = engine.getSettings(); + auto& window = engine.getWindow(); + auto& input = engine.getInput(); + window.setFramerate( + window.isIconified() && settings.display.limitFpsIconified.get() + ? 20 + : settings.display.framerate.get() + ); + window.swapBuffers(); + input.pollEvents(); +} diff --git a/src/engine/WindowControl.hpp b/src/engine/WindowControl.hpp new file mode 100644 index 00000000..807d9758 --- /dev/null +++ b/src/engine/WindowControl.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include + +class Window; +class Input; +class Engine; + +class WindowControl { +public: + struct Result { + std::unique_ptr window; + std::unique_ptr input; + }; + WindowControl(Engine& engine); + + Result initialize(); + + void nextFrame(); + + void saveScreenshot(); +private: + Engine& engine; +}; diff --git a/src/io/engine_paths.cpp b/src/io/engine_paths.cpp index 98363d9b..ef102621 100644 --- a/src/io/engine_paths.cpp +++ b/src/io/engine_paths.cpp @@ -67,7 +67,7 @@ const std::filesystem::path& EnginePaths::getResourcesFolder() const { return resourcesFolder; } -io::path EnginePaths::getNewScreenshotFile(const std::string& ext) { +io::path EnginePaths::getNewScreenshotFile(const std::string& ext) const { auto folder = SCREENSHOTS_FOLDER; if (!io::is_directory(folder)) { io::create_directories(folder); diff --git a/src/io/engine_paths.hpp b/src/io/engine_paths.hpp index 8b9b7f8e..0fa58874 100644 --- a/src/io/engine_paths.hpp +++ b/src/io/engine_paths.hpp @@ -63,7 +63,7 @@ public: void setCurrentWorldFolder(io::path folder); io::path getCurrentWorldFolder(); - io::path getNewScreenshotFile(const std::string& ext); + io::path getNewScreenshotFile(const std::string& ext) const; std::string mount(const io::path& file); void unmount(const std::string& name);