- Add Exception when Animation's method or property is used after itself has been disposed already. (requested by GBM)
- All NUI object will throw an ObjectDisposedException when it is tried to be used after disposed.
- BaseHandle's internal SwigCPtr has setter and getter, but setter seems to be dangerous so it is changed to be getter only. (requested by GBM)
- SwigCPtr becomes only getter, so DisconnectFromSignals() has been changed accordingly.
private void DisConnectFromSignals()
{
- // Save current CPtr.
- global::System.Runtime.InteropServices.HandleRef currentCPtr = SwigCPtr;
-
- // Use BaseHandle CPtr as current might have been deleted already in derived classes.
- SwigCPtr = GetBaseHandleCPtrHandleRef;
-
if (scrollableCompletedCallbackDelegate != null)
{
- this.ScrollCompletedSignal().Disconnect(scrollableCompletedCallbackDelegate);
+ using ScrollableSignal signal = new ScrollableSignal(Interop.Scrollable.ScrollCompletedSignal(GetBaseHandleCPtrHandleRef), false);
+ signal?.Disconnect(scrollableCompletedCallbackDelegate);
+ scrollableCompletedCallbackDelegate = null;
}
if (scrollableUpdatedCallbackDelegate != null)
{
- this.ScrollUpdatedSignal().Disconnect(scrollableUpdatedCallbackDelegate);
+ using ScrollableSignal signal = new ScrollableSignal(Interop.Scrollable.ScrollUpdatedSignal(GetBaseHandleCPtrHandleRef), false);
+ signal?.Disconnect(scrollableUpdatedCallbackDelegate);
+ scrollableUpdatedCallbackDelegate = null;
}
if (scrollableStartedCallbackDelegate != null)
{
- this.ScrollStartedSignal().Disconnect(scrollableStartedCallbackDelegate);
+ using ScrollableSignal signal = new ScrollableSignal(Interop.Scrollable.ScrollStartedSignal(GetBaseHandleCPtrHandleRef), false);
+ signal?.Disconnect(scrollableStartedCallbackDelegate);
+ scrollableStartedCallbackDelegate = null;
}
-
- // BaseHandle CPtr is used in Registry and there is danger of deletion if we keep using it here.
- // Restore current CPtr.
- SwigCPtr = currentCPtr;
}
private void OnStarted(IntPtr vector2)
}
onWindowSendEventCallback = SendViewAddedEventToWindow;
- this.OnWindowSignal().Connect(onWindowSendEventCallback);
+ using ViewSignal signal = new ViewSignal(Interop.ActorSignal.ActorOnSceneSignal(SwigCPtr), false);
+ signal?.Connect(onWindowSendEventCallback);
if (!shown)
{
if (keyInputFocusGainedEventHandler == null)
{
keyInputFocusGainedCallback = OnKeyInputFocusGained;
- this.KeyInputFocusGainedSignal().Connect(keyInputFocusGainedCallback);
+ using KeyInputFocusSignal signal = new KeyInputFocusSignal(Interop.ViewSignal.KeyInputFocusGainedSignal(SwigCPtr), false);
+ signal?.Connect(keyInputFocusGainedCallback);
}
-
keyInputFocusGainedEventHandler += value;
}
remove
{
keyInputFocusGainedEventHandler -= value;
-
- if (keyInputFocusGainedEventHandler == null && KeyInputFocusGainedSignal().Empty() == false)
+ if (keyInputFocusGainedEventHandler == null)
{
- this.KeyInputFocusGainedSignal().Disconnect(keyInputFocusGainedCallback);
+ using KeyInputFocusSignal signal = new KeyInputFocusSignal(Interop.ViewSignal.KeyInputFocusGainedSignal(SwigCPtr), false);
+ if (signal?.Empty() == false)
+ {
+ signal?.Disconnect(keyInputFocusGainedCallback);
+ keyInputFocusGainedCallback = null;
+ }
}
}
}
if (keyInputFocusLostEventHandler == null)
{
keyInputFocusLostCallback = OnKeyInputFocusLost;
- this.KeyInputFocusLostSignal().Connect(keyInputFocusLostCallback);
+ using KeyInputFocusSignal signal = new KeyInputFocusSignal(Interop.ViewSignal.KeyInputFocusLostSignal(SwigCPtr), false);
+ signal?.Connect(keyInputFocusLostCallback);
}
-
keyInputFocusLostEventHandler += value;
}
remove
{
keyInputFocusLostEventHandler -= value;
-
- if (keyInputFocusLostEventHandler == null && KeyInputFocusLostSignal().Empty() == false)
+ if (keyInputFocusLostEventHandler == null)
{
- this.KeyInputFocusLostSignal().Disconnect(keyInputFocusLostCallback);
+ using KeyInputFocusSignal signal = new KeyInputFocusSignal(Interop.ViewSignal.KeyInputFocusLostSignal(SwigCPtr), false);
+ if (signal?.Empty() == false)
+ {
+ signal?.Disconnect(keyInputFocusLostCallback);
+ keyInputFocusLostCallback = null;
+ }
}
}
}
if (keyEventHandler == null)
{
keyCallback = OnKeyEvent;
- this.KeyEventSignal().Connect(keyCallback);
+ using ControlKeySignal signal = new ControlKeySignal(Interop.ViewSignal.KeyEventSignal(SwigCPtr), false);
+ signal?.Connect(keyCallback);
}
-
keyEventHandler += value;
}
remove
{
keyEventHandler -= value;
-
- if (keyEventHandler == null && KeyEventSignal().Empty() == false)
+ if (keyEventHandler == null)
{
- this.KeyEventSignal().Disconnect(keyCallback);
+ using ControlKeySignal signal = new ControlKeySignal(Interop.ViewSignal.KeyEventSignal(SwigCPtr), false);
+ if (signal?.Empty() == false)
+ {
+ signal?.Disconnect(keyCallback);
+ keyCallback = null;
+ }
}
}
}
if (onRelayoutEventHandler == null)
{
onRelayoutEventCallback = OnRelayout;
- this.OnRelayoutSignal().Connect(onRelayoutEventCallback);
+ using ViewSignal signal = new ViewSignal(Interop.ActorSignal.ActorOnRelayoutSignal(SwigCPtr), false);
+ signal?.Connect(onRelayoutEventCallback);
}
-
onRelayoutEventHandler += value;
}
remove
{
onRelayoutEventHandler -= value;
-
- if (onRelayoutEventHandler == null && OnRelayoutSignal().Empty() == false)
+ if (onRelayoutEventHandler == null)
{
- this.OnRelayoutSignal().Disconnect(onRelayoutEventCallback);
- onRelayoutEventCallback = null;
+ using ViewSignal signal = new ViewSignal(Interop.ActorSignal.ActorOnRelayoutSignal(SwigCPtr), false);
+ if (signal?.Empty() == false)
+ {
+ signal?.Disconnect(onRelayoutEventCallback);
+ onRelayoutEventCallback = null;
+ }
}
-
}
}
if (interceptTouchDataEventHandler == null)
{
interceptTouchDataCallback = OnInterceptTouch;
- this.InterceptTouchSignal().Connect(interceptTouchDataCallback);
+ using TouchDataSignal signal = new TouchDataSignal(Interop.ActorSignal.ActorInterceptTouchSignal(SwigCPtr), false);
+ signal?.Connect(interceptTouchDataCallback);
}
-
interceptTouchDataEventHandler += value;
}
remove
{
interceptTouchDataEventHandler -= value;
-
- if (interceptTouchDataEventHandler == null && InterceptTouchSignal().Empty() == false)
+ if (interceptTouchDataEventHandler == null)
{
- this.InterceptTouchSignal().Disconnect(interceptTouchDataCallback);
+ using TouchDataSignal signal = new TouchDataSignal(Interop.ActorSignal.ActorInterceptTouchSignal(SwigCPtr), false);
+ if (signal?.Empty() == false)
+ {
+ signal?.Disconnect(interceptTouchDataCallback);
+ interceptTouchDataCallback = null;
+ }
}
}
}
if (touchDataEventHandler == null)
{
touchDataCallback = OnTouch;
- this.TouchSignal().Connect(touchDataCallback);
+ using TouchDataSignal signal = new TouchDataSignal(Interop.ActorSignal.ActorTouchSignal(SwigCPtr), false);
+ signal.Connect(touchDataCallback);
}
-
touchDataEventHandler += value;
}
remove
{
touchDataEventHandler -= value;
-
- if (touchDataEventHandler == null && TouchSignal().Empty() == false)
+ if (touchDataEventHandler == null)
{
- this.TouchSignal().Disconnect(touchDataCallback);
+ using TouchDataSignal signal = new TouchDataSignal(Interop.ActorSignal.ActorTouchSignal(SwigCPtr), false);
+ if (signal.Empty() == false)
+ {
+ signal.Disconnect(touchDataCallback);
+ touchDataCallback = null;
+ }
}
}
}
if (hoverEventHandler == null)
{
hoverEventCallback = OnHoverEvent;
- this.HoveredSignal().Connect(hoverEventCallback);
+ using HoverSignal signal = new HoverSignal(Interop.ActorSignal.ActorHoveredSignal(SwigCPtr), false);
+ signal?.Connect(hoverEventCallback);
}
-
hoverEventHandler += value;
}
remove
{
hoverEventHandler -= value;
-
- if (hoverEventHandler == null && HoveredSignal().Empty() == false)
+ if (hoverEventHandler == null)
{
- this.HoveredSignal().Disconnect(hoverEventCallback);
+ using HoverSignal signal = new HoverSignal(Interop.ActorSignal.ActorHoveredSignal(SwigCPtr), false);
+ if (signal?.Empty() == false)
+ {
+ signal?.Disconnect(hoverEventCallback);
+ hoverEventCallback = null;
+ }
}
-
}
}
if (wheelEventHandler == null)
{
wheelEventCallback = OnWheelEvent;
- this.WheelEventSignal().Connect(wheelEventCallback);
+ using WheelSignal signal = new WheelSignal(Interop.ActorSignal.ActorWheelEventSignal(SwigCPtr), false);
+ signal?.Connect(wheelEventCallback);
}
wheelEventHandler += value;
remove
{
wheelEventHandler -= value;
- if (wheelEventHandler == null && WheelEventSignal().Empty() == false)
+ if (wheelEventHandler == null)
{
- this.WheelEventSignal().Disconnect(wheelEventCallback);
+ using WheelSignal signal = new WheelSignal(Interop.ActorSignal.ActorWheelEventSignal(SwigCPtr), false);
+ if (signal?.Empty() == false)
+ {
+ signal?.Disconnect(wheelEventCallback);
+ wheelEventCallback = null;
+ }
}
WindowWheelEventHandler -= value;
if (onWindowEventHandler == null)
{
onWindowEventCallback = OnWindow;
- this.OnWindowSignal().Connect(onWindowEventCallback);
+ using ViewSignal signal = new ViewSignal(Interop.ActorSignal.ActorOnSceneSignal(SwigCPtr), false);
+ signal?.Connect(onWindowEventCallback);
}
-
onWindowEventHandler += value;
}
remove
{
onWindowEventHandler -= value;
-
- if (onWindowEventHandler == null && OnWindowSignal().Empty() == false)
+ if (onWindowEventHandler == null)
{
- this.OnWindowSignal().Disconnect(onWindowEventCallback);
- onWindowEventCallback = null;
+ using ViewSignal signal = new ViewSignal(Interop.ActorSignal.ActorOnSceneSignal(SwigCPtr), false);
+ if (signal?.Empty() == false)
+ {
+ signal?.Disconnect(onWindowEventCallback);
+ onWindowEventCallback = null;
+ }
}
}
}
if (offWindowEventHandler == null)
{
offWindowEventCallback = OffWindow;
- this.OffWindowSignal().Connect(offWindowEventCallback);
+ using ViewSignal signal = new ViewSignal(Interop.ActorSignal.ActorOffSceneSignal(SwigCPtr), false);
+ signal?.Connect(offWindowEventCallback);
}
-
offWindowEventHandler += value;
}
remove
{
offWindowEventHandler -= value;
-
- if (offWindowEventHandler == null && OffWindowSignal().Empty() == false)
+ if (offWindowEventHandler == null)
{
- this.OffWindowSignal().Disconnect(offWindowEventCallback);
- offWindowEventCallback = null;
+ using ViewSignal signal = new ViewSignal(Interop.ActorSignal.ActorOffSceneSignal(SwigCPtr), false);
+ if (signal?.Empty() == false)
+ {
+ signal?.Disconnect(offWindowEventCallback);
+ offWindowEventCallback = null;
+ }
}
}
}
if (resourcesLoadedEventHandler == null)
{
ResourcesLoadedCallback = OnResourcesLoaded;
- this.ResourcesLoadedSignal().Connect(ResourcesLoadedCallback);
+ using ViewSignal signal = new ViewSignal(Interop.View.ResourceReadySignal(SwigCPtr), false);
+ signal?.Connect(ResourcesLoadedCallback);
}
-
resourcesLoadedEventHandler += value;
}
remove
{
resourcesLoadedEventHandler -= value;
-
- if (resourcesLoadedEventHandler == null && ResourcesLoadedSignal().Empty() == false)
+ if (resourcesLoadedEventHandler == null)
{
- this.ResourcesLoadedSignal().Disconnect(ResourcesLoadedCallback);
- ResourcesLoadedCallback = null;
+ using ViewSignal signal = new ViewSignal(Interop.View.ResourceReadySignal(SwigCPtr), false);
+ if (signal?.Empty() == false)
+ {
+ signal?.Disconnect(ResourcesLoadedCallback);
+ ResourcesLoadedCallback = null;
+ }
}
}
}
if (backgroundResourceLoadedEventHandler == null)
{
backgroundResourceLoadedCallback = OnBackgroundResourceLoaded;
- this.ResourcesLoadedSignal().Connect(backgroundResourceLoadedCallback);
+ using ViewSignal signal = new ViewSignal(Interop.View.ResourceReadySignal(SwigCPtr), false);
+ signal?.Connect(backgroundResourceLoadedCallback);
}
-
backgroundResourceLoadedEventHandler += value;
}
+
remove
{
backgroundResourceLoadedEventHandler -= value;
-
- if (backgroundResourceLoadedEventHandler == null && ResourcesLoadedSignal().Empty() == false)
+ if (backgroundResourceLoadedEventHandler == null)
{
- this.ResourcesLoadedSignal().Disconnect(backgroundResourceLoadedCallback);
- backgroundResourceLoadedCallback = null;
+ using ViewSignal signal = new ViewSignal(Interop.View.ResourceReadySignal(SwigCPtr), false);
+ if (signal?.Empty() == false)
+ {
+ signal?.Disconnect(backgroundResourceLoadedCallback);
+ backgroundResourceLoadedCallback = null;
+ }
}
}
}
//You should not access any managed member here except static instance.
//because the execution order of Finalizes is non-deterministic.
- // equivalent to "if (this != null)". more clear to understand.
- if (this.HasBody())
- {
- DisConnectFromSignals();
-
- foreach (View view in Children)
- {
- view.InternalParent = null;
- }
+ DisConnectFromSignals();
+ foreach (View view in Children)
+ {
+ view.InternalParent = null;
}
base.Dispose(type);
private void DisConnectFromSignals()
{
- // Save current CPtr.
- global::System.Runtime.InteropServices.HandleRef currentCPtr = SwigCPtr;
-
- // Use BaseHandle CPtr as current might have been deleted already in derived classes.
- SwigCPtr = GetBaseHandleCPtrHandleRef;
-
if (onRelayoutEventCallback != null)
{
- ViewSignal signal = this.OnRelayoutSignal();
+ using ViewSignal signal = new ViewSignal(Interop.ActorSignal.ActorOnRelayoutSignal(GetBaseHandleCPtrHandleRef), false);
signal?.Disconnect(onRelayoutEventCallback);
- signal?.Dispose();
onRelayoutEventCallback = null;
}
if (offWindowEventCallback != null)
{
- ViewSignal signal = this.OffWindowSignal();
+ using ViewSignal signal = new ViewSignal(Interop.ActorSignal.ActorOffSceneSignal(GetBaseHandleCPtrHandleRef), false);
signal?.Disconnect(offWindowEventCallback);
- signal?.Dispose();
offWindowEventCallback = null;
}
if (onWindowEventCallback != null)
{
- ViewSignal signal = this.OnWindowSignal();
+ using ViewSignal signal = new ViewSignal(Interop.ActorSignal.ActorOnSceneSignal(GetBaseHandleCPtrHandleRef), false);
signal?.Disconnect(onWindowEventCallback);
- signal?.Dispose();
onWindowEventCallback = null;
}
if (wheelEventCallback != null)
{
- WheelSignal signal = this.WheelEventSignal();
+ using WheelSignal signal = new WheelSignal(Interop.ActorSignal.ActorWheelEventSignal(GetBaseHandleCPtrHandleRef), false);
signal?.Disconnect(wheelEventCallback);
- signal?.Dispose();
+ wheelEventCallback = null;
}
if (WindowWheelEventHandler != null)
{
NUIApplication.GetDefaultWindow().WheelEvent -= OnWindowWheelEvent;
+ WindowWheelEventHandler = null;
}
if (hoverEventCallback != null)
{
- HoverSignal signal = this.HoveredSignal();
+ using HoverSignal signal = new HoverSignal(Interop.ActorSignal.ActorHoveredSignal(GetBaseHandleCPtrHandleRef), false);
signal?.Disconnect(hoverEventCallback);
- signal?.Dispose();
+ hoverEventCallback = null;
}
if (interceptTouchDataCallback != null)
{
- TouchDataSignal signal = this.InterceptTouchSignal();
+ using TouchDataSignal signal = new TouchDataSignal(Interop.ActorSignal.ActorInterceptTouchSignal(GetBaseHandleCPtrHandleRef), false);
signal?.Disconnect(interceptTouchDataCallback);
- signal?.Dispose();
+ interceptTouchDataCallback = null;
}
if (touchDataCallback != null)
{
- TouchDataSignal signal = this.TouchSignal();
+ using TouchDataSignal signal = new TouchDataSignal(Interop.ActorSignal.ActorTouchSignal(GetBaseHandleCPtrHandleRef), false);
signal?.Disconnect(touchDataCallback);
- signal?.Dispose();
+ touchDataCallback = null;
}
if (ResourcesLoadedCallback != null)
{
- ViewSignal signal = this.ResourcesLoadedSignal();
+ using ViewSignal signal = new ViewSignal(Interop.View.ResourceReadySignal(GetBaseHandleCPtrHandleRef), false);
signal?.Disconnect(ResourcesLoadedCallback);
- signal?.Dispose();
ResourcesLoadedCallback = null;
}
if (keyCallback != null)
{
- ControlKeySignal signal = this.KeyEventSignal();
+ using ControlKeySignal signal = new ControlKeySignal(Interop.ViewSignal.KeyEventSignal(GetBaseHandleCPtrHandleRef), false);
signal?.Disconnect(keyCallback);
- signal?.Dispose();
+ keyCallback = null;
}
if (keyInputFocusLostCallback != null)
{
- KeyInputFocusSignal signal = this.KeyInputFocusLostSignal();
+ using KeyInputFocusSignal signal = new KeyInputFocusSignal(Interop.ViewSignal.KeyInputFocusLostSignal(GetBaseHandleCPtrHandleRef), false);
signal?.Disconnect(keyInputFocusLostCallback);
- signal?.Dispose();
+ keyInputFocusLostCallback = null;
}
if (keyInputFocusGainedCallback != null)
{
- KeyInputFocusSignal signal = this.KeyInputFocusGainedSignal();
+ using KeyInputFocusSignal signal = new KeyInputFocusSignal(Interop.ViewSignal.KeyInputFocusGainedSignal(GetBaseHandleCPtrHandleRef), false);
signal?.Disconnect(keyInputFocusGainedCallback);
- signal?.Dispose();
+ keyInputFocusGainedCallback = null;
}
if (backgroundResourceLoadedCallback != null)
{
- ViewSignal signal = this.ResourcesLoadedSignal();
+ using ViewSignal signal = new ViewSignal(Interop.View.ResourceReadySignal(GetBaseHandleCPtrHandleRef), false);
signal?.Disconnect(backgroundResourceLoadedCallback);
- signal?.Dispose();
backgroundResourceLoadedCallback = null;
}
if (onWindowSendEventCallback != null)
{
- ViewSignal signal = this.OnWindowSignal();
+ using ViewSignal signal = new ViewSignal(Interop.ActorSignal.ActorOnSceneSignal(GetBaseHandleCPtrHandleRef), false);
signal?.Disconnect(onWindowSendEventCallback);
- signal?.Dispose();
onWindowSendEventCallback = null;
}
-
- // BaseHandle CPtr is used in Registry and there is danger of deletion if we keep using it here.
- // Restore current CPtr.
- SwigCPtr = currentCPtr;
}
/// <summary>
internal global::System.Runtime.InteropServices.HandleRef SwigCPtr
{
- get => swigCPtr;
- set
+ get
{
- swigCPtr = value;
+ if (swigCPtr.Handle == IntPtr.Zero)
+ {
+ throw new ObjectDisposedException(nameof(SwigCPtr), "Error! NUI's native dali object is already disposed. OR the native dali object handle of NUI becomes null!");
+ }
+ return swigCPtr;
}
}
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.Applications.ThemeManager", "..\..\src\Tizen.Applications.ThemeManager\Tizen.Applications.ThemeManager.csproj", "{FB8B42D6-76CC-4836-8A80-58A816C6A17F}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.NUI.Extension", "..\..\src\Tizen.NUI.Extension\Tizen.NUI.Extension.csproj", "{47829CA1-0E21-4687-9ABB-0C27E1A67E85}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
{FB8B42D6-76CC-4836-8A80-58A816C6A17F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FB8B42D6-76CC-4836-8A80-58A816C6A17F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FB8B42D6-76CC-4836-8A80-58A816C6A17F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {47829CA1-0E21-4687-9ABB-0C27E1A67E85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {47829CA1-0E21-4687-9ABB-0C27E1A67E85}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {47829CA1-0E21-4687-9ABB-0C27E1A67E85}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {47829CA1-0E21-4687-9ABB-0C27E1A67E85}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
--- /dev/null
+
+using global::System;
+using Tizen.NUI.BaseComponents;
+using System.Collections.Generic;
+
+namespace Tizen.NUI.Samples
+{
+ using tlog = Tizen.Log;
+ public class DisposeWithoutEventUnsubscribedTestAndAnimationDisposeTest : IExample
+ {
+ private const string tag = "NUITEST";
+ private const int NUMBER_OF_VIEW = 1000;
+ private const int INTERVAL_MS = 1000;
+ private const int MIN_POSITION = 100;
+ private const int MAX_POSITION = 900;
+ private const bool TURN_ON_GC = true;
+
+ private Window win;
+ private View rootView;
+ private int cnt;
+ private List<View> list = new List<View>();
+ private Random rand = new Random();
+ private bool toggle, toggleRemoveMany;
+ private string res;
+ private Timer timer;
+
+ public void Activate()
+ {
+ DisposeWithoutUnsubscribedEventTest();
+ AnimationDisposeTest();
+ }
+ public void Deactivate()
+ {
+ DisposeManyObject();
+ timer.Stop();
+ timer.Dispose();
+ rootView.Unparent();
+ rootView.Dispose();
+ }
+
+ private void AnimationDisposeTest()
+ {
+ var ani = new Animation(1000);
+ ani.AnimateTo(rootView, "size", new Size(500, 500, 0));
+ ani.Dispose();
+ try
+ {
+ ani.Play();
+ tlog.Fatal(tag, "this should not be shown! test NG!");
+ }
+ catch (Exception e)
+ {
+ if (e is ObjectDisposedException)
+ {
+ tlog.Fatal(tag, "Animation is used after disposed! test OK!");
+ }
+ else
+ {
+ tlog.Fatal(tag, $"unwanted exception came! test NG! exception:{e} msg:{e.Message}");
+ }
+ }
+
+ try
+ {
+ ani.Clear();
+ tlog.Fatal(tag, "this should not be shown! test NG!");
+ }
+ catch (Exception e)
+ {
+ if (e is ObjectDisposedException)
+ {
+ tlog.Fatal(tag, "Animation is used after disposed! test OK!");
+ }
+ else
+ {
+ tlog.Fatal(tag, $"unwanted exception came! test NG! exception:{e} msg:{e.Message}");
+ }
+ }
+ }
+
+ private void DisposeWithoutUnsubscribedEventTest()
+ {
+ win = NUIApplication.GetDefaultWindow();
+
+ res = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
+
+ rootView = new View()
+ {
+ Size = new Size(100, 100),
+ BackgroundColor = Color.Blue,
+ };
+ rootView.Relayout += View_Relayout;
+ win.Add(rootView);
+
+ timer = new Timer(INTERVAL_MS);
+ timer.Tick += Timer_Tick;
+ timer.Start();
+ }
+
+ private void AddManyObject()
+ {
+ tlog.Fatal(tag, $"AddManyObject()");
+
+ for (int i = 0; i < NUMBER_OF_VIEW; i++)
+ {
+ var child = new ImageView()
+ {
+ ResourceUrl = res + "images/Dali/DaliDemo/application-icon-1.png",
+ Size = new Size(60, 60),
+ Position = new Position(rand.Next(MIN_POSITION, MAX_POSITION), rand.Next(MIN_POSITION, MAX_POSITION)),
+ BackgroundColor = new Color((float)rand.NextDouble(), (float)rand.NextDouble(), (float)rand.NextDouble(), 1),
+ };
+
+ rootView.Add(child);
+ child.Relayout += Child_Relayout;
+ child.RemovedFromWindow += Child_RemovedFromWindow;
+ child.AddedToWindow += Child_AddedToWindow;
+ child.WheelEvent += Child_WheelEvent;
+ child.HoverEvent += Child_HoverEvent;
+ child.InterceptTouchEvent += Child_InterceptTouchEvent;
+ child.TouchEvent += Child_TouchEvent;
+ child.ResourcesLoaded += Child_ResourcesLoaded;
+ child.KeyEvent += Child_KeyEvent;
+ child.FocusLost += Child_FocusLost;
+ child.FocusGained += Child_FocusGained;
+ }
+ }
+
+ private void Child_FocusGained(object sender, EventArgs e)
+ {
+ if (++cnt % (NUMBER_OF_VIEW * 3) == 1)
+ {
+ tlog.Fatal(tag, $"Child_FocusGained() called!");
+ }
+ }
+
+ private void Child_FocusLost(object sender, EventArgs e)
+ {
+ if (++cnt % (NUMBER_OF_VIEW * 3) == 1)
+ {
+ tlog.Fatal(tag, $"Child_FocusLost() called!");
+ }
+ }
+
+ private bool Child_KeyEvent(object source, View.KeyEventArgs e)
+ {
+ if (++cnt % (NUMBER_OF_VIEW * 3) == 1)
+ {
+ tlog.Fatal(tag, $"Child_KeyEvent() called!");
+ }
+ return true;
+ }
+
+ private void Child_ResourcesLoaded(object sender, EventArgs e)
+ {
+ if (++cnt % (NUMBER_OF_VIEW * 3) == 1)
+ {
+ tlog.Fatal(tag, $"Child_ResourcesLoaded() called!");
+ }
+ }
+
+ private bool Child_TouchEvent(object source, View.TouchEventArgs e)
+ {
+ if (++cnt % (NUMBER_OF_VIEW * 3) == 1)
+ {
+ tlog.Fatal(tag, $"Child_TouchEvent() called!");
+ }
+ return true;
+ }
+
+ private bool Child_InterceptTouchEvent(object source, View.TouchEventArgs e)
+ {
+ if (++cnt % (NUMBER_OF_VIEW * 3) == 1)
+ {
+ tlog.Fatal(tag, $"Child_InterceptTouchEvent() called!");
+ }
+ return true;
+ }
+
+ private bool Child_HoverEvent(object source, View.HoverEventArgs e)
+ {
+ if (++cnt % (NUMBER_OF_VIEW * 3) == 1)
+ {
+ tlog.Fatal(tag, $"Child_HoverEvent() called!");
+ }
+ return true;
+ }
+
+ private bool Child_WheelEvent(object source, View.WheelEventArgs e)
+ {
+ if (++cnt % (NUMBER_OF_VIEW * 3) == 1)
+ {
+ tlog.Fatal(tag, $"Child_WheelEvent() called!");
+ }
+ return true;
+ }
+
+ private void Child_AddedToWindow(object sender, EventArgs e)
+ {
+ if (++cnt % (NUMBER_OF_VIEW * 3) == 1)
+ {
+ tlog.Fatal(tag, $"Child_AddedToWindow() called!");
+ }
+ }
+
+ private void Child_RemovedFromWindow(object sender, EventArgs e)
+ {
+ if (++cnt % (NUMBER_OF_VIEW * 3) == 1)
+ {
+ tlog.Fatal(tag, $"Child_RemovedFromWindow() called!");
+ }
+ }
+
+ private void Child_Relayout(object sender, EventArgs e)
+ {
+ if (++cnt % (NUMBER_OF_VIEW * 3) == 1)
+ {
+ tlog.Fatal(tag, $"Child_Relayout() called!");
+ }
+ }
+
+ private void View_Relayout(object sender, EventArgs e)
+ {
+ if (++cnt % (NUMBER_OF_VIEW * 3) == 1)
+ {
+ tlog.Fatal(tag, $"View_Relayout() called! cnt:{cnt}");
+ }
+ }
+
+ private void RemoveManyObject()
+ {
+ int childCnt = (int)rootView.ChildCount;
+ tlog.Fatal(tag, $"RemoveManyObject() child count:{childCnt}");
+
+ for (int i = childCnt - 1; i >= 0; i--)
+ {
+ var child = rootView.GetChildAt((uint)i);
+ rootView.Remove(child);
+ }
+ }
+ private void DisposeManyObject()
+ {
+ int childCnt = (int)rootView.ChildCount;
+ tlog.Fatal(tag, $"DisposeManyObject() child count:{childCnt}");
+
+ for (int i = childCnt - 1; i >= 0; i--)
+ {
+ var child = rootView.GetChildAt((uint)i);
+ rootView.Remove(child);
+ child.Size += new Size(100, 100);
+ child.Size -= new Size(100, 100);
+ child.Size += new Size(100, 100);
+ child.Size -= new Size(100, 100);
+ child.Dispose();
+ }
+ }
+
+ private bool Timer_Tick(object source, Timer.TickEventArgs e)
+ {
+ toggle = !toggle;
+ if (toggle)
+ {
+ AddManyObject();
+ }
+ else
+ {
+ toggleRemoveMany = !toggleRemoveMany;
+ if (toggleRemoveMany)
+ {
+ RemoveManyObject();
+ }
+ else
+ {
+ DisposeManyObject();
+ }
+ }
+
+ if (TURN_ON_GC)
+ {
+ FullGC();
+ }
+ return true;
+ }
+
+ private void FullGC()
+ {
+ global::System.GC.Collect();
+ global::System.GC.WaitForPendingFinalizers();
+ global::System.GC.Collect();
+ }
+
+ }
+}