public class PropertyNotification : BaseHandle
{
- private DaliEventHandler<object, NotifyEventArgs> _propertyNotificationNotifyEventHandler;
- private NotifyEventCallbackDelegate _propertyNotificationNotifyEventCallbackDelegate;
+ private DaliEventHandler<object, NotifyEventArgs> propertyNotificationNotifyEventHandler;
+ private NotifyEventCallbackDelegate propertyNotificationNotifyEventCallback;
/// <summary>
/// Create a instance of PropertyNotification.
{
}
- [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void NotifyEventCallbackDelegate(IntPtr propertyNotification);
///<summary>
{
add
{
- // Restricted to only one listener
- if (_propertyNotificationNotifyEventHandler == null)
+ if (propertyNotificationNotifyEventHandler == null)
{
- _propertyNotificationNotifyEventHandler += value;
-
- _propertyNotificationNotifyEventCallbackDelegate = new NotifyEventCallbackDelegate(OnPropertyNotificationNotify);
- this.NotifySignal().Connect(_propertyNotificationNotifyEventCallbackDelegate);
+ propertyNotificationNotifyEventCallback = OnPropertyNotificationNotify;
+ using PropertyNotifySignal signal = new PropertyNotifySignal(Interop.PropertyNotification.NotifySignal(SwigCPtr), false);
+ signal?.Connect(propertyNotificationNotifyEventCallback);
}
+ propertyNotificationNotifyEventHandler += value;
}
-
remove
{
- if (_propertyNotificationNotifyEventHandler != null)
+ propertyNotificationNotifyEventHandler -= value;
+ if (propertyNotificationNotifyEventHandler == null)
{
- this.NotifySignal().Disconnect(_propertyNotificationNotifyEventCallbackDelegate);
+ using PropertyNotifySignal signal = new PropertyNotifySignal(Interop.PropertyNotification.NotifySignal(SwigCPtr), false);
+ if (signal?.Empty() == false)
+ {
+ signal?.Disconnect(propertyNotificationNotifyEventCallback);
+ if (signal?.Empty() == true)
+ {
+ propertyNotificationNotifyEventCallback = null;
+ }
+ }
}
-
- _propertyNotificationNotifyEventHandler -= value;
}
}
/// <summary>
/// Get property notification from Intptr.<br/>
- /// This should be internal, please do not use.
+ /// This should be internal, do not use.
/// </summary>
/// <param name="cPtr">An object of IntPtr type.</param>
/// <returns>An object of the PropertyNotification type.</returns>
/// <since_tizen> 4 </since_tizen>
public Animatable GetTarget()
{
- BaseHandle ret = Registry.GetManagedBaseHandleFromNativePtr(Interop.PropertyNotification.GetTarget(SwigCPtr));
+ //to fix memory leak issue, match the handle count with native side.
+ Animatable ret = this.GetInstanceSafely<Animatable>(Interop.PropertyNotification.GetTarget(SwigCPtr));
if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
- return ret as Animatable;
+ return ret;
}
/// <summary>
}
/// <summary>
- /// Connects to this signal to be notified when the notification has occurred.
+ /// override it to clean-up your own resources.
/// </summary>
- /// <returns>A signal object to Connect() with</returns>
- internal PropertyNotifySignal NotifySignal()
+ /// <param name="type"></param>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected override void Dispose(DisposeTypes type)
{
- PropertyNotifySignal ret = new PropertyNotifySignal(Interop.PropertyNotification.NotifySignal(SwigCPtr), false);
- if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
- return ret;
- }
+ if (disposed)
+ {
+ return;
+ }
- internal static global::System.Runtime.InteropServices.HandleRef getCPtr(PropertyNotification obj)
- {
- return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.SwigCPtr;
+ if (type == DisposeTypes.Explicit)
+ {
+ //Called by User
+ //Release your own managed resources here.
+ //You should release all of your own disposable objects here.
+ }
+
+ //Release your own unmanaged resources here.
+ //You should not access any managed member here except static instance.
+ //because the execution order of Finalizes is non-deterministic.
+
+ if (HasBody())
+ {
+ if (propertyNotificationNotifyEventCallback != null)
+ {
+ using PropertyNotifySignal signal = new PropertyNotifySignal(Interop.PropertyNotification.NotifySignal(SwigCPtr), false);
+ signal?.Disconnect(propertyNotificationNotifyEventCallback);
+ propertyNotificationNotifyEventCallback = null;
+ }
+ }
+ base.Dispose(type);
}
/// This will not be public opened.
// Callback for PropertyNotification NotifySignal
private void OnPropertyNotificationNotify(IntPtr propertyNotification)
{
- NotifyEventArgs e = new NotifyEventArgs();
- e.PropertyNotification = GetPropertyNotificationFromPtr(propertyNotification);
+ if (IsNativeHandleInvalid())
+ {
+ if (this.Disposed)
+ {
+ if (propertyNotificationNotifyEventHandler != null)
+ {
+ var process = global::System.Diagnostics.Process.GetCurrentProcess();
+ var processId = process?.Id ?? -1;
+ var thread = global::System.Threading.Thread.CurrentThread.ManagedThreadId;
+ var me = this.GetType().FullName;
- if (_propertyNotificationNotifyEventHandler != null)
+ Tizen.Log.Error("NUI", $"Error! NUI's native dali object is already disposed. " +
+ $"OR the native dali object handle of NUI becomes null! \n" +
+ $" process:{processId} thread:{thread}, isDisposed:{this.Disposed}, isDisposeQueued:{this.IsDisposeQueued}, me:{me}\n");
+
+ process?.Dispose();
+ }
+ }
+ else
+ {
+ if (this.IsDisposeQueued)
+ {
+ var process = global::System.Diagnostics.Process.GetCurrentProcess();
+ var processId = process?.Id ?? -1;
+ var thread = global::System.Threading.Thread.CurrentThread.ManagedThreadId;
+ var me = this.GetType().FullName;
+
+ //in this case, this 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:{processId} thread:{thread}, isDisposed:{this.Disposed}, isDisposeQueued:{this.IsDisposeQueued}, me:{me}\n");
+
+ process?.Dispose();
+ return;
+ }
+ }
+ }
+
+ if (propertyNotificationNotifyEventHandler != null)
{
+ NotifyEventArgs e = new NotifyEventArgs();
+ e.PropertyNotification = GetPropertyNotificationFromPtr(propertyNotification);
+
//here we send all data to user event handlers
- _propertyNotificationNotifyEventHandler(this, e);
+ propertyNotificationNotifyEventHandler(this, e);
}
}
/// <since_tizen> 3 </since_tizen>
public class NotifyEventArgs : EventArgs
{
- private PropertyNotification _propertyNotification;
+ private PropertyNotification propertyNotification;
///<summary>
/// PropertyNotification - is the PropertyNotification handle that has the notification properties.
{
get
{
- return _propertyNotification;
+ return propertyNotification;
}
set
{
- _propertyNotification = value;
+ propertyNotification = value;
}
}
}