[Scummvm-git-logs] scummvm master -> 082d0efdccdc7f65a2be543cf8f1a95c87f67345

sev- sev at scummvm.org
Sat Mar 11 10:08:16 CET 2017


This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
cc75d17e9c GUI: Allow delayed deletion of GuiObject
1a874f9c07 GUI: Delay deletion of child widgets when rebuilding launcher and options dialog
082d0efdcc Merge pull request #920 from criezy/gui-delete-later


Commit: cc75d17e9c9d4074d94826165fb3831090a502b1
    https://github.com/scummvm/scummvm/commit/cc75d17e9c9d4074d94826165fb3831090a502b1
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2017-03-10T02:02:58Z

Commit Message:
GUI: Allow delayed deletion of GuiObject

This is achieved by adding a list of GuiObject to delete to GuiManager
and doing the deletion in GuiManager::runLoop.

The main purpose of this is to avoid the deletion of ButtonWidget object
while their ButtonWidget::sendCommand function is being called. For
example the sendCommand of the Apply button of the OptionsDialog
may cause a rebuild (if the GUI language was changed) which tries to
delete the widgets inside the OptionsDialog, including the Apply button.

Changed paths:
    gui/gui-manager.cpp
    gui/gui-manager.h


diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp
index d28a0df..feb4e50 100644
--- a/gui/gui-manager.cpp
+++ b/gui/gui-manager.cpp
@@ -254,6 +254,23 @@ Dialog *GuiManager::getTopDialog() const {
 	return _dialogStack.top();
 }
 
+void GuiManager::addToTrash(GuiObject* object, Dialog* parent) {
+	debug(7, "Adding Gui Object %p to trash", object);
+	GuiObjectTrashItem t;
+	t.object = object;
+	t.parent = 0;
+	// If a dialog was provided, check it is in the dialog stack
+	if (parent != 0) {
+		for (int i = 0 ; i < _dialogStack.size() ; ++i) {
+			if (_dialogStack[i] == parent) {
+				t.parent = parent;
+				break;
+			}
+		}
+	}
+	_guiObjectTrash.push_back(t);
+}
+
 void GuiManager::runLoop() {
 	Dialog * const activeDialog = getTopDialog();
 	bool didSaveState = false;
@@ -341,6 +358,17 @@ void GuiManager::runLoop() {
 			}
 		}
 
+		// Delete GuiObject that have been added to the trash for a delayed deletion
+		Common::List<GuiObjectTrashItem>::iterator it = _guiObjectTrash.begin();
+		while (it != _guiObjectTrash.end()) {
+			if ((*it).parent == 0 || (*it).parent == activeDialog) {
+				debug(7, "Delayed deletion of Gui Object %p", (*it).object);
+				delete (*it).object;
+				it = _guiObjectTrash.erase(it);
+			} else
+				++it;
+		}
+
 		if (_lastMousePosition.time + kTooltipDelay < _system->getMillis(true)) {
 			Widget *wdg = activeDialog->findWidget(_lastMousePosition.x, _lastMousePosition.y);
 			if (wdg && wdg->hasTooltip() && !(wdg->getFlags() & WIDGET_PRESSED)) {
diff --git a/gui/gui-manager.h b/gui/gui-manager.h
index 4dc9af9..82a8aa9 100644
--- a/gui/gui-manager.h
+++ b/gui/gui-manager.h
@@ -27,6 +27,7 @@
 #include "common/singleton.h"
 #include "common/stack.h"
 #include "common/str.h"
+#include "common/list.h"
 
 #include "gui/ThemeEngine.h"
 
@@ -44,6 +45,7 @@ namespace GUI {
 
 class Dialog;
 class ThemeEval;
+class GuiObject;
 
 #define g_gui	(GUI::GuiManager::instance())
 
@@ -99,6 +101,13 @@ public:
 	 */
 	bool checkScreenChange();
 
+	/**
+	 * Tell the GuiManager to delete the given GuiObject later. If a parent
+	 * dialog is provided and is present in the DialogStack, the object will
+	 * only be deleted when that dialog is the top level dialog.
+	 */
+	void addToTrash(GuiObject*, Dialog* parent = 0);
+
 	bool _launched;
 
 protected:
@@ -137,6 +146,13 @@ protected:
 	int		_cursorAnimateTimer;
 	byte	_cursor[2048];
 
+	// delayed deletion of GuiObject
+	struct GuiObjectTrashItem {
+		GuiObject* object;
+		Dialog* parent;
+	};
+	Common::List<GuiObjectTrashItem> _guiObjectTrash;
+
 	void initKeymap();
 	void pushKeymap();
 	void popKeymap();


Commit: 1a874f9c0748486e86dcdbeb31a9065c36d5eaf4
    https://github.com/scummvm/scummvm/commit/1a874f9c0748486e86dcdbeb31a9065c36d5eaf4
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2017-03-10T02:05:27Z

Commit Message:
GUI: Delay deletion of child widgets when rebuilding launcher and options dialog

This is to avoid writing in deleted memory in the ButtonWidget::sendCommand
when the sent command results in the parent dialog being rebuilt.

Changed paths:
    gui/launcher.cpp
    gui/options.cpp


diff --git a/gui/launcher.cpp b/gui/launcher.cpp
index f96dd17..f60fecf 100644
--- a/gui/launcher.cpp
+++ b/gui/launcher.cpp
@@ -204,7 +204,10 @@ void LauncherDialog::clean() {
 	while (_firstWidget) {
 		Widget* w = _firstWidget;
 		removeWidget(w);
-		delete w;
+		// This is called from rebuild() which may result from handleCommand being called by
+		// a child widget sendCommand call. In such a case sendCommand is still being executed
+		// so we should not delete yet the child widget. Thus delay the deletion.
+		g_gui.addToTrash(w, this);
 	}
 	delete _browser;
 	delete _loadDialog;
diff --git a/gui/options.cpp b/gui/options.cpp
index 7a22a9b..179fa65 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -423,7 +423,10 @@ void OptionsDialog::clean() {
 	while (_firstWidget) {
 		Widget* w = _firstWidget;
 		removeWidget(w);
-		delete w;
+		// This is called from rebuild() which may result from handleCommand being called by
+		// a child widget sendCommand call. In such a case sendCommand is still being executed
+		// so we should not delete yet the child widget. Thus delay the deletion.
+		g_gui.addToTrash(w, this);
 	}
 	init();
 }


Commit: 082d0efdccdc7f65a2be543cf8f1a95c87f67345
    https://github.com/scummvm/scummvm/commit/082d0efdccdc7f65a2be543cf8f1a95c87f67345
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2017-03-11T10:08:12+01:00

Commit Message:
Merge pull request #920 from criezy/gui-delete-later

GUI: Delay deletion of widgets when rebuilding launcher and options dialogs

Changed paths:
    gui/gui-manager.cpp
    gui/gui-manager.h
    gui/launcher.cpp
    gui/options.cpp







More information about the Scummvm-git-logs mailing list