[NUI] Change all CallingConvention to `Cdecl`
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / internal / Transition / TransitionSet.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;
19 using System.ComponentModel;
20 using System.Runtime.InteropServices;
21
22 namespace Tizen.NUI
23 {
24     /// <summary>
25     /// TransitionSet is used to control lifetime of multiple Transitions.
26     /// For the one page transition, may multiple transitions are played coincidently.
27     /// Every transitions added on a TransitionSet have same play lifetime. And emit a single Finished signal.
28     /// </summary>
29     internal class TransitionSet : BaseHandle
30     {
31         private TransitionSetFinishedEventCallbackType transitionSetFinishedEventCallback;
32         private System.IntPtr finishedCallbackOfNative;
33
34         /// <summary>
35         /// Creates an initialized transitionSet.<br />
36         /// </summary>
37         /// <remarks>DurationmSeconds must be greater than zero.</remarks>
38         public TransitionSet() : this(Interop.TransitionSet.New(), true)
39         {
40             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
41         }
42
43         internal TransitionSet(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
44         {
45             transitionSetFinishedEventCallback = OnFinished;
46             finishedCallbackOfNative = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate<System.Delegate>(transitionSetFinishedEventCallback);
47         }
48
49         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
50         private delegate void TransitionSetFinishedEventCallbackType(IntPtr data);
51
52         private event EventHandler transitionSetFinishedEventHandler;
53
54         /**
55         * @brief Event for the finished signal which can be used to subscribe or unsubscribe the event handler.
56         * The finished signal is emitted when an transitionSet's transitionSets have finished.
57         */
58         public event EventHandler Finished
59         {
60             add
61             {
62                 if (transitionSetFinishedEventHandler == null && disposed == false)
63                 {
64                     TransitionSetFinishedSignal finishedSignal = FinishedSignal();
65                     finishedSignal.Connect(finishedCallbackOfNative);
66                     finishedSignal.Dispose();
67                 }
68                 transitionSetFinishedEventHandler += value;
69             }
70             remove
71             {
72                 transitionSetFinishedEventHandler -= value;
73
74                 TransitionSetFinishedSignal finishedSignal = FinishedSignal();
75                 if (transitionSetFinishedEventHandler == null && finishedSignal.Empty() == false)
76                 {
77                     finishedSignal.Disconnect(finishedCallbackOfNative);
78                 }
79                 finishedSignal.Dispose();
80             }
81         }
82
83         /// <summary>
84         /// Downcasts a handle to transitionSet handle.<br />
85         /// If handle points to an transitionSet object, the downcast produces a valid handle.<br />
86         /// If not, the returned handle is left uninitialized.<br />
87         /// </summary>
88         /// <param name="handle">Handle to an object.</param>
89         /// <returns>Handle to an transitionSet object or an uninitialized handle.</returns>
90         /// <exception cref="ArgumentNullException"> Thrown when handle is null. </exception>
91         internal static TransitionSet DownCast(BaseHandle handle)
92         {
93             if (handle == null)
94             {
95                 throw new ArgumentNullException(nameof(handle));
96             }
97             TransitionSet ret = Registry.GetManagedBaseHandleFromNativePtr(handle) as TransitionSet;
98             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
99             return ret;
100         }
101
102         public void AddTransition(TransitionItemBase transition)
103         {
104             if (transition is TransitionGroupItem)
105             {
106                 TransitionGroupItem transitionGroup = transition as TransitionGroupItem;
107                 for (int index = 0; index < transitionGroup.TransitionCount; ++index)
108                 {
109                     this.AddTransition(transitionGroup.GetTransitionAt(index));
110                 }
111             }
112             else
113             {
114                 Interop.TransitionSet.AddTransition(SwigCPtr, transition.SwigCPtr);
115                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
116             }
117         }
118
119         public TransitionItemBase GetTransitionAt(uint index)
120         {
121             //to fix memory leak issue, match the handle count with native side.
122             IntPtr cPtr = Interop.TransitionSet.GetTransitionAt(SwigCPtr, index);
123             HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
124             TransitionItemBase ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as TransitionItemBase;
125             if (cPtr != IntPtr.Zero && ret == null)
126             {
127                 ret = new TransitionItemBase(cPtr, false);
128                 if (NDalicPINVOKE.SWIGPendingException.Pending)
129                     throw NDalicPINVOKE.SWIGPendingException.Retrieve();
130                 return ret;
131             }
132             Interop.BaseHandle.DeleteBaseHandle(CPtr);
133             CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
134
135             if (NDalicPINVOKE.SWIGPendingException.Pending)
136                 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
137             return ret;
138         }
139
140         public uint GetTransitionCount()
141         {
142             uint ret = Interop.TransitionSet.GetTransitionCount(SwigCPtr);
143             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
144             return ret;
145         }
146
147         /// <summary>
148         /// Plays the transitionSet.
149         /// </summary>
150         public void Play()
151         {
152             Interop.TransitionSet.Play(SwigCPtr);
153             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
154         }
155
156         internal TransitionSet(TransitionSet handle) : this(Interop.TransitionSet.NewTransitionSet(TransitionSet.getCPtr(handle)), true)
157         {
158             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
159         }
160
161         internal TransitionSet Assign(TransitionSet rhs)
162         {
163             TransitionSet ret = new TransitionSet(Interop.TransitionSet.Assign(SwigCPtr, TransitionSet.getCPtr(rhs)), false);
164             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
165             return ret;
166         }
167
168         internal TransitionSetFinishedSignal FinishedSignal()
169         {
170             TransitionSetFinishedSignal ret = new TransitionSetFinishedSignal(Interop.TransitionSet.FinishedSignal(SwigCPtr), false);
171             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
172             return ret;
173         }
174
175         /// <summary>
176         /// To make transitionSet instance be disposed.
177         /// </summary>
178         protected override void Dispose(DisposeTypes type)
179         {
180             if (disposed)
181             {
182                 return;
183             }
184
185             if (transitionSetFinishedEventHandler != null)
186             {
187                 TransitionSetFinishedSignal finishedSignal = FinishedSignal();
188                 finishedSignal?.Disconnect(finishedCallbackOfNative);
189                 finishedSignal?.Dispose();
190                 transitionSetFinishedEventHandler = null;
191             }
192
193             base.Dispose(type);
194         }
195
196         /// This will not be public opened.
197         [EditorBrowsable(EditorBrowsableState.Never)]
198         protected override void ReleaseSwigCPtr(System.Runtime.InteropServices.HandleRef swigCPtr)
199         {
200             if (swigCPtr.Handle == IntPtr.Zero || Disposed)
201             {
202                 Tizen.Log.Fatal("NUI", $"[ERROR] TransitionSet ReleaseSwigCPtr()! IntPtr=0x{swigCPtr.Handle:X} Disposed={Disposed}");
203                 return;
204             }
205             Interop.TransitionSet.Delete(swigCPtr);
206         }
207
208         private void OnFinished(IntPtr data)
209         {
210             if (transitionSetFinishedEventHandler != null)
211             {
212                 //here we send all data to user event handlers
213                 transitionSetFinishedEventHandler(this, null);
214             }
215         }
216     }
217 }