From 4459a5f60db483bc3e63587b1c911ca98f415ec7 Mon Sep 17 00:00:00 2001 From: and3md Date: Wed, 22 Mar 2017 19:31:28 +0100 Subject: [PATCH 1/3] Ability to safe destroy widget later by event. --- src/dlangui/core/events.d | 14 ++++++++++++++ src/dlangui/platforms/common/platform.d | 8 +++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/dlangui/core/events.d b/src/dlangui/core/events.d index 3caa30de..f7c95a0b 100644 --- a/src/dlangui/core/events.d +++ b/src/dlangui/core/events.d @@ -1649,6 +1649,20 @@ class RunnableEvent : CustomEvent { } } +/// save destroy event +class SafeDestroyEvent : RunnableEvent { + Widget _widgetToDestroy; + this (Widget widgetToDestroy) + { + _widgetToDestroy = widgetToDestroy; + super(1,null, delegate void () { + if (_widgetToDestroy.parent) + _widgetToDestroy.parent.removeChild(_widgetToDestroy); + destroy(_widgetToDestroy); + }); + } +} + interface CustomEventTarget { /// post event to handle in UI thread (this method can be used from background thread) void postEvent(CustomEvent event); diff --git a/src/dlangui/platforms/common/platform.d b/src/dlangui/platforms/common/platform.d index 63629585..b41617a9 100644 --- a/src/dlangui/platforms/common/platform.d +++ b/src/dlangui/platforms/common/platform.d @@ -519,7 +519,13 @@ class Window : CustomEventTarget { destroy(_timerQueue); _eventList = null; } - + /// safe destroy widget + void safeWidgetDestroy(Widget widgetToDestroy) + { + SafeDestroyEvent ev = new SafeDestroyEvent(widgetToDestroy); + postEvent(ev); + } + private void animate(Widget root, long interval) { if (root is null) return; From a99064eb03df0e4ede28465bed83be8cc3b50a41 Mon Sep 17 00:00:00 2001 From: and3md Date: Thu, 6 Apr 2017 18:46:01 +0200 Subject: [PATCH 2/3] Change name safeWidgetDestroy() and SaveDestroyEvent to more accurate queueWidgetDestroy() and QueueDestroyEvent --- src/dlangui/core/events.d | 4 ++-- src/dlangui/platforms/common/platform.d | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/dlangui/core/events.d b/src/dlangui/core/events.d index f7c95a0b..cf495e3d 100644 --- a/src/dlangui/core/events.d +++ b/src/dlangui/core/events.d @@ -1649,8 +1649,8 @@ class RunnableEvent : CustomEvent { } } -/// save destroy event -class SafeDestroyEvent : RunnableEvent { +/// queue destroy event +class QueueDestroyEvent : RunnableEvent { Widget _widgetToDestroy; this (Widget widgetToDestroy) { diff --git a/src/dlangui/platforms/common/platform.d b/src/dlangui/platforms/common/platform.d index b41617a9..abaa366a 100644 --- a/src/dlangui/platforms/common/platform.d +++ b/src/dlangui/platforms/common/platform.d @@ -519,10 +519,10 @@ class Window : CustomEventTarget { destroy(_timerQueue); _eventList = null; } - /// safe destroy widget - void safeWidgetDestroy(Widget widgetToDestroy) + /// queue destroy widget + void queueWidgetDestroy(Widget widgetToDestroy) { - SafeDestroyEvent ev = new SafeDestroyEvent(widgetToDestroy); + QueueDestroyEvent ev = new QueueDestroyEvent(widgetToDestroy); postEvent(ev); } From 73944287adce43b5416c364b2bddb5e719fbde7f Mon Sep 17 00:00:00 2001 From: and3md Date: Sat, 8 Apr 2017 13:42:34 +0200 Subject: [PATCH 3/3] _widgetToDestroy should be private, enlarged documentation --- src/dlangui/core/events.d | 9 +++++++-- src/dlangui/platforms/common/platform.d | 13 ++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/dlangui/core/events.d b/src/dlangui/core/events.d index cf495e3d..5c3358ab 100644 --- a/src/dlangui/core/events.d +++ b/src/dlangui/core/events.d @@ -1649,9 +1649,14 @@ class RunnableEvent : CustomEvent { } } -/// queue destroy event +/** +Queue destroy event. + +This event allows delayed widget destruction and is used internally by +$(LINK2 $(DDOX_ROOT_DIR)dlangui/platforms/common/platform/Window.queueWidgetDestroy.html, Window.queueWidgetDestroy()). +*/ class QueueDestroyEvent : RunnableEvent { - Widget _widgetToDestroy; + private Widget _widgetToDestroy; this (Widget widgetToDestroy) { _widgetToDestroy = widgetToDestroy; diff --git a/src/dlangui/platforms/common/platform.d b/src/dlangui/platforms/common/platform.d index abaa366a..399505c3 100644 --- a/src/dlangui/platforms/common/platform.d +++ b/src/dlangui/platforms/common/platform.d @@ -519,7 +519,18 @@ class Window : CustomEventTarget { destroy(_timerQueue); _eventList = null; } - /// queue destroy widget + + /** + Allows queue destroy of widget. + + Sometimes when you have very complicated UI with dynamic create/destroy lists of widgets calling simple destroy() + on widget makes segmentation fault. + + Usually because you destroy widget that on some stage call another that tries to destroy widget that calls it. + When the control flow returns widget not exist and you have seg. fault. + + This function use internally $(LINK2 $(DDOX_ROOT_DIR)dlangui/core/events/QueueDestroyEvent.html, QueueDestroyEvent). + */ void queueWidgetDestroy(Widget widgetToDestroy) { QueueDestroyEvent ev = new QueueDestroyEvent(widgetToDestroy);