[NUI] Change all CallingConvention to `Cdecl`
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / internal / Common / ProcessorController.cs
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 using System.Runtime.InteropServices;
19 using System;
20 using System.ComponentModel;
21
22 namespace Tizen.NUI
23 {
24     /// <summary>
25     /// Singleton class.
26     /// ProcessorController handles ProcessorCallbacks those are requested to be called for each end of event process.
27     /// If there are works those required to be called after all of the event process for the efficiency, add them ProcessorController.
28     /// The calling order is not guaranteed but ProcessorCallbackes of LayoutController those are added by using AddLayoutControllerProcessor,
29     /// are called after ordinaly ProcessCallbacks added by AddProcessor.
30     ///
31     /// The added callbacks will be called every time of event tick.
32     /// If the callback is not be wanted to be called anymore, remove it.
33     /// </summary>
34     internal sealed class ProcessorController : Disposable
35     {
36         private static ProcessorController instance = null;
37
38         private ProcessorController() : this(Interop.ProcessorController.New(), true)
39         {
40         }
41
42         internal ProcessorController(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
43         {
44             onceEventIndex = 0u;
45             internalProcessorOnceEvent = new EventHandler[2];
46             internalProcessorOnceEvent[0] = null;
47             internalProcessorOnceEvent[1] = null;
48
49             processorCallback = new ProcessorEventHandler(Process);
50             Interop.ProcessorController.SetCallback(SwigCPtr, processorCallback);
51         }
52
53         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
54         internal delegate void ProcessorEventHandler();
55
56         private ProcessorEventHandler processorCallback = null;
57
58         private uint onceEventIndex;
59         // Double buffered once event processing
60         private EventHandler[] internalProcessorOnceEvent;
61
62         public event EventHandler ProcessorOnceEvent
63         {
64             add
65             {
66                 internalProcessorOnceEvent[onceEventIndex] += value;
67             }
68             remove
69             {
70                 internalProcessorOnceEvent[onceEventIndex] -= value;
71             }
72         }
73         public event EventHandler ProcessorEvent;
74         public event EventHandler LayoutProcessorEvent;
75
76         public static ProcessorController Instance
77         {
78             get
79             {
80                 if (instance == null)
81                 {
82                     instance = new ProcessorController();
83                 }
84                 return instance;
85             }
86         }
87
88         public void Process()
89         {
90             // Let us add once event into 1 index during 0 event invoke
91             onceEventIndex = 1;
92             internalProcessorOnceEvent[0]?.Invoke(this, null);
93             internalProcessorOnceEvent[0] = null;
94
95             ProcessorEvent?.Invoke(this, null);
96             LayoutProcessorEvent?.Invoke(this, null);
97
98             // Let us add once event into 0 index during 1 event invoke
99             // Note : To avoid ImageView's properties mismatched problem,
100             // We need to invoke events now which attached during internalProcessorOnceEvent[0] and LayoutProcessor.
101             onceEventIndex = 0;
102             internalProcessorOnceEvent[1]?.Invoke(this, null);
103             internalProcessorOnceEvent[1] = null;
104         }
105
106         /// <summary>
107         /// Dispose ProcessorController.
108         /// </summary>
109         [EditorBrowsable(EditorBrowsableState.Never)]
110         protected override void Dispose(DisposeTypes type)
111         {
112             Interop.ProcessorController.RemoveCallback(SwigCPtr, processorCallback);
113             internalProcessorOnceEvent[0] = null;
114             internalProcessorOnceEvent[1] = null;
115             ProcessorEvent = null;
116             LayoutProcessorEvent = null;
117             GC.SuppressFinalize(this);
118
119             base.Dispose(type);
120         }
121
122         /// <summary>
123         /// Awake ProcessorController.
124         /// It will call ProcessController.processorCallback and ProcessController.processorPostCallback hardly.
125         /// </summary>
126         /// <note>
127         /// When event thread is not in idle state, This function will be ignored.
128         /// </note>
129         [EditorBrowsable(EditorBrowsableState.Never)]
130         public void Awake()
131         {
132             Interop.ProcessorController.Awake(SwigCPtr);
133         }
134     } // class ProcessorController
135 } // namespace Tizen.NUI