From e230d7b902831b9e6fdac4eebffd73087fb4b6cd Mon Sep 17 00:00:00 2001 From: maj00r Date: Tue, 3 Nov 2026 21:45:58 +0100 Subject: [PATCH] fix: a deleted model is no longer the picked node, an orthophoto tile isn't swept as a grey stub, the ED brake arrays freed Deleting a model in the editor left the renderer holding it as the picked node, the next pick used freed memory: the renderer forgets it now (Forget_Node). A texture filled straight from memory (internalsrc:) can't be read again, released by the garbage sweep it came back grey; it stays now, and the units bound with the old name are rebound. The arrays of the ED brake force sharing are vectors, they leaked once per update. The scene hierarchy and the editor menu items go through the translation. Python caches ignored. --- .gitignore | 2 ++ application/uilayer.cpp | 10 +++++----- model/Texture.cpp | 10 ++++++++++ rendering/opengl33renderer.cpp | 7 +++++++ rendering/opengl33renderer.h | 2 ++ rendering/openglrenderer.cpp | 9 +++++++++ rendering/openglrenderer.h | 2 ++ rendering/renderer.h | 2 ++ simulation/simulation.cpp | 4 ++++ vehicle/DynObj.cpp | 16 ++++------------ 10 files changed, 47 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index 5186ceaee..70a6d1c68 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ vcpkg.json # Local Python (setup.bat / CMake) for embedding tools/python314/ +__pycache__/ +*.pyc diff --git a/application/uilayer.cpp b/application/uilayer.cpp index 2dd771bdd..d8417e4fe 100644 --- a/application/uilayer.cpp +++ b/application/uilayer.cpp @@ -567,7 +567,7 @@ void ui_layer::render_hierarchy(){ // fitted to the contents when it first appears; no auto resize, which a docked window can't do ImGui::SetNextWindowSize(ImVec2(0, 0), ImGuiCond_FirstUseEver); ImGui::Begin((std::string(STR_C("Scene Hierarchy")) + "###scenehierarchy").c_str(), &m_editor_hierarchy); - ImGui::Text("Registered nodes: %zu", scene::Hierarchy.size()); + ImGui::Text(STR_C("Registered nodes: %zu"), scene::Hierarchy.size()); ImGui::BeginChild("hierarchy_list", ImVec2(500, 300), true); for (auto &entry : scene::Hierarchy) @@ -598,7 +598,7 @@ void ui_layer::render_hierarchy(){ if (ImGui::IsItemHovered()) { - ImGui::SetTooltip("UUID: %s\nNode type: %s", uuid.c_str(), typeid(*node).name()); + ImGui::SetTooltip(STR_C("UUID: %s\nNode type: %s"),uuid.c_str(), typeid(*node).name()); } } } @@ -708,14 +708,14 @@ void ui_layer::render_menu_contents() GfxRenderer->Debug_Ui_State(ret); } if(EditorModeFlag){ - ImGui::MenuItem("Hierarchy", nullptr, &m_editor_hierarchy); + ImGui::MenuItem(STR_C("Scene Hierarchy"), nullptr, &m_editor_hierarchy); bool change_history_enabled = editor_mode::change_history(); - if (ImGui::MenuItem("Change History", nullptr, &change_history_enabled)) + if (ImGui::MenuItem(STR_C("Change History"), nullptr, &change_history_enabled)) { editor_mode::set_change_history(change_history_enabled); } bool settings_open = editor_mode::settings_open(); - if (ImGui::MenuItem("Editor Settings", nullptr, &settings_open)) + if (ImGui::MenuItem(STR_C("Editor Settings"), nullptr, &settings_open)) { editor_mode::set_settings_open(settings_open); } diff --git a/model/Texture.cpp b/model/Texture.cpp index 136846a33..4a7b24792 100644 --- a/model/Texture.cpp +++ b/model/Texture.cpp @@ -706,6 +706,16 @@ void opengl_texture::update_from_memory(size_t width, size_t height, const uint8 if (glGenerateMipmap) glGenerateMipmap(target); glFlush(); + // the content given straight to the gpu can't be read again: released by the garbage sweep, the texture would come back as + // the grey stub + if (type == "internalsrc:") + { + is_static = true; + is_ready = true; + } + // the name may be a new one, and the unit active took the texture past the unit cache + for (auto &unit : units) + unit = -1; } void diff --git a/rendering/opengl33renderer.cpp b/rendering/opengl33renderer.cpp index d20454c35..a5d1f3894 100644 --- a/rendering/opengl33renderer.cpp +++ b/rendering/opengl33renderer.cpp @@ -5410,6 +5410,13 @@ void opengl33_renderer::Pick_Node_Callback(std::functionis_busy()) diff --git a/rendering/opengl33renderer.h b/rendering/opengl33renderer.h index 64574420f..0f17ede7f 100644 --- a/rendering/opengl33renderer.h +++ b/rendering/opengl33renderer.h @@ -108,6 +108,8 @@ class opengl33_renderer : public gfx_renderer { Pick_Control() const override { return m_pickcontrolitem; } scene::basic_node const * Pick_Node() const override { return m_picksceneryitem; } + void + Forget_Node( scene::basic_node const *Node ) override; glm::dvec3 Mouse_Position() const override { return m_worldmousecoordinates; } bool diff --git a/rendering/openglrenderer.cpp b/rendering/openglrenderer.cpp index 59152c64d..864d84141 100644 --- a/rendering/openglrenderer.cpp +++ b/rendering/openglrenderer.cpp @@ -1888,6 +1888,15 @@ opengl_renderer::Pick_Node_Callback( std::function m_node_pick_requests.emplace_back( Callback ); } +void +opengl_renderer::Forget_Node( scene::basic_node const *Node ) { + + if( m_picksceneryitem == Node ) { + m_picksceneryitem = nullptr; + } + std::replace_if( m_picksceneryitems.begin(), m_picksceneryitems.end(), [Node]( scene::basic_node const *Item ) { return Item == Node; }, nullptr ); +} + void opengl_renderer::Render( scene::basic_region *Region ) { diff --git a/rendering/openglrenderer.h b/rendering/openglrenderer.h index 78fffa40b..ada032808 100644 --- a/rendering/openglrenderer.h +++ b/rendering/openglrenderer.h @@ -103,6 +103,8 @@ public: Pick_Control() const override { return m_pickcontrolitem; } scene::basic_node const * Pick_Node() const override { return m_picksceneryitem; } + void + Forget_Node( scene::basic_node const *Node ) override; glm::dvec3 Mouse_Position() const override { return m_worldmousecoordinates; } glm::mat4 diff --git a/rendering/renderer.h b/rendering/renderer.h index 0b9eb60f4..e9dc8a47c 100644 --- a/rendering/renderer.h +++ b/rendering/renderer.h @@ -90,6 +90,8 @@ public: virtual void Pick_Node_Callback( std::function Callback ) = 0; virtual auto Pick_Control() const -> TSubModel const * = 0; virtual auto Pick_Node() const -> scene::basic_node const * = 0; + // a node deleted from the scene is no longer given as picked + virtual void Forget_Node( scene::basic_node const *Node ) {} virtual auto Mouse_Position() const -> glm::dvec3 = 0; virtual auto Mouse_Hit() const -> bool { return true; } diff --git a/simulation/simulation.cpp b/simulation/simulation.cpp index 70f9e3074..ea2177170 100644 --- a/simulation/simulation.cpp +++ b/simulation/simulation.cpp @@ -30,6 +30,7 @@ http://mozilla.org/MPL/2.0/. #include "scene/scenelayers.h" #include "vehicle/Train.h" #include "application/application.h" +#include "rendering/renderer.h" #include "utilities/Logs.h" #include "vehicle/Driver.h" @@ -561,6 +562,9 @@ std::pair state_manager::rebuild_include(scene::instance_handle const } void state_manager::delete_model(TAnimModel *model) { + if (GfxRenderer) { + GfxRenderer->Forget_Node(model); + } scene::Layers.count(model->layer(), scene::layer_item::model, -1); scene::Layers.forget(model); Region->erase(model); diff --git a/vehicle/DynObj.cpp b/vehicle/DynObj.cpp index c6793e454..2309c433b 100644 --- a/vehicle/DynObj.cpp +++ b/vehicle/DynObj.cpp @@ -3381,15 +3381,12 @@ bool TDynamicObject::Update(double dt, double dt1) && MoverParameters->eimc[eimc_p_abed] < 0.001) FzadED = 0; //pętla bezpieczeństwa - bez ED auto const FzadPN = Fzad - FrED * MoverParameters->MED_FrED_factor; - //np = 0; - // BUG: likely memory leak, allocation per inner loop, deleted only once outside - // TODO: sort this shit out - bool* PrzekrF = new bool[np]; + std::vector PrzekrF( np ); float nPrzekrF = 0; bool test = true; - float* FzED = new float[np]; - float* FzEP = new float[np]; - float* FmaxEP = new float[np]; + std::vector FzED( np ); + std::vector FzEP( np ); + std::vector FmaxEP( np ); // 3. ustaw pojazdom sile hamowania ED // - proporcjonalnie do mozliwosci @@ -3548,11 +3545,6 @@ bool TDynamicObject::Update(double dt, double dt1) } - delete[] PrzekrF; - delete[] FzED; - delete[] FzEP; - delete[] FmaxEP; - MED_oldFED = FzadED; }