[NUI] Dispose queue incrementally
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / internal / Common / ProcessorController.cs
index 85e34af..0132e90 100755 (executable)
  *
  */
 
-using Tizen.NUI.BaseComponents;
 using System.Runtime.InteropServices;
-using System.Collections.Generic;
-using System.Diagnostics;
 using System;
 using System.ComponentModel;
 
@@ -36,16 +33,8 @@ namespace Tizen.NUI
     /// </summary>
     internal sealed class ProcessorController : Disposable
     {
-        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
-        internal delegate void ProcessorCallback();
-
-        private ProcessorCallback callback = null;
-
-        public event EventHandler ProcessorOnceEvent;
-
-        public event EventHandler ProcessorEvent;
-
-        public event EventHandler LayoutProcessorEvent;
+        private static ProcessorController instance = null;
+        private bool initialied = false;
 
         private ProcessorController() : this(Interop.ProcessorController.New(), true)
         {
@@ -53,17 +42,38 @@ namespace Tizen.NUI
 
         internal ProcessorController(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
-            callback = new ProcessorCallback(Process);
-            Interop.ProcessorController.SetCallback(SwigCPtr, callback);
         }
 
-        private static ProcessorController instance = null;
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void ProcessorEventHandler();
+
+        private ProcessorEventHandler processorCallback = null;
+
+        private uint onceEventIndex;
+        // Double buffered once event processing
+        private EventHandler[] internalProcessorOnceEvent;
+
+        public event EventHandler ProcessorOnceEvent
+        {
+            add
+            {
+                internalProcessorOnceEvent[onceEventIndex] += value;
+            }
+            remove
+            {
+                internalProcessorOnceEvent[onceEventIndex] -= value;
+            }
+        }
+        public event EventHandler ProcessorEvent;
+        public event EventHandler LayoutProcessorEvent;
+
+        public bool Initialized => initialied;
 
         public static ProcessorController Instance
         {
             get
             {
-                if(instance == null)
+                if (instance == null)
                 {
                     instance = new ProcessorController();
                 }
@@ -71,12 +81,41 @@ namespace Tizen.NUI
             }
         }
 
+        public void Initialize()
+        {
+            if (initialied == false)
+            {
+                initialied = true;
+
+                Interop.ProcessorController.Initialize(SwigCPtr);
+
+                onceEventIndex = 0u;
+                internalProcessorOnceEvent = new EventHandler[2];
+                internalProcessorOnceEvent[0] = null;
+                internalProcessorOnceEvent[1] = null;
+
+                processorCallback = new ProcessorEventHandler(Process);
+                Interop.ProcessorController.SetCallback(SwigCPtr, processorCallback);
+                NDalicPINVOKE.ThrowExceptionIfExists();
+            }
+        }
+
         public void Process()
         {
-            ProcessorOnceEvent?.Invoke(this, null);
-            ProcessorOnceEvent = null;
+            // Let us add once event into 1 index during 0 event invoke
+            onceEventIndex = 1;
+            internalProcessorOnceEvent[0]?.Invoke(this, null);
+            internalProcessorOnceEvent[0] = null;
+
             ProcessorEvent?.Invoke(this, null);
             LayoutProcessorEvent?.Invoke(this, null);
+
+            // Let us add once event into 0 index during 1 event invoke
+            // Note : To avoid ImageView's properties mismatched problem,
+            // We need to invoke events now which attached during internalProcessorOnceEvent[0] and LayoutProcessor.
+            onceEventIndex = 0;
+            internalProcessorOnceEvent[1]?.Invoke(this, null);
+            internalProcessorOnceEvent[1] = null;
         }
 
         /// <summary>
@@ -85,13 +124,28 @@ namespace Tizen.NUI
         [EditorBrowsable(EditorBrowsableState.Never)]
         protected override void Dispose(DisposeTypes type)
         {
-            Interop.ProcessorController.RemoveCallback(SwigCPtr, callback);
-            ProcessorOnceEvent = null;
+            Interop.ProcessorController.RemoveCallback(SwigCPtr, processorCallback);
+            internalProcessorOnceEvent[0] = null;
+            internalProcessorOnceEvent[1] = null;
             ProcessorEvent = null;
             LayoutProcessorEvent = null;
             GC.SuppressFinalize(this);
 
             base.Dispose(type);
         }
+
+        /// <summary>
+        /// Awake ProcessorController.
+        /// It will call ProcessController.processorCallback and ProcessController.processorPostCallback hardly.
+        /// </summary>
+        /// <note>
+        /// When event thread is not in idle state, This function will be ignored.
+        /// </note>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void Awake()
+        {
+            Interop.ProcessorController.Awake(SwigCPtr);
+            NDalicPINVOKE.ThrowExceptionIfExists();
+        }
     } // class ProcessorController
 } // namespace Tizen.NUI