From 4c09142e306810e58ed099396761be8bc0f26a3d Mon Sep 17 00:00:00 2001 From: "D. Quan" <60545346+sudoker0@users.noreply.github.com> Date: Tue, 24 Mar 2026 13:23:10 +0700 Subject: [PATCH 1/2] Fix VRAM leak --- src/editor/fileViews/roomFileView.cpp | 1 - src/editor/services/childWindowSubService.cpp | 1 - src/editor/services/editorGuiService.cpp | 4 -- src/editor/services/translationService.cpp | 1 - src/editor/views/worldView.cpp | 56 +++++++++++-------- 5 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/editor/fileViews/roomFileView.cpp b/src/editor/fileViews/roomFileView.cpp index 90fc68e..ed1e78c 100644 --- a/src/editor/fileViews/roomFileView.cpp +++ b/src/editor/fileViews/roomFileView.cpp @@ -187,7 +187,6 @@ void RoomFileView::setRoomTool(ToolboxItem tool) { layerVisitor.group->removeAllWidgets(); mj::visit(layerVisitor, static_cast(layerChoose->getSelectedItemIndex())); - cout << "Selected tool: " << tool.text << endl; } RoomFileView::~RoomFileView() { HotkeyService &hks = Editor::instance->getHotkeyService(); diff --git a/src/editor/services/childWindowSubService.cpp b/src/editor/services/childWindowSubService.cpp index f3853f9..d4af3c4 100644 --- a/src/editor/services/childWindowSubService.cpp +++ b/src/editor/services/childWindowSubService.cpp @@ -27,6 +27,5 @@ void ChildWindowSubService::openWindow(const std::string &windowName) { void ChildWindowSubService::resetAndOpen(const std::string windowName) { this->createWindows(); - std::cout << windowName << std::endl; this->openWindow(windowName); } diff --git a/src/editor/services/editorGuiService.cpp b/src/editor/services/editorGuiService.cpp index 7321575..f591cf8 100644 --- a/src/editor/services/editorGuiService.cpp +++ b/src/editor/services/editorGuiService.cpp @@ -43,10 +43,6 @@ void EditorGuiService::init() { auto &hks = Editor::instance->getHotkeyService(); hks.deserialize(cfgs.getField("hotkeys")); - auto serialized = hks.serialize(); - for (auto &[keyId, keyStr] : serialized) { - std::cout << keyId << ": " << keyStr << std::endl; - } this->resetUi(); hks.registerHotkeyCallback("toggle_debug", diff --git a/src/editor/services/translationService.cpp b/src/editor/services/translationService.cpp index 567bee2..815553b 100644 --- a/src/editor/services/translationService.cpp +++ b/src/editor/services/translationService.cpp @@ -97,7 +97,6 @@ void TranslationService::purgeDeadListeners() { } } for (auto id : toBePurged) { - // std::cout << "Purging listener " << id << "\n"; removeListener(id); } } diff --git a/src/editor/views/worldView.cpp b/src/editor/views/worldView.cpp index 1f2790b..35e3e4b 100644 --- a/src/editor/views/worldView.cpp +++ b/src/editor/views/worldView.cpp @@ -22,8 +22,6 @@ WorldView::WorldView(const char *typeName, bool initRenderer) tgui::Vector2f size = getSize(); widgetSize = size; - texture = - LoadRenderTexture(static_cast(size.x), static_cast(size.y)); camera = {}; camera.offset = Vector2{0, 0}; @@ -35,9 +33,6 @@ WorldView::WorldView(const char *typeName, bool initRenderer) } WorldView::~WorldView() { - if (IsRenderTextureValid(texture)) { - UnloadRenderTexture(texture); - } } WorldView::Ptr WorldView::create() { return std::make_shared(); } @@ -55,7 +50,38 @@ tgui::Widget::Ptr WorldView::clone() const { } void WorldView::setSize(const tgui::Layout2d &size) { - tgui::CanvasRaylib::setSize(size); + CanvasBase::setSize(size); + const tgui::Vector2f newSize = getSize(); + + if ((newSize.x > 0) && (newSize.y > 0)) + { + const tgui::Vector2u newTextureSize{newSize}; + // if ((m_textureSize.x < newTextureSize.x) || (m_textureSize.y < newTextureSize.y)) + { + if (m_textureTarget.id > 0) + { + // The m_backendTexture is using the exact same texture as our render target (due to the call to replaceInternalTexture). + // To prevent the texture from being freed twice, we shouldn't let UnloadRenderTexture delete the texture. + m_textureTarget.texture.id = 0; + UnloadRenderTexture(m_textureTarget); + } + TGUI_ASSERT(tgui::isBackendSet() && tgui::getBackend()->hasRenderer() + && std::dynamic_pointer_cast(tgui::getBackend()->getRenderer()), + "CanvasRaylib can only be used when using the Raylib backend renderer"); + + m_textureTarget = LoadRenderTexture(static_cast(newTextureSize.x), static_cast(newTextureSize.y)); + + // Move the ownership of the texture to our backend texture + m_backendTexture->replaceInternalTexture(m_textureTarget.texture); + + if (m_textureTarget.id) + m_textureSize = newTextureSize; + else + m_textureSize = {}; + } + + m_usedTextureSize = newTextureSize; + } } bool WorldView::isMouseOnWidget(tgui::Vector2f pos) const { @@ -125,27 +151,9 @@ void WorldView::keyPressed(const tgui::Event::KeyEvent &event) { bool WorldView::canGainFocus() const { return true; } -void WorldView::resetRender() { - tgui::Vector2f newSize = getSize(); - m_textureTarget = LoadRenderTexture(static_cast(newSize.x), - static_cast(newSize.y)); - m_backendTexture->replaceInternalTexture(m_textureTarget.texture); - if (m_textureTarget.id) { - m_textureSize = tgui::Vector2u{newSize}; - } else { - m_textureSize = {}; - } - m_usedTextureSize = tgui::Vector2u{newSize}; -} - void WorldView::update() { mouseMiddleButton = IsMouseButtonDown(MOUSE_MIDDLE_BUTTON); - if (widgetSize != getSize()) { - widgetSize = getSize(); - resetRender(); - } - BeginTextureMode(m_textureTarget); BeginMode2D(camera); From 7a734f7ead7232b51eb40ff6ae3233e5d08a59cd Mon Sep 17 00:00:00 2001 From: "D. Quan" <60545346+sudoker0@users.noreply.github.com> Date: Tue, 24 Mar 2026 13:25:20 +0700 Subject: [PATCH 2/2] Code linting --- include/editor/project.hpp | 6 ++- .../editor/services/recentProjectService.hpp | 9 ++-- src/editor/screens/welcomeScreen.cpp | 15 +++--- src/editor/services/fileSystemService.cpp | 5 +- src/editor/services/recentProjectService.cpp | 3 +- src/editor/views/worldView.cpp | 50 +++++++++---------- 6 files changed, 46 insertions(+), 42 deletions(-) diff --git a/include/editor/project.hpp b/include/editor/project.hpp index 4e39212..063a1f2 100644 --- a/include/editor/project.hpp +++ b/include/editor/project.hpp @@ -18,8 +18,10 @@ class Project { public: Project(const std::string &path); - static std::string create(const std::string &dirPath, const std::string &title); - static void openProject(const tgui::String &filePath, bool forceSwitch = false); + static std::string create(const std::string &dirPath, + const std::string &title); + static void openProject(const tgui::String &filePath, + bool forceSwitch = false); json toJson(); std::string &getTitle(); std::string &getBasePath(); diff --git a/include/editor/services/recentProjectService.hpp b/include/editor/services/recentProjectService.hpp index 4a9a209..c8f0e69 100644 --- a/include/editor/services/recentProjectService.hpp +++ b/include/editor/services/recentProjectService.hpp @@ -9,10 +9,11 @@ class RecentProjectService { private: - int limit = 10; - std::deque recentProjects; - std::filesystem::path path; - void save(); + int limit = 10; + std::deque recentProjects; + std::filesystem::path path; + void save(); + public: RecentProjectService(); void enqueue(const std::string &projectPath); diff --git a/src/editor/screens/welcomeScreen.cpp b/src/editor/screens/welcomeScreen.cpp index 14d67e1..7daeb64 100644 --- a/src/editor/screens/welcomeScreen.cpp +++ b/src/editor/screens/welcomeScreen.cpp @@ -69,7 +69,7 @@ void screens::WelcomeScreen::initItems(tgui::Group::Ptr layout) { actionsLabel->setTextSize(24); left->add(actionsLabel); bindTranslation(actionsLabel, "screen.starting.actions", - &tgui::Label::setText); + &tgui::Label::setText); const auto newProjButton = tgui::Button::create(); bindTranslation(newProjButton, "menu.file.new_project", @@ -103,8 +103,9 @@ void screens::WelcomeScreen::initItems(tgui::Group::Ptr layout) { right->setAutoLayout(tgui::AutoLayout::Fill); const auto recentProjectLabel = tgui::Label::create(""); - bindTranslation(recentProjectLabel, "screen.starting.recent_projects", - &tgui::Label::setText); + bindTranslation(recentProjectLabel, + "screen.starting.recent_projects", + &tgui::Label::setText); recentProjectLabel->setTextSize(24); recentProjectLabel->setAutoLayout(tgui::AutoLayout::Top); right->add(recentProjectLabel); @@ -112,13 +113,13 @@ void screens::WelcomeScreen::initItems(tgui::Group::Ptr layout) { const auto recentProject = tgui::ListBox::create(); recentProject->setAutoLayout(tgui::AutoLayout::Fill); - for (auto i : Editor::instance->getRecentProjectService().getRecentProjects()) { + for (auto i : + Editor::instance->getRecentProjectService().getRecentProjects()) { recentProject->addItem(i); } - recentProject->onItemSelect([this](const tgui::String& path) { - Project::openProject(path); - }); + recentProject->onItemSelect( + [this](const tgui::String &path) { Project::openProject(path); }); right->add(recentProject); diff --git a/src/editor/services/fileSystemService.cpp b/src/editor/services/fileSystemService.cpp index 3513993..fb4050b 100644 --- a/src/editor/services/fileSystemService.cpp +++ b/src/editor/services/fileSystemService.cpp @@ -62,9 +62,8 @@ void FileSystemService::promptOpenProject() { auto files = tgui::FileDialog::create(); files->setFileTypeFilters({{"RPG++ Project", {"*.rpgpp"}}}); - files->onFileSelect([](const tgui::String &filePath) { - Project::openProject(filePath); - }); + files->onFileSelect( + [](const tgui::String &filePath) { Project::openProject(filePath); }); Editor::instance->getGui().gui->add(files); } diff --git a/src/editor/services/recentProjectService.cpp b/src/editor/services/recentProjectService.cpp index d9be805..2dd2f2e 100644 --- a/src/editor/services/recentProjectService.cpp +++ b/src/editor/services/recentProjectService.cpp @@ -35,7 +35,8 @@ void RecentProjectService::save() { std::ofstream file(path); if (!file.is_open()) { - std::cerr << "Failed to open recent project file for saving" << std::endl; + std::cerr << "Failed to open recent project file for saving" + << std::endl; return; } diff --git a/src/editor/views/worldView.cpp b/src/editor/views/worldView.cpp index 35e3e4b..d74cee3 100644 --- a/src/editor/views/worldView.cpp +++ b/src/editor/views/worldView.cpp @@ -51,37 +51,37 @@ tgui::Widget::Ptr WorldView::clone() const { void WorldView::setSize(const tgui::Layout2d &size) { CanvasBase::setSize(size); - const tgui::Vector2f newSize = getSize(); + const tgui::Vector2f newSize = getSize(); - if ((newSize.x > 0) && (newSize.y > 0)) + if ((newSize.x > 0) && (newSize.y > 0)) + { + const tgui::Vector2u newTextureSize{newSize}; + // if ((m_textureSize.x < newTextureSize.x) || (m_textureSize.y < newTextureSize.y)) { - const tgui::Vector2u newTextureSize{newSize}; - // if ((m_textureSize.x < newTextureSize.x) || (m_textureSize.y < newTextureSize.y)) + if (m_textureTarget.id > 0) { - if (m_textureTarget.id > 0) - { - // The m_backendTexture is using the exact same texture as our render target (due to the call to replaceInternalTexture). - // To prevent the texture from being freed twice, we shouldn't let UnloadRenderTexture delete the texture. - m_textureTarget.texture.id = 0; - UnloadRenderTexture(m_textureTarget); - } - TGUI_ASSERT(tgui::isBackendSet() && tgui::getBackend()->hasRenderer() - && std::dynamic_pointer_cast(tgui::getBackend()->getRenderer()), - "CanvasRaylib can only be used when using the Raylib backend renderer"); - - m_textureTarget = LoadRenderTexture(static_cast(newTextureSize.x), static_cast(newTextureSize.y)); - - // Move the ownership of the texture to our backend texture - m_backendTexture->replaceInternalTexture(m_textureTarget.texture); - - if (m_textureTarget.id) - m_textureSize = newTextureSize; - else - m_textureSize = {}; + // The m_backendTexture is using the exact same texture as our render target (due to the call to replaceInternalTexture). + // To prevent the texture from being freed twice, we shouldn't let UnloadRenderTexture delete the texture. + m_textureTarget.texture.id = 0; + UnloadRenderTexture(m_textureTarget); } + TGUI_ASSERT(tgui::isBackendSet() && tgui::getBackend()->hasRenderer() + && std::dynamic_pointer_cast(tgui::getBackend()->getRenderer()), + "CanvasRaylib can only be used when using the Raylib backend renderer"); - m_usedTextureSize = newTextureSize; + m_textureTarget = LoadRenderTexture(static_cast(newTextureSize.x), static_cast(newTextureSize.y)); + + // Move the ownership of the texture to our backend texture + m_backendTexture->replaceInternalTexture(m_textureTarget.texture); + + if (m_textureTarget.id) + m_textureSize = newTextureSize; + else + m_textureSize = {}; } + + m_usedTextureSize = newTextureSize; + } } bool WorldView::isMouseOnWidget(tgui::Vector2f pos) const {