https://github.com/libsdl-org/Maelstrom/commit/b254839f6eb7c001b9d26c92f7af1a387c6a3f3c
From b254839f6eb7c001b9d26c92f7af1a387c6a3f3c Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 6 Nov 2011 10:56:17 -0500
Subject: [PATCH] Defer deleting panels until we're done with the tick/draw
cycle, to prevent crashes.
---
screenlib/UIManager.cpp | 21 +++++++++++++++++++--
screenlib/UIManager.h | 1 +
screenlib/UIPanel.cpp | 6 +++++-
screenlib/UIPanel.h | 1 +
4 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/screenlib/UIManager.cpp b/screenlib/UIManager.cpp
index aa348b07..b9fbb98f 100644
--- a/screenlib/UIManager.cpp
+++ b/screenlib/UIManager.cpp
@@ -218,17 +218,26 @@ UIManager::DeletePanel(UIPanel *panel)
// Remove us so we don't recurse in HidePanel() or callbacks
m_panels.remove(panel);
HidePanel(panel);
- delete panel;
+ m_delete.add(panel);
}
}
void
UIManager::Draw(bool fullUpdate)
{
+ int i;
+
+ // Run the tick before we draw in case it changes drawing state
+ for (i = 0; i < m_visible.length(); ++i) {
+ UIPanel *panel = m_visible[i];
+
+ panel->Tick();
+ }
+
if (fullUpdate) {
m_screen->Clear();
}
- for (int i = 0; i < m_visible.length(); ++i) {
+ for (i = 0; i < m_visible.length(); ++i) {
UIPanel *panel = m_visible[i];
panel->Draw();
@@ -236,6 +245,14 @@ UIManager::Draw(bool fullUpdate)
if (fullUpdate) {
m_screen->Update();
}
+
+ // Clean up any deleted panels when we're done...
+ if (!m_delete.empty()) {
+ for (i = 0; i < m_delete.length(); ++i) {
+ delete m_delete[i];
+ }
+ m_delete.clear();
+ }
}
bool
diff --git a/screenlib/UIManager.h b/screenlib/UIManager.h
index 4df91be5..bf0289d5 100644
--- a/screenlib/UIManager.h
+++ b/screenlib/UIManager.h
@@ -111,6 +111,7 @@ class UIManager : public UIArea, public UIFontInterface, public UISoundInterface
UITemplates m_templates;
array<UIPanel *> m_panels;
array<UIPanel *> m_visible;
+ array<UIPanel *> m_delete;
};
#endif // _UIManager_h
diff --git a/screenlib/UIPanel.cpp b/screenlib/UIPanel.cpp
index c911b714..f586b4c8 100644
--- a/screenlib/UIPanel.cpp
+++ b/screenlib/UIPanel.cpp
@@ -130,12 +130,16 @@ UIPanel::HideAll()
}
void
-UIPanel::Draw()
+UIPanel::Tick()
{
if (m_delegate) {
m_delegate->OnTick();
}
+}
+void
+UIPanel::Draw()
+{
UIBaseElement::Draw();
if (m_delegate) {
diff --git a/screenlib/UIPanel.h b/screenlib/UIPanel.h
index 8a5d27bb..137a6bc0 100644
--- a/screenlib/UIPanel.h
+++ b/screenlib/UIPanel.h
@@ -74,6 +74,7 @@ DECLARE_TYPESAFE_CLASS(UIBaseElement)
void HideAll();
+ virtual void Tick();
override void Draw();
override bool HandleEvent(const SDL_Event &event);