- The objects that are waiting in disposeQueue are not yet signal disconnected, and their states are implict disposed.
- When dali callback comes and the obeject is in the queue, it seems that the problem will occur.
- User event callback checks IsDisposeQueued before Invoked, and if Dispose == False, IsDisposeQueued == true, then event callback is not invoked.
- when Dispose == True, User callback != NULL, throw exception.
public void Connect(System.Delegate func)
{
- System.IntPtr ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate<System.Delegate>(func);
- {
- Interop.KeyInputFocusManager.KeyInputFocusSignalConnect(SwigCPtr, new System.Runtime.InteropServices.HandleRef(this, ip));
- if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
- }
+ Interop.KeyInputFocusManager.KeyInputFocusSignalConnect(SwigCPtr, func);
+ if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
}
public void Disconnect(System.Delegate func)
{
- System.IntPtr ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate<System.Delegate>(func);
- {
- Interop.KeyInputFocusManager.KeyInputFocusSignalDisconnect(SwigCPtr, new System.Runtime.InteropServices.HandleRef(this, ip));
+ Interop.KeyInputFocusManager.KeyInputFocusSignalDisconnect(SwigCPtr, func);
if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
- }
}
public void Emit(View arg)
*
*/
+using global::System;
+using global::System.Runtime.InteropServices;
+
namespace Tizen.NUI
{
internal static partial class Interop
{
internal static partial class KeyInputFocusManager
{
- [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusManager_SWIGUpcast")]
- public static extern global::System.IntPtr Upcast(global::System.IntPtr jarg1);
+ [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusManager_SWIGUpcast")]
+ public static extern IntPtr Upcast(IntPtr jarg1);
- [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_new_KeyInputFocusManager")]
- public static extern global::System.IntPtr NewKeyInputFocusManager();
+ [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_new_KeyInputFocusManager")]
+ public static extern IntPtr NewKeyInputFocusManager();
- [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_KeyInputFocusManager")]
- public static extern void DeleteKeyInputFocusManager(global::System.Runtime.InteropServices.HandleRef jarg1);
+ [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_KeyInputFocusManager")]
+ public static extern void DeleteKeyInputFocusManager(HandleRef jarg1);
- [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusManager_Get")]
- public static extern global::System.IntPtr Get();
+ [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusManager_Get")]
+ public static extern IntPtr Get();
- [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusManager_SetFocus")]
- public static extern void SetFocus(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2);
+ [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusManager_SetFocus")]
+ public static extern void SetFocus(HandleRef jarg1, HandleRef jarg2);
- [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusManager_GetCurrentFocusControl")]
- public static extern global::System.IntPtr GetCurrentFocusControl(global::System.Runtime.InteropServices.HandleRef jarg1);
+ [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusManager_GetCurrentFocusControl")]
+ public static extern IntPtr GetCurrentFocusControl(HandleRef jarg1);
- [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusManager_RemoveFocus")]
- public static extern void RemoveFocus(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2);
+ [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusManager_RemoveFocus")]
+ public static extern void RemoveFocus(HandleRef jarg1, HandleRef jarg2);
- [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusManager_KeyInputFocusChangedSignal")]
- public static extern global::System.IntPtr KeyInputFocusChangedSignal(global::System.Runtime.InteropServices.HandleRef jarg1);
+ [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusManager_KeyInputFocusChangedSignal")]
+ public static extern IntPtr KeyInputFocusChangedSignal(HandleRef jarg1);
- [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusSignal_Empty")]
- [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.U1)]
- public static extern bool KeyInputFocusSignalEmpty(global::System.Runtime.InteropServices.HandleRef jarg1);
+ [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusSignal_Empty")]
+ [return: MarshalAs(UnmanagedType.U1)]
+ public static extern bool KeyInputFocusSignalEmpty(HandleRef jarg1);
- [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusSignal_GetConnectionCount")]
- public static extern uint KeyInputFocusSignalGetConnectionCount(global::System.Runtime.InteropServices.HandleRef jarg1);
+ [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusSignal_GetConnectionCount")]
+ public static extern uint KeyInputFocusSignalGetConnectionCount(HandleRef jarg1);
- [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusSignal_Connect")]
- public static extern void KeyInputFocusSignalConnect(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2);
+ [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusSignal_Connect", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void KeyInputFocusSignalConnect(HandleRef jarg1, Delegate jarg2);
- [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusSignal_Disconnect")]
- public static extern void KeyInputFocusSignalDisconnect(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2);
+ [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusSignal_Disconnect", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void KeyInputFocusSignalDisconnect(HandleRef jarg1, Delegate jarg2);
- [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusSignal_Emit")]
- public static extern void KeyInputFocusSignalEmit(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2);
+ [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_KeyInputFocusSignal_Emit")]
+ public static extern void KeyInputFocusSignalEmit(HandleRef jarg1, HandleRef jarg2);
- [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_new_KeyInputFocusSignal")]
- public static extern global::System.IntPtr NewKeyInputFocusSignal();
+ [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_new_KeyInputFocusSignal")]
+ public static extern IntPtr NewKeyInputFocusSignal();
- [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_KeyInputFocusSignal")]
- public static extern void DeleteKeyInputFocusSignal(global::System.Runtime.InteropServices.HandleRef jarg1);
+ [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_KeyInputFocusSignal")]
+ public static extern void DeleteKeyInputFocusSignal(HandleRef jarg1);
}
}
}
private EventHandler<VisibilityChangedEventArgs> visibilityChangedEventHandler;
private VisibilityChangedEventCallbackType visibilityChangedEventCallback;
private EventHandler keyInputFocusGainedEventHandler;
+
private KeyInputFocusGainedCallbackType keyInputFocusGainedCallback;
private EventHandler keyInputFocusLostEventHandler;
+
private KeyInputFocusLostCallbackType keyInputFocusLostCallback;
private EventHandler onRelayoutEventHandler;
private OnRelayoutEventCallbackType onRelayoutEventCallback;
private delegate void ResourcesLoadedCallbackType(IntPtr control);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate void _backgroundResourceLoadedCallbackType(IntPtr view);
- [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void KeyInputFocusGainedCallbackType(IntPtr control);
- [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void KeyInputFocusLostCallbackType(IntPtr control);
+
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate void OnRelayoutEventCallbackType(IntPtr control);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
if (keyInputFocusGainedEventHandler == null)
{
using KeyInputFocusSignal signal = new KeyInputFocusSignal(Interop.ViewSignal.KeyInputFocusGainedSignal(SwigCPtr), false);
- if (signal?.Empty() == false)
+
+ if (keyInputFocusGainedCallback != null)
{
signal?.Disconnect(keyInputFocusGainedCallback);
- keyInputFocusGainedCallback = null;
+ if (signal?.Empty() == true)
+ {
+ keyInputFocusGainedCallback = null;
+ }
}
}
}
if (keyInputFocusLostEventHandler == null)
{
using KeyInputFocusSignal signal = new KeyInputFocusSignal(Interop.ViewSignal.KeyInputFocusLostSignal(SwigCPtr), false);
- if (signal?.Empty() == false)
+
+ if (keyInputFocusLostCallback != null)
{
signal?.Disconnect(keyInputFocusLostCallback);
- keyInputFocusLostCallback = null;
+ if (signal?.Empty() == true)
+ {
+ keyInputFocusLostCallback = null;
+ }
}
}
}
private void OnKeyInputFocusGained(IntPtr view)
{
- if (keyInputFocusGainedEventHandler != null)
+ if (IsNativeHandleInvalid())
{
- keyInputFocusGainedEventHandler(this, null);
+ if (this.Disposed)
+ {
+ if (keyInputFocusGainedEventHandler != null)
+ {
+ var process = global::System.Diagnostics.Process.GetCurrentProcess().Id;
+ var thread = global::System.Threading.Thread.CurrentThread.ManagedThreadId;
+ var me = this.GetType().FullName;
+
+ throw new ObjectDisposedException(nameof(SwigCPtr), $"Error! NUI's native dali object is already disposed. " +
+ $"OR the native dali object handle of NUI becomes null! \n" +
+ $" process:{process} thread:{thread}, isDisposed:{this.Disposed}, isDisposeQueued:{this.IsDisposeQueued}, me:{me}\n");
+ }
+ }
+ else
+ {
+ if (this.IsDisposeQueued)
+ {
+ var process = global::System.Diagnostics.Process.GetCurrentProcess().Id;
+ var thread = global::System.Threading.Thread.CurrentThread.ManagedThreadId;
+ var me = this.GetType().FullName;
+
+ //in this case, the View object is ready to be disposed waiting on DisposeQueue, so event callback should not be invoked!
+ Tizen.Log.Error("NUI", "in this case, the View object is ready to be disposed waiting on DisposeQueue, so event callback should not be invoked! just return here! \n" +
+ $"process:{process} thread:{thread}, isDisposed:{this.Disposed}, isDisposeQueued:{this.IsDisposeQueued}, me:{me}\n");
+ return;
+ }
+ }
}
+
+ keyInputFocusGainedEventHandler?.Invoke(this, null);
}
private void OnKeyInputFocusLost(IntPtr view)
{
- if (keyInputFocusLostEventHandler != null)
+ if (IsNativeHandleInvalid())
{
- keyInputFocusLostEventHandler(this, null);
+ if (this.Disposed)
+ {
+ if (keyInputFocusLostEventHandler != null)
+ {
+ var process = global::System.Diagnostics.Process.GetCurrentProcess().Id;
+ var thread = global::System.Threading.Thread.CurrentThread.ManagedThreadId;
+ var me = this.GetType().FullName;
+
+ throw new ObjectDisposedException(nameof(SwigCPtr), $"Error! NUI's native dali object is already disposed. " +
+ $"OR the native dali object handle of NUI becomes null! \n" +
+ $" process:{process} thread:{thread}, isDisposed:{this.Disposed}, isDisposeQueued:{this.IsDisposeQueued}, me:{me}\n");
+ }
+ }
+ else
+ {
+ if (this.IsDisposeQueued)
+ {
+ var process = global::System.Diagnostics.Process.GetCurrentProcess().Id;
+ var thread = global::System.Threading.Thread.CurrentThread.ManagedThreadId;
+ var me = this.GetType().FullName;
+
+ //in this case, the View object is ready to be disposed waiting on DisposeQueue, so event callback should not be invoked!
+ Tizen.Log.Error("NUI", "in this case, the View object is ready to be disposed waiting on DisposeQueue, so event callback should not be invoked! just return here! \n" +
+ $"process:{process} thread:{thread}, isDisposed:{this.Disposed}, isDisposeQueued:{this.IsDisposeQueued}, me:{me}\n");
+ return;
+ }
+ }
}
+
+ keyInputFocusLostEventHandler?.Invoke(this, null);
}
private bool OnKeyEvent(IntPtr view, IntPtr keyEvent)
ThemeManager.ThemeChangedInternal.Remove(OnThemeChanged);
}
}
- if(widthConstraint != null)
+ if (widthConstraint != null)
{
widthConstraint.Remove();
widthConstraint.Dispose();
}
- if(heightConstraint != null)
+ if (heightConstraint != null)
{
heightConstraint.Remove();
heightConstraint.Dispose();
using KeyInputFocusSignal signal = new KeyInputFocusSignal(Interop.ViewSignal.KeyInputFocusLostSignal(GetBaseHandleCPtrHandleRef), false);
signal?.Disconnect(keyInputFocusLostCallback);
keyInputFocusLostCallback = null;
+ keyInputFocusLostEventHandler = null;
}
if (keyInputFocusGainedCallback != null)
using KeyInputFocusSignal signal = new KeyInputFocusSignal(Interop.ViewSignal.KeyInputFocusGainedSignal(GetBaseHandleCPtrHandleRef), false);
signal?.Disconnect(keyInputFocusGainedCallback);
keyInputFocusGainedCallback = null;
+ keyInputFocusGainedEventHandler = null;
}
if (backgroundResourceLoadedCallback != null)
//Throw exception if Dispose() is called in separate thread.
if (!Window.IsInstalled())
{
- throw new System.InvalidOperationException("This API called from separate thread. This API must be called from MainThread.");
+ var process = global::System.Diagnostics.Process.GetCurrentProcess().Id;
+ var thread = global::System.Threading.Thread.CurrentThread.ManagedThreadId;
+ var me = this.GetType().FullName;
+
+ throw new global::System.InvalidOperationException("This API called from separate thread. This API must be called from MainThread. \n" +
+ $" process:{process} thread:{thread}, disposing:{disposing}, isDisposed:{this.disposed}, isDisposeQueued:{this.isDisposeQueued}, me:{me}\n");
}
if (isDisposeQueued)
{
+ Tizen.Log.Fatal("NUI", $"should not be here! (dead code) this will be removed!");
+ throw new global::System.Exception($"[NUI] should not be here! (dead code) this will be removed!");
Dispose(DisposeTypes.Implicit);
}
else
{
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!");
+ var process = global::System.Diagnostics.Process.GetCurrentProcess().Id;
+ var thread = global::System.Threading.Thread.CurrentThread.ManagedThreadId;
+ var me = this.GetType().FullName;
+
+ throw new ObjectDisposedException(nameof(SwigCPtr), $"Error! NUI's native dali object is already disposed. " +
+ $"OR the native dali object handle of NUI becomes null! \n" +
+ $" process:{process} thread:{thread}, isDisposed:{this.disposed}, isDisposeQueued:{this.isDisposeQueued}, me:{me}\n");
}
return swigCPtr;
}
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
protected internal bool Disposed => disposed;
+
+ /// <summary>
+ /// A flag to check if it is disposed by DisposeQueue.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected internal bool IsDisposeQueued => isDisposeQueued;
+
}
}