diff --git a/src/Tizen.NUI/src/public/Common/BaseHandle.cs b/src/Tizen.NUI/src/public/Common/BaseHandle.cs
index b724019f8bc..61cafd19ce8 100755
--- a/src/Tizen.NUI/src/public/Common/BaseHandle.cs
+++ b/src/Tizen.NUI/src/public/Common/BaseHandle.cs
@@ -15,6 +15,7 @@
*
*/
using System;
+using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Tizen.NUI.Binding;
@@ -33,6 +34,8 @@ namespace Tizen.NUI
/// 3
public class BaseHandle : Element, global::System.IDisposable
{
+ private static Dictionary> nativeBindedHolder = new Dictionary>();
+
static internal void Preload()
{
// Do nothing. Just call for load static values.
@@ -287,7 +290,7 @@ public static explicit operator bool(BaseHandle handle)
}
///
- /// Logical OR operator for ||.
+ /// Logical OR operator for ||.
/// It's possible when doing a || this function (opBitwiseOr) is never called due to short circuiting.
///
/// The first BaseHandle to be compared.
@@ -375,7 +378,7 @@ public void Dispose()
///
/// Hidden API (Inhouse API).
- /// Dispose.
+ /// Dispose.
/// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
///
///
@@ -622,6 +625,9 @@ protected virtual void Dispose(DisposeTypes type)
if (SwigCPtr.Handle != IntPtr.Zero)
{
var nativeSwigCPtr = swigCPtr.Handle;
+
+ ClearHolder(nativeSwigCPtr);
+
swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
if (swigCMemOwn)
{
@@ -654,6 +660,49 @@ protected virtual void ReleaseSwigCPtr(System.Runtime.InteropServices.HandleRef
Interop.BaseHandle.DeleteBaseHandle(swigCPtr.Handle);
}
+ ///
+ /// Adds the specified object to the set of objects that have been bound to the native object.
+ ///
+ /// The object to add.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected void AddToNativeHolder(object obj)
+ {
+ if (IsDisposedOrQueued)
+ {
+ return;
+ }
+
+ if (!nativeBindedHolder.TryGetValue(swigCPtr.Handle, out var holders))
+ {
+ nativeBindedHolder.Add(swigCPtr.Handle, holders = new HashSet());
+ }
+
+ holders.Add(obj);
+ }
+
+ ///
+ /// Removes the specified object from the set of objects that have been bound to the native object.
+ ///
+ /// The object to remove.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected void RemoveFromNativeHolder(object obj)
+ {
+ if (IsDisposedOrQueued)
+ {
+ return;
+ }
+
+ if (nativeBindedHolder.TryGetValue(swigCPtr.Handle, out var holders))
+ {
+ holders.Remove(obj);
+
+ if (holders.Count == 0)
+ {
+ nativeBindedHolder.Remove(swigCPtr.Handle);
+ }
+ }
+ }
+
///
/// Contains event arguments for the FocusChangeRequested event.
///
@@ -728,6 +777,14 @@ internal bool IsNativeHandleInvalid()
[EditorBrowsable(EditorBrowsableState.Never)]
protected internal bool IsDisposeQueued => isDisposeQueued;
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected internal bool IsDisposedOrQueued => disposed || isDisposeQueued;
+
+ static private void ClearHolder(IntPtr handle)
+ {
+ nativeBindedHolder.Remove(handle);
+ }
+
[Conditional("NUI_DISPOSE_DEBUG_ON")]
private void disposeDebuggingCtor()
{
diff --git a/src/Tizen.NUI/src/public/Window/WindowEvent.cs b/src/Tizen.NUI/src/public/Window/WindowEvent.cs
index 5cb61ef37e4..f416a081c4d 100755
--- a/src/Tizen.NUI/src/public/Window/WindowEvent.cs
+++ b/src/Tizen.NUI/src/public/Window/WindowEvent.cs
@@ -20,6 +20,7 @@
using System.Runtime.InteropServices;
using Tizen.NUI.BaseComponents;
using System.Collections.Generic;
+using System.Diagnostics;
namespace Tizen.NUI
{
@@ -106,7 +107,7 @@ public event EventHandler FocusChanged
{
if (windowFocusChangedEventHandler == null)
{
- windowFocusChangedEventCallback = OnWindowFocusedChanged;
+ CreateSafeCallback(OnWindowFocusedChanged, out windowFocusChangedEventCallback);
using WindowFocusSignalType signal = new WindowFocusSignalType(Interop.Window.FocusChangedSignal(SwigCPtr), false);
signal.Ensure()?.Connect(windowFocusChangedEventCallback);
}
@@ -119,7 +120,7 @@ public event EventHandler FocusChanged
{
using WindowFocusSignalType signal = new WindowFocusSignalType(Interop.Window.FocusChangedSignal(SwigCPtr), false);
signal.Ensure()?.Disconnect(windowFocusChangedEventCallback);
- windowFocusChangedEventCallback = null;
+ ReleaseSafeCallback(ref windowFocusChangedEventCallback);
}
}
}
@@ -137,7 +138,7 @@ public event EventHandler TouchEvent
{
if (rootLayerTouchDataEventHandler == null)
{
- rootLayerTouchDataCallback = OnWindowTouch;
+ CreateSafeCallback(OnWindowTouch, out rootLayerTouchDataCallback);
Interop.ActorSignal.TouchConnect(Layer.getCPtr(GetRootLayer()), rootLayerTouchDataCallback.ToHandleRef(this));
NDalicPINVOKE.ThrowExceptionIfExists();
}
@@ -150,7 +151,7 @@ public event EventHandler TouchEvent
{
Interop.ActorSignal.TouchDisconnect(Layer.getCPtr(GetRootLayer()), rootLayerTouchDataCallback.ToHandleRef(this));
NDalicPINVOKE.ThrowExceptionIfExists();
- rootLayerTouchDataCallback = null;
+ ReleaseSafeCallback(ref rootLayerTouchDataCallback);
}
}
}
@@ -169,7 +170,7 @@ public event ReturnTypeEventHandler InterceptTouch
{
if (rootLayerInterceptTouchDataEventHandler == null)
{
- rootLayerInterceptTouchDataCallback = OnWindowInterceptTouch;
+ CreateSafeCallback(OnWindowInterceptTouch, out rootLayerInterceptTouchDataCallback);
Interop.ActorSignal.InterceptTouchConnect(Layer.getCPtr(GetRootLayer()), rootLayerInterceptTouchDataCallback.ToHandleRef(this));
NDalicPINVOKE.ThrowExceptionIfExists();
}
@@ -182,7 +183,7 @@ public event ReturnTypeEventHandler InterceptTouch
{
Interop.ActorSignal.InterceptTouchDisconnect(Layer.getCPtr(GetRootLayer()), rootLayerInterceptTouchDataCallback.ToHandleRef(this));
NDalicPINVOKE.ThrowExceptionIfExists();
- rootLayerInterceptTouchDataCallback = null;
+ ReleaseSafeCallback(ref rootLayerInterceptTouchDataCallback);
}
}
}
@@ -197,7 +198,7 @@ public event EventHandler WheelEvent
{
if (stageWheelHandler == null)
{
- wheelEventCallback = OnStageWheel;
+ CreateSafeCallback(OnStageWheel, out wheelEventCallback);
Interop.ActorSignal.WheelEventConnect(Layer.getCPtr(GetRootLayer()), wheelEventCallback.ToHandleRef(this));
NDalicPINVOKE.ThrowExceptionIfExists();
}
@@ -205,7 +206,7 @@ public event EventHandler WheelEvent
if (DetentEventHandler == null)
{
- DetentEventCallback = OnDetentEvent;
+ CreateSafeCallback(OnDetentEvent, out DetentEventCallback);
using StageWheelSignal signal = new StageWheelSignal(Interop.StageSignal.WheelEventSignal(stageCPtr), false);
signal.Ensure()?.Connect(DetentEventCallback);
}
@@ -218,7 +219,7 @@ public event EventHandler WheelEvent
{
Interop.ActorSignal.WheelEventDisconnect(Layer.getCPtr(GetRootLayer()), wheelEventCallback.ToHandleRef(this));
NDalicPINVOKE.ThrowExceptionIfExists();
- wheelEventCallback = null;
+ ReleaseSafeCallback(ref wheelEventCallback);
}
DetentEventHandler -= value;
@@ -226,7 +227,7 @@ public event EventHandler WheelEvent
{
using StageWheelSignal signal = new StageWheelSignal(Interop.StageSignal.WheelEventSignal(stageCPtr), false);
signal.Ensure()?.Disconnect(DetentEventCallback);
- DetentEventCallback = null;
+ ReleaseSafeCallback(ref DetentEventCallback);
}
}
}
@@ -244,7 +245,7 @@ public event ReturnTypeEventHandler InterceptWheel
{
if (interceptWheelHandler == null)
{
- interceptWheelCallback = OnWindowInterceptWheel;
+ CreateSafeCallback(OnWindowInterceptWheel, out interceptWheelCallback);
Interop.ActorSignal.InterceptWheelConnect(Layer.getCPtr(GetRootLayer()), interceptWheelCallback.ToHandleRef(this));
NDalicPINVOKE.ThrowExceptionIfExists();
}
@@ -257,7 +258,7 @@ public event ReturnTypeEventHandler InterceptWheel
{
Interop.ActorSignal.InterceptWheelDisconnect(Layer.getCPtr(GetRootLayer()), interceptWheelCallback.ToHandleRef(this));
NDalicPINVOKE.ThrowExceptionIfExists();
- interceptWheelCallback = null;
+ ReleaseSafeCallback(ref interceptWheelCallback);
}
}
}
@@ -272,7 +273,7 @@ public event EventHandler KeyEvent
{
if (stageKeyHandler == null)
{
- stageKeyCallbackDelegate = OnStageKey;
+ CreateSafeCallback(OnStageKey, out stageKeyCallbackDelegate);
using KeyEventSignal signal = new KeyEventSignal(Interop.Window.KeyEventSignal(SwigCPtr), false);
signal.Ensure()?.Connect(stageKeyCallbackDelegate);
}
@@ -285,7 +286,7 @@ public event EventHandler KeyEvent
{
using KeyEventSignal signal = new KeyEventSignal(Interop.Window.KeyEventSignal(SwigCPtr), false);
signal.Ensure()?.Disconnect(stageKeyCallbackDelegate);
- stageKeyCallbackDelegate = null;
+ ReleaseSafeCallback(ref stageKeyCallbackDelegate);
}
}
}
@@ -301,7 +302,7 @@ public event ReturnTypeEventHandler InterceptKeyEven
{
if (stageInterceptKeyHandler == null)
{
- stageInterceptKeyCallbackDelegate = OnStageInterceptKey;
+ CreateSafeCallback(OnStageInterceptKey, out stageInterceptKeyCallbackDelegate);
using KeyEventSignal signal = new KeyEventSignal(Interop.Window.InterceptKeyEventSignal(SwigCPtr), false);
signal.Ensure()?.Connect(stageInterceptKeyCallbackDelegate);
}
@@ -314,7 +315,7 @@ public event ReturnTypeEventHandler InterceptKeyEven
{
using KeyEventSignal signal = new KeyEventSignal(Interop.Window.InterceptKeyEventSignal(SwigCPtr), false);
signal.Ensure()?.Disconnect(stageInterceptKeyCallbackDelegate);
- stageInterceptKeyCallbackDelegate = null;
+ ReleaseSafeCallback(ref stageInterceptKeyCallbackDelegate);
}
}
}
@@ -329,7 +330,7 @@ public event EventHandler Resized
{
if (windowResizeEventHandler == null)
{
- windowResizeEventCallback = OnResized;
+ CreateSafeCallback(OnResized, out windowResizeEventCallback);
using ResizeSignal signal = new ResizeSignal(Interop.Window.ResizeSignal(SwigCPtr), false);
signal.Ensure()?.Connect(windowResizeEventCallback);
}
@@ -343,7 +344,7 @@ public event EventHandler Resized
{
using ResizeSignal signal = new ResizeSignal(Interop.Window.ResizeSignal(SwigCPtr), false);
signal.Ensure()?.Disconnect(windowResizeEventCallback);
- windowResizeEventCallback = null;
+ ReleaseSafeCallback(ref windowResizeEventCallback);
}
}
}
@@ -359,7 +360,7 @@ public event EventHandler HoverEvent
{
if (rootLayerHoverDataEventHandler == null)
{
- rootLayerHoverDataCallback = OnWindowHover;
+ CreateSafeCallback(OnWindowHover, out rootLayerHoverDataCallback);
Interop.ActorSignal.HoveredConnect(Layer.getCPtr(GetRootLayer()), rootLayerHoverDataCallback.ToHandleRef(this));
NDalicPINVOKE.ThrowExceptionIfExists();
}
@@ -372,7 +373,7 @@ public event EventHandler HoverEvent
{
Interop.ActorSignal.HoveredDisconnect(Layer.getCPtr(GetRootLayer()), rootLayerHoverDataCallback.ToHandleRef(this));
NDalicPINVOKE.ThrowExceptionIfExists();
- rootLayerHoverDataCallback = null;
+ ReleaseSafeCallback(ref rootLayerHoverDataCallback);
}
}
}
@@ -394,7 +395,7 @@ public event EventHandler WindowFocusChanged
{
if (windowFocusChangedEventHandler2 == null)
{
- windowFocusChangedEventCallback2 = OnWindowFocusedChanged2;
+ CreateSafeCallback(OnWindowFocusedChanged2, out windowFocusChangedEventCallback2);
using WindowFocusSignalType signal = new WindowFocusSignalType(Interop.Window.FocusChangedSignal(SwigCPtr), false);
signal.Ensure()?.Connect(windowFocusChangedEventCallback2);
}
@@ -407,7 +408,7 @@ public event EventHandler WindowFocusChanged
{
using WindowFocusSignalType signal = new WindowFocusSignalType(Interop.Window.FocusChangedSignal(SwigCPtr), false);
signal.Ensure()?.Disconnect(windowFocusChangedEventCallback2);
- windowFocusChangedEventCallback2 = null;
+ ReleaseSafeCallback(ref windowFocusChangedEventCallback2);
}
}
}
@@ -422,7 +423,7 @@ public event EventHandler TransitionEffect
{
if (transitionEffectHandler == null)
{
- transitionEffectEventCallback = OnTransitionEffect;
+ CreateSafeCallback(OnTransitionEffect, out transitionEffectEventCallback);
using WindowTransitionEffectSignal signal = new WindowTransitionEffectSignal(Interop.WindowTransitionEffectSignal.GetSignal(SwigCPtr), false);
signal.Ensure()?.Connect(transitionEffectEventCallback);
}
@@ -435,7 +436,7 @@ public event EventHandler TransitionEffect
{
using WindowTransitionEffectSignal signal = new WindowTransitionEffectSignal(Interop.WindowTransitionEffectSignal.GetSignal(SwigCPtr), false);
signal.Ensure()?.Disconnect(transitionEffectEventCallback);
- transitionEffectEventCallback = null;
+ ReleaseSafeCallback(ref transitionEffectEventCallback);
}
}
}
@@ -450,7 +451,7 @@ public event EventHandler Moved
{
if (movedHandler == null)
{
- movedEventCallback = OnMoved;
+ CreateSafeCallback(OnMoved, out movedEventCallback);
using WindowMovedSignal signal = new WindowMovedSignal(Interop.WindowMovedSignal.GetSignal(SwigCPtr), false);
signal.Ensure()?.Connect(movedEventCallback);
}
@@ -463,7 +464,7 @@ public event EventHandler Moved
{
using WindowMovedSignal signal = new WindowMovedSignal(Interop.WindowMovedSignal.GetSignal(SwigCPtr), false);
signal.Ensure()?.Disconnect(movedEventCallback);
- movedEventCallback = null;
+ ReleaseSafeCallback(ref movedEventCallback);
}
}
}
@@ -479,7 +480,7 @@ public event EventHandler OrientationChanged
{
if (orientationChangedHandler == null)
{
- orientationChangedEventCallback = OnOrientationChanged;
+ CreateSafeCallback(OnOrientationChanged, out orientationChangedEventCallback);
using WindowOrientationChangedSignal signal = new WindowOrientationChangedSignal(Interop.WindowOrientationChangedSignal.GetSignal(SwigCPtr), false);
signal.Ensure()?.Connect(orientationChangedEventCallback);
}
@@ -492,7 +493,7 @@ public event EventHandler OrientationChanged
{
using WindowOrientationChangedSignal signal = new WindowOrientationChangedSignal(Interop.WindowOrientationChangedSignal.GetSignal(SwigCPtr), false);
signal.Ensure()?.Disconnect(orientationChangedEventCallback);
- orientationChangedEventCallback = null;
+ ReleaseSafeCallback(ref orientationChangedEventCallback);
}
}
}
@@ -507,7 +508,7 @@ public event EventHandler KeyboardRepeatSettingsChanged
{
if (keyboardRepeatSettingsChangedHandler == null)
{
- keyboardRepeatSettingsChangedEventCallback = OnKeyboardRepeatSettingsChanged;
+ CreateSafeCallback(OnKeyboardRepeatSettingsChanged, out keyboardRepeatSettingsChangedEventCallback);
using KeyboardRepeatSettingsChangedSignal signal = new KeyboardRepeatSettingsChangedSignal(Interop.KeyboardRepeatSettingsChangedSignal.GetSignal(SwigCPtr), false);
signal.Ensure()?.Connect(keyboardRepeatSettingsChangedEventCallback);
}
@@ -520,7 +521,7 @@ public event EventHandler KeyboardRepeatSettingsChanged
{
using KeyboardRepeatSettingsChangedSignal signal = new KeyboardRepeatSettingsChangedSignal(Interop.KeyboardRepeatSettingsChangedSignal.GetSignal(SwigCPtr), false);
signal.Ensure()?.Disconnect(keyboardRepeatSettingsChangedEventCallback);
- keyboardRepeatSettingsChangedEventCallback = null;
+ ReleaseSafeCallback(ref keyboardRepeatSettingsChangedEventCallback);
}
}
}
@@ -535,7 +536,7 @@ public event EventHandler MouseInOutEvent
{
if (windowMouseInOutEventHandler == null)
{
- windowMouseInOutEventCallback = OnWindowMouseInOutEvent;
+ CreateSafeCallback(OnWindowMouseInOutEvent, out windowMouseInOutEventCallback);
using WindowMouseInOutEventSignal signal = new WindowMouseInOutEventSignal(Interop.WindowMouseInOutEventSignal.GetSignal(SwigCPtr), false);
signal.Ensure()?.Connect(windowMouseInOutEventCallback);
}
@@ -548,7 +549,7 @@ public event EventHandler MouseInOutEvent
{
using WindowMouseInOutEventSignal signal = new WindowMouseInOutEventSignal(Interop.WindowMouseInOutEventSignal.GetSignal(SwigCPtr), false);
signal.Ensure()?.Disconnect(windowMouseInOutEventCallback);
- windowMouseInOutEventCallback = null;
+ ReleaseSafeCallback(ref windowMouseInOutEventCallback);
}
}
}
@@ -565,7 +566,7 @@ public event EventHandler MoveCompleted
{
if (moveCompletedHandler == null)
{
- moveCompletedEventCallback = OnMoveCompleted;
+ CreateSafeCallback(OnMoveCompleted, out moveCompletedEventCallback);
using WindowMoveCompletedSignal signal = new WindowMoveCompletedSignal(Interop.WindowMoveCompletedSignal.GetSignal(SwigCPtr), false);
signal.Ensure()?.Connect(moveCompletedEventCallback);
}
@@ -578,7 +579,7 @@ public event EventHandler MoveCompleted
{
using WindowMoveCompletedSignal signal = new WindowMoveCompletedSignal(Interop.WindowMoveCompletedSignal.GetSignal(SwigCPtr), false);
signal.Ensure()?.Disconnect(moveCompletedEventCallback);
- moveCompletedEventCallback = null;
+ ReleaseSafeCallback(ref moveCompletedEventCallback);
}
}
}
@@ -595,7 +596,7 @@ public event EventHandler ResizeCompleted
{
if (resizeCompletedHandler == null)
{
- resizeCompletedEventCallback = OnResizeCompleted;
+ CreateSafeCallback(OnResizeCompleted, out resizeCompletedEventCallback);
using WindowResizeCompletedSignal signal = new WindowResizeCompletedSignal(Interop.WindowResizeCompletedSignal.GetSignal(SwigCPtr), false);
signal.Ensure()?.Connect(resizeCompletedEventCallback);
}
@@ -608,7 +609,7 @@ public event EventHandler ResizeCompleted
{
using WindowResizeCompletedSignal signal = new WindowResizeCompletedSignal(Interop.WindowResizeCompletedSignal.GetSignal(SwigCPtr), false);
signal.Ensure()?.Disconnect(resizeCompletedEventCallback);
- resizeCompletedEventCallback = null;
+ ReleaseSafeCallback(ref resizeCompletedEventCallback);
}
}
}
@@ -623,7 +624,7 @@ public event EventHandler MouseRelativeEvent
{
if (windowMouseRelativeEventHandler == null)
{
- windowMouseRelativeEventCallback = OnWindowMouseRelativeEvent;
+ CreateSafeCallback(OnWindowMouseRelativeEvent, out windowMouseRelativeEventCallback);
using WindowMouseRelativeEventSignal signal = new WindowMouseRelativeEventSignal(Interop.WindowMouseRelativeEventSignal.GetSignal(SwigCPtr), false);
signal?.Connect(windowMouseRelativeEventCallback);
}
@@ -636,7 +637,7 @@ public event EventHandler MouseRelativeEvent
{
using WindowMouseRelativeEventSignal signal = new WindowMouseRelativeEventSignal(Interop.WindowMouseRelativeEventSignal.GetSignal(SwigCPtr), false);
signal?.Disconnect(windowMouseRelativeEventCallback);
- windowMouseRelativeEventCallback = null;
+ ReleaseSafeCallback(ref windowMouseRelativeEventCallback);
}
}
}
@@ -651,7 +652,7 @@ public event EventHandler PointerConstraintsEvent
{
if (windowPointerConstraintsEventHandler == null)
{
- windowPointerConstraintsEventCallback = OnWindowPointerConstraintsEvent;
+ CreateSafeCallback(OnWindowPointerConstraintsEvent, out windowPointerConstraintsEventCallback);
using WindowPointerConstraintsSignal signal = new WindowPointerConstraintsSignal(Interop.WindowPointerConstraintsSignal.GetSignal(SwigCPtr), false);
signal?.Connect(windowPointerConstraintsEventCallback);
}
@@ -664,7 +665,7 @@ public event EventHandler PointerConstraintsEvent
{
using WindowPointerConstraintsSignal signal = new WindowPointerConstraintsSignal(Interop.WindowPointerConstraintsSignal.GetSignal(SwigCPtr), false);
signal?.Disconnect(windowPointerConstraintsEventCallback);
- windowPointerConstraintsEventCallback = null;
+ ReleaseSafeCallback(ref windowPointerConstraintsEventCallback);
}
}
}
@@ -735,7 +736,7 @@ internal event EventHandler EventProcessingFinished
{
if (stageEventProcessingFinishedEventHandler == null)
{
- stageEventProcessingFinishedEventCallbackDelegate = OnEventProcessingFinished;
+ CreateSafeCallback(OnEventProcessingFinished, out stageEventProcessingFinishedEventCallbackDelegate);
using VoidSignal signal = new VoidSignal(Interop.StageSignal.EventProcessingFinishedSignal(stageCPtr), false);
signal.Ensure()?.Connect(stageEventProcessingFinishedEventCallbackDelegate);
}
@@ -748,7 +749,7 @@ internal event EventHandler EventProcessingFinished
{
using VoidSignal signal = new VoidSignal(Interop.StageSignal.EventProcessingFinishedSignal(stageCPtr), false);
signal.Ensure()?.Disconnect(stageEventProcessingFinishedEventCallbackDelegate);
- stageEventProcessingFinishedEventCallbackDelegate = null;
+ ReleaseSafeCallback(ref stageEventProcessingFinishedEventCallbackDelegate);
}
}
}
@@ -759,7 +760,7 @@ internal event EventHandler ContextLost
{
if (stageContextLostEventHandler == null)
{
- stageContextLostEventCallbackDelegate = OnContextLost;
+ CreateSafeCallback(OnContextLost, out stageContextLostEventCallbackDelegate);
using VoidSignal signal = new VoidSignal(Interop.StageSignal.ContextLostSignal(stageCPtr), false);
signal.Ensure()?.Connect(stageContextLostEventCallbackDelegate);
}
@@ -772,7 +773,7 @@ internal event EventHandler ContextLost
{
using VoidSignal signal = new VoidSignal(Interop.StageSignal.ContextLostSignal(stageCPtr), false);
signal.Ensure()?.Disconnect(stageContextLostEventCallbackDelegate);
- stageContextLostEventCallbackDelegate = null;
+ ReleaseSafeCallback(ref stageContextLostEventCallbackDelegate);
}
}
}
@@ -783,7 +784,7 @@ internal event EventHandler ContextRegained
{
if (stageContextRegainedEventHandler == null)
{
- stageContextRegainedEventCallbackDelegate = OnContextRegained;
+ CreateSafeCallback(OnContextRegained, out stageContextRegainedEventCallbackDelegate);
using VoidSignal signal = new VoidSignal(Interop.StageSignal.ContextRegainedSignal(stageCPtr), false);
signal.Ensure()?.Connect(stageContextRegainedEventCallbackDelegate);
}
@@ -796,7 +797,7 @@ internal event EventHandler ContextRegained
{
using VoidSignal signal = new VoidSignal(Interop.StageSignal.ContextRegainedSignal(stageCPtr), false);
signal.Ensure()?.Disconnect(stageContextRegainedEventCallbackDelegate);
- stageContextRegainedEventCallbackDelegate = null;
+ ReleaseSafeCallback(ref stageContextRegainedEventCallbackDelegate);
}
}
}
@@ -807,7 +808,7 @@ internal event EventHandler SceneCreated
{
if (stageSceneCreatedEventHandler == null)
{
- stageSceneCreatedEventCallbackDelegate = OnSceneCreated;
+ CreateSafeCallback(OnSceneCreated, out stageSceneCreatedEventCallbackDelegate);
using VoidSignal signal = new VoidSignal(Interop.StageSignal.SceneCreatedSignal(stageCPtr), false);
signal.Ensure()?.Connect(stageSceneCreatedEventCallbackDelegate);
}
@@ -820,7 +821,7 @@ internal event EventHandler SceneCreated
{
using VoidSignal signal = new VoidSignal(Interop.StageSignal.SceneCreatedSignal(stageCPtr), false);
signal.Ensure()?.Disconnect(stageSceneCreatedEventCallbackDelegate);
- stageSceneCreatedEventCallbackDelegate = null;
+ ReleaseSafeCallback(ref stageSceneCreatedEventCallbackDelegate);
}
}
}
@@ -1036,6 +1037,11 @@ internal void DisconnectNativeSignals()
private void OnWindowFocusedChanged(IntPtr window, bool focusGained)
{
+ if (IsDisposedOrQueued)
+ {
+ return;
+ }
+
if (window == IntPtr.Zero)
{
NUILog.Error("OnWindowFocusedChanged() Window is null! Do nothing!");
@@ -1052,6 +1058,12 @@ private void OnWindowFocusedChanged(IntPtr window, bool focusGained)
private bool OnWindowTouch(IntPtr view, IntPtr touchData)
{
+ if (IsDisposedOrQueued)
+ {
+ // Ignore native callback if the window is disposed or queued for disposal.
+ return false;
+ }
+
if (touchData == global::System.IntPtr.Zero)
{
NUILog.Error("touchData should not be null!");
@@ -1069,6 +1081,12 @@ private bool OnWindowTouch(IntPtr view, IntPtr touchData)
private bool OnWindowInterceptTouch(IntPtr view, IntPtr touchData)
{
+ if (IsDisposedOrQueued)
+ {
+ // Ignore native callback if the window is disposed or queued for disposal.
+ return false;
+ }
+
if (touchData == global::System.IntPtr.Zero)
{
NUILog.Error("touchData should not be null!");
@@ -1087,6 +1105,12 @@ private bool OnWindowInterceptTouch(IntPtr view, IntPtr touchData)
private bool OnStageWheel(IntPtr rootLayer, IntPtr wheelEvent)
{
+ if (IsDisposedOrQueued)
+ {
+ // Ignore native callback if the window is disposed or queued for disposal.
+ return false;
+ }
+
if (wheelEvent == global::System.IntPtr.Zero)
{
NUILog.Error("wheelEvent should not be null!");
@@ -1104,6 +1128,12 @@ private bool OnStageWheel(IntPtr rootLayer, IntPtr wheelEvent)
private bool OnWindowInterceptWheel(IntPtr view, IntPtr wheelEvent)
{
+ if (IsDisposedOrQueued)
+ {
+ // Ignore native callback if the window is disposed or queued for disposal.
+ return false;
+ }
+
if (wheelEvent == global::System.IntPtr.Zero)
{
NUILog.Error("wheelEvent should not be null!");
@@ -1123,6 +1153,12 @@ private bool OnWindowInterceptWheel(IntPtr view, IntPtr wheelEvent)
// Callback for Stage KeyEventsignal
private void OnStageKey(IntPtr data)
{
+ if (IsDisposedOrQueued)
+ {
+ // Ignore native callback if the window is disposed or queued for disposal.
+ return;
+ }
+
if (stageKeyHandler != null)
{
KeyEventArgs e = new KeyEventArgs();
@@ -1135,6 +1171,12 @@ private void OnStageKey(IntPtr data)
// Callback for Stage InterceptKeyEventsignal
private bool OnStageInterceptKey(IntPtr data)
{
+ if (IsDisposedOrQueued)
+ {
+ // Ignore native callback if the window is disposed or queued for disposal.
+ return false;
+ }
+
bool consumed = false;
if (stageInterceptKeyHandler != null)
{
@@ -1149,29 +1191,54 @@ private bool OnStageInterceptKey(IntPtr data)
// Callback for Stage EventProcessingFinishedSignal
private void OnEventProcessingFinished()
{
+ if (IsDisposedOrQueued)
+ {
+ return;
+ }
+
stageEventProcessingFinishedEventHandler?.Invoke(this, null);
}
// Callback for Stage ContextLostSignal
private void OnContextLost()
{
+ if (IsDisposedOrQueued)
+ {
+ return;
+ }
+
stageContextLostEventHandler?.Invoke(this, null);
}
// Callback for Stage ContextRegainedSignal
private void OnContextRegained()
{
+ if (IsDisposedOrQueued)
+ {
+ return;
+ }
+
stageContextRegainedEventHandler?.Invoke(this, null);
}
// Callback for Stage SceneCreatedSignal
private void OnSceneCreated()
{
+ if (IsDisposedOrQueued)
+ {
+ return;
+ }
+
stageSceneCreatedEventHandler?.Invoke(this, null);
}
private void OnResized(IntPtr window, IntPtr windowSize)
{
+ if (IsDisposedOrQueued)
+ {
+ return;
+ }
+
if (window == IntPtr.Zero)
{
NUILog.Error("OnResized() Window is null! Do nothing!");
@@ -1195,6 +1262,11 @@ private void OnResized(IntPtr window, IntPtr windowSize)
private void OnWindowFocusedChanged2(IntPtr window, bool focusGained)
{
+ if (IsDisposedOrQueued)
+ {
+ return;
+ }
+
if (window == IntPtr.Zero)
{
NUILog.Error("OnWindowFocusedChanged() Window is null! Do nothing!");
@@ -1211,6 +1283,11 @@ private void OnWindowFocusedChanged2(IntPtr window, bool focusGained)
private void OnTransitionEffect(IntPtr window, int state, int type)
{
+ if (IsDisposedOrQueued)
+ {
+ return;
+ }
+
if (window == global::System.IntPtr.Zero)
{
return;
@@ -1228,6 +1305,11 @@ private void OnTransitionEffect(IntPtr window, int state, int type)
private void OnMoved(IntPtr window, IntPtr position)
{
+ if (IsDisposedOrQueued)
+ {
+ return;
+ }
+
if (window == global::System.IntPtr.Zero)
{
return;
@@ -1244,6 +1326,11 @@ private void OnMoved(IntPtr window, IntPtr position)
private void OnOrientationChanged(IntPtr window, int orientation)
{
+ if (IsDisposedOrQueued)
+ {
+ return;
+ }
+
if (window == global::System.IntPtr.Zero)
{
return;
@@ -1260,12 +1347,23 @@ private void OnOrientationChanged(IntPtr window, int orientation)
private void OnKeyboardRepeatSettingsChanged()
{
+ if (IsDisposedOrQueued)
+ {
+ return;
+ }
+
keyboardRepeatSettingsChangedHandler?.Invoke(this, null);
return;
}
private void OnWindowMouseInOutEvent(IntPtr view, IntPtr mouseEvent)
{
+ if (IsDisposedOrQueued)
+ {
+ // Ignore native callback if the window is disposed or queued for disposal.
+ return;
+ }
+
if (mouseEvent == global::System.IntPtr.Zero)
{
NUILog.Error("mouseEvent should not be null!");
@@ -1282,6 +1380,11 @@ private void OnWindowMouseInOutEvent(IntPtr view, IntPtr mouseEvent)
private void OnMoveCompleted(IntPtr window, IntPtr position)
{
+ if (IsDisposedOrQueued)
+ {
+ return;
+ }
+
if (window == global::System.IntPtr.Zero)
{
return;
@@ -1297,6 +1400,11 @@ private void OnMoveCompleted(IntPtr window, IntPtr position)
private void OnResizeCompleted(IntPtr window, IntPtr size)
{
+ if (IsDisposedOrQueued)
+ {
+ return;
+ }
+
if (window == global::System.IntPtr.Zero)
{
return;
@@ -1312,6 +1420,12 @@ private void OnResizeCompleted(IntPtr window, IntPtr size)
private void OnWindowMouseRelativeEvent(IntPtr view, IntPtr mouseEvent)
{
+ if (IsDisposedOrQueued)
+ {
+ // Ignore native callback if the window is disposed or queued for disposal.
+ return;
+ }
+
if (mouseEvent == global::System.IntPtr.Zero)
{
NUILog.Error("mouseEvent should not be null!");
@@ -1328,6 +1442,12 @@ private void OnWindowMouseRelativeEvent(IntPtr view, IntPtr mouseEvent)
private void OnWindowPointerConstraintsEvent(IntPtr view, IntPtr constraintsEvent)
{
+ if (IsDisposedOrQueued)
+ {
+ // Ignore native callback if the window is disposed or queued for disposal.
+ return;
+ }
+
if (constraintsEvent == global::System.IntPtr.Zero)
{
NUILog.Error("constraintsEvent should not be null!");
@@ -1344,6 +1464,12 @@ private void OnWindowPointerConstraintsEvent(IntPtr view, IntPtr constraintsEven
private bool OnWindowHover(IntPtr view, IntPtr hoverData)
{
+ if (IsDisposedOrQueued)
+ {
+ // Ignore native callback if the window is disposed or queued for disposal.
+ return false;
+ }
+
if (hoverData == global::System.IntPtr.Zero)
{
NUILog.Error("hoverData should not be null!");
@@ -1688,6 +1814,12 @@ public EffectType Type
private void OnDetentEvent(IntPtr wheelEvent)
{
+ if (IsDisposedOrQueued)
+ {
+ // Ignore native callback if the window is disposed or queued for disposal.
+ return;
+ }
+
WheelEventArgs e = new WheelEventArgs();
if (wheelEvent != global::System.IntPtr.Zero)
@@ -1721,6 +1853,11 @@ public bool Visibility
private void OnVisibilityChanged(IntPtr window, bool visibility)
{
+ if (IsDisposedOrQueued)
+ {
+ return;
+ }
+
if (window == global::System.IntPtr.Zero)
{
NUILog.Error("[ERR] OnVisibilityChanged() window is null");
@@ -1751,7 +1888,7 @@ public event EventHandler VisibilityChanged
{
if (VisibilityChangedEventHandler == null)
{
- VisibilityChangedEventCallback = OnVisibilityChanged;
+ CreateSafeCallback(OnVisibilityChanged, out VisibilityChangedEventCallback);
using WindowVisibilityChangedEvent signal = new WindowVisibilityChangedEvent(Interop.WindowVisibilityChangedSignal.GetSignal(Window.getCPtr(this)), false);
signal.Ensure()?.Connect(VisibilityChangedEventCallback);
}
@@ -1764,7 +1901,7 @@ public event EventHandler VisibilityChanged
{
using WindowVisibilityChangedEvent signal = new WindowVisibilityChangedEvent(Interop.WindowVisibilityChangedSignal.GetSignal(Window.getCPtr(this)), false);
signal.Ensure()?.Disconnect(VisibilityChangedEventCallback);
- VisibilityChangedEventCallback = null;
+ ReleaseSafeCallback(ref VisibilityChangedEventCallback);
}
}
}
@@ -1784,6 +1921,11 @@ public void VisibiltyChangedSignalEmit(bool visibility)
private void OnAuxiliaryMessage(IntPtr kData, IntPtr vData, IntPtr optionsArray)
{
+ if (IsDisposedOrQueued)
+ {
+ return;
+ }
+
if (kData == IntPtr.Zero || vData == IntPtr.Zero)
{
return;
@@ -1824,7 +1966,7 @@ public event EventHandler AuxiliaryMessage
{
if (auxiliaryMessageEventHandler == null)
{
- auxiliaryMessageEventCallback = OnAuxiliaryMessage;
+ CreateSafeCallback(OnAuxiliaryMessage, out auxiliaryMessageEventCallback);
using WindowAuxiliaryMessageSignal signal = new WindowAuxiliaryMessageSignal(Interop.WindowAuxiliaryMessageSignalType.Get(SwigCPtr), false);
signal.Ensure()?.Connect(auxiliaryMessageEventCallback);
}
@@ -1837,7 +1979,7 @@ public event EventHandler AuxiliaryMessage
{
using WindowAuxiliaryMessageSignal signal = new WindowAuxiliaryMessageSignal(Interop.WindowAuxiliaryMessageSignalType.Get(SwigCPtr), false);
signal.Ensure()?.Disconnect(auxiliaryMessageEventCallback);
- auxiliaryMessageEventCallback = null;
+ ReleaseSafeCallback(ref auxiliaryMessageEventCallback);
}
}
}
@@ -1917,6 +2059,11 @@ internal set
private void OnInsetsChanged(int partType, int partState, IntPtr extents)
{
+ if (IsDisposedOrQueued)
+ {
+ return;
+ }
+
if (insetsChangedEventHandler != null)
{
InsetsChangedEventArgs e = new InsetsChangedEventArgs();
@@ -1938,7 +2085,7 @@ public event EventHandler InsetsChanged
{
if (insetsChangedEventHandler == null)
{
- insetsChangedEventCallback = OnInsetsChanged;
+ CreateSafeCallback(OnInsetsChanged, out insetsChangedEventCallback);
using WindowInsetsChangedSignal signal = new WindowInsetsChangedSignal(Interop.WindowInsetsChangedSignalType.Get(SwigCPtr), false);
signal.Ensure()?.Connect(insetsChangedEventCallback);
}
@@ -1951,7 +2098,7 @@ public event EventHandler InsetsChanged
{
using WindowInsetsChangedSignal signal = new WindowInsetsChangedSignal(Interop.WindowInsetsChangedSignalType.Get(SwigCPtr), false);
signal.Ensure()?.Disconnect(insetsChangedEventCallback);
- insetsChangedEventCallback = null;
+ ReleaseSafeCallback(ref insetsChangedEventCallback);
}
}
}
@@ -1979,6 +2126,11 @@ public bool AccessibilityHighlight
private void OnAccessibilityHighlight(IntPtr window, bool highlight)
{
+ if (IsDisposedOrQueued)
+ {
+ return;
+ }
+
if (window == global::System.IntPtr.Zero)
{
NUILog.Error("[ERR] OnAccessibilityHighlight() window is null");
@@ -2008,7 +2160,7 @@ public event EventHandler AccessibilityHighligh
{
if (AccessibilityHighlightEventHandler == null)
{
- AccessibilityHighlightEventCallback = OnAccessibilityHighlight;
+ CreateSafeCallback(OnAccessibilityHighlight, out AccessibilityHighlightEventCallback);
using WindowAccessibilityHighlightEvent signal = new WindowAccessibilityHighlightEvent(Interop.WindowAccessibilityHighlightSignal.GetSignal(SwigCPtr), false);
signal.Ensure()?.Connect(AccessibilityHighlightEventCallback);
}
@@ -2021,10 +2173,24 @@ public event EventHandler AccessibilityHighligh
{
using WindowAccessibilityHighlightEvent signal = new WindowAccessibilityHighlightEvent(Interop.WindowAccessibilityHighlightSignal.GetSignal(SwigCPtr), false);
signal.Ensure()?.Disconnect(AccessibilityHighlightEventCallback);
- AccessibilityHighlightEventCallback = null;
+ ReleaseSafeCallback(ref AccessibilityHighlightEventCallback);
}
}
}
+
+ void CreateSafeCallback(T method, out T safeCallback) where T : Delegate
+ {
+ AddToNativeHolder(method);
+ safeCallback = method;
+ }
+
+ void ReleaseSafeCallback(ref T safeCallback) where T : Delegate
+ {
+ Debug.Assert(safeCallback != null);
+ RemoveFromNativeHolder(safeCallback);
+ safeCallback = null;
+ }
+
}
///