From 39a29cf8652913d7a4a02cc0eac44251a2f5e006 Mon Sep 17 00:00:00 2001 From: SoftFever Date: Wed, 3 Jun 2026 02:43:41 +0800 Subject: [PATCH] feat(automation): wxWindow automation-id registry --- src/slic3r/CMakeLists.txt | 2 + .../GUI/Automation/AutomationRegistry.cpp | 50 +++++++++++++++++++ .../GUI/Automation/AutomationRegistry.hpp | 19 +++++++ 3 files changed, 71 insertions(+) create mode 100644 src/slic3r/GUI/Automation/AutomationRegistry.cpp create mode 100644 src/slic3r/GUI/Automation/AutomationRegistry.hpp diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 3d4ce6d7a4..295ae683df 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -239,6 +239,8 @@ set(SLIC3R_GUI_SOURCES GUI/Automation/JsonRpcDispatcher.hpp GUI/Automation/AutomationServer.cpp GUI/Automation/AutomationServer.hpp + GUI/Automation/AutomationRegistry.cpp + GUI/Automation/AutomationRegistry.hpp GUI/I18N.cpp GUI/I18N.hpp GUI/DragDropPanel.cpp diff --git a/src/slic3r/GUI/Automation/AutomationRegistry.cpp b/src/slic3r/GUI/Automation/AutomationRegistry.cpp new file mode 100644 index 0000000000..3f8dc8becc --- /dev/null +++ b/src/slic3r/GUI/Automation/AutomationRegistry.cpp @@ -0,0 +1,50 @@ +#include "AutomationRegistry.hpp" +#include +#include +#include +#include + +namespace Slic3r { namespace GUI { namespace Automation { + +namespace { +std::mutex& mtx() { static std::mutex m; return m; } +std::unordered_map& fwd() { + static std::unordered_map m; return m; +} +std::unordered_map& rev() { + static std::unordered_map m; return m; +} +void erase_window(const wxWindow* w) { + std::lock_guard lk(mtx()); + auto it = fwd().find(w); + if (it != fwd().end()) { rev().erase(it->second); fwd().erase(it); } +} +} // namespace + +void set_automation_id(wxWindow* window, const std::string& id) { + if (window == nullptr || id.empty()) return; + { + std::lock_guard lk(mtx()); + fwd()[window] = id; + rev()[id] = window; + } + // Prune on destruction. + window->Bind(wxEVT_DESTROY, [window](wxWindowDestroyEvent& e) { + erase_window(window); + e.Skip(); + }); +} + +std::string automation_id_of(const wxWindow* window) { + std::lock_guard lk(mtx()); + auto it = fwd().find(window); + return it == fwd().end() ? std::string() : it->second; +} + +wxWindow* window_for_automation_id(const std::string& id) { + std::lock_guard lk(mtx()); + auto it = rev().find(id); + return it == rev().end() ? nullptr : it->second; +} + +}}} // namespace diff --git a/src/slic3r/GUI/Automation/AutomationRegistry.hpp b/src/slic3r/GUI/Automation/AutomationRegistry.hpp new file mode 100644 index 0000000000..f60512f7c1 --- /dev/null +++ b/src/slic3r/GUI/Automation/AutomationRegistry.hpp @@ -0,0 +1,19 @@ +#pragma once +#include +#include + +class wxWindow; + +namespace Slic3r { namespace GUI { namespace Automation { + +// Process-wide wxWindow* <-> automation_id side map. Header is dependency-light so +// widget-construction code can call set_automation_id() unconditionally — it is a +// cheap, safe registration that no-ops when the window is null. +// +// Registration is pruned automatically when the window is destroyed (bound to +// wxEVT_DESTROY inside set_automation_id). +void set_automation_id(wxWindow* window, const std::string& id); +std::string automation_id_of(const wxWindow* window); // "" if none +wxWindow* window_for_automation_id(const std::string& id); // nullptr if none + +}}} // namespace