52cb55405fe969e29ab018a120edf3b92615c83c
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / Timer.cs
1 /*
2  * Copyright(c) 2017 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 using System;
18 using System.Runtime.InteropServices;
19 using System.ComponentModel;
20 using System.Threading;
21
22 namespace Tizen.NUI
23 {
24     /// <summary>
25     /// Mechanism to issue simple periodic or one-shot events.<br />
26     /// Timer is provided for application developers to be able to issue
27     /// simple periodic or one-shot events. Please note that the timer
28     /// callback functions should return as soon as possible because they
29     /// block the next SignalTick. Please note that timer signals are not
30     /// in sync with DALi's render timer.<br />
31     /// This class is a handle class so it can be stack allocated and used
32     /// as a member.<br />
33     /// </summary>
34     /// <since_tizen> 3 </since_tizen>
35     public class Timer : BaseHandle
36     {
37         private global::System.Runtime.InteropServices.HandleRef swigCPtr;
38
39         private bool played = false;
40
41         internal Timer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(NDalicPINVOKE.Timer_SWIGUpcast(cPtr), cMemoryOwn)
42         {
43             swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
44
45             _timerTickCallbackDelegate = OnTick;
46             _timerTickCallbackOfNative = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate<System.Delegate>(_timerTickCallbackDelegate);
47
48             NUILog.Debug($"(0x{swigCPtr.Handle:X})Timer() contructor!");
49         }
50
51         ~Timer()
52         {
53             NUILog.Debug($"(0x{swigCPtr.Handle:X})Timer() distructor!, disposed={disposed}");
54         }
55
56         internal static global::System.Runtime.InteropServices.HandleRef getCPtr(Timer obj)
57         {
58             return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
59         }
60
61         /// <summary>
62         /// Dispose.
63         /// </summary>
64         /// <since_tizen> 3 </since_tizen>
65         protected override void Dispose(DisposeTypes type)
66         {
67             NUILog.Debug($"(0x{swigCPtr.Handle:X}) Timer.Dispose(type={type}, disposed={disposed})");
68
69             if (this != null && _timerTickCallbackDelegate != null)
70             {
71                 TickSignal().Disconnect(_timerTickCallbackOfNative);
72             }
73
74             if (disposed)
75             {
76                 return;
77             }
78
79             if (type == DisposeTypes.Explicit)
80             {
81                 //Called by User
82                 //Release your own managed resources here.
83                 //You should release all of your own disposable objects here.
84             }
85
86             //Release your own unmanaged resources here.
87             //You should not access any managed member here except static instance.
88             //because the execution order of Finalizes is non-deterministic.
89
90             if (swigCPtr.Handle != global::System.IntPtr.Zero)
91             {
92                 if (swigCMemOwn)
93                 {
94                     swigCMemOwn = false;
95                     NDalicPINVOKE.delete_Timer(swigCPtr);
96                 }
97                 swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
98             }
99
100             played = false;
101             base.Dispose(type);
102         }
103
104
105         /// <summary>
106         /// Event arguments that passed via the tick event.
107         /// </summary>
108         /// <since_tizen> 3 </since_tizen>
109         public class TickEventArgs : EventArgs
110         {
111         }
112
113         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
114         private delegate bool TickCallbackDelegate();
115         private EventHandlerWithReturnType<object, TickEventArgs, bool> _timerTickEventHandler;
116         private TickCallbackDelegate _timerTickCallbackDelegate;
117
118         private System.IntPtr _timerTickCallbackOfNative;
119
120         /// <summary>
121         /// @brief Event for the ticked signal, which can be used to subscribe or unsubscribe the event handler
122         /// provided by the user. The ticked signal is emitted after specified time interval.<br />
123         /// </summary>
124         /// <since_tizen> 3 </since_tizen>
125         public event EventHandlerWithReturnType<object, TickEventArgs, bool> Tick
126         {
127             add
128             {
129                 if (_timerTickEventHandler == null && disposed == false)
130                 {
131                     TickSignal().Connect(_timerTickCallbackOfNative);
132                 }
133                 _timerTickEventHandler += value;
134             }
135             remove
136             {
137                 _timerTickEventHandler -= value;
138                 if (_timerTickEventHandler == null && TickSignal().Empty() == false)
139                 {
140                     TickSignal().Disconnect(_timerTickCallbackOfNative);
141                 }
142             }
143         }
144
145         private bool OnTick()
146         {
147             TickEventArgs e = new TickEventArgs();
148
149             if (played == false)
150             {
151                 Tizen.Log.Fatal("NUI", $"(0x{swigCPtr.Handle:X}) OnTick() is called even played is false!");
152                 //throw new System.InvalidOperationException($"OnTick() excpetion!");
153             }
154
155             if (_timerTickEventHandler != null && played == true)
156             {
157                 //here we send all data to user event handlers
158                 return _timerTickEventHandler(this, e);
159             }
160             return false;
161         }
162
163         /// <summary>
164         /// Creates a tick timer that emits periodic signal.
165         /// </summary>
166         /// <param name="milliSec">Interval in milliseconds.</param>
167         /// <returns>A new timer.</returns>
168         /// <since_tizen> 3 </since_tizen>
169         public Timer(uint milliSec) : this(NDalicPINVOKE.Timer_New(milliSec), true)
170         {
171             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
172
173             NUILog.Debug($"(0x{swigCPtr.Handle:X})  Timer({milliSec}) Constructor!");
174         }
175         internal Timer(Timer timer) : this(NDalicPINVOKE.new_Timer__SWIG_1(Timer.getCPtr(timer)), true)
176         {
177             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
178         }
179
180         /// <summary>
181         /// Starts the timer.<br />
182         /// In case a timer is already running, its time is reset and the timer is restarted.<br />
183         /// </summary>
184         /// <since_tizen> 3 </since_tizen>
185         public void Start()
186         {
187             played = true;
188             NDalicPINVOKE.Timer_Start(swigCPtr);
189
190             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
191         }
192
193         /// <summary>
194         /// Stops the timer.
195         /// </summary>
196         /// <since_tizen> 3 </since_tizen>
197         public void Stop()
198         {
199             played = false;
200             NDalicPINVOKE.Timer_Stop(swigCPtr);
201
202             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
203         }
204
205         /// <summary>
206         /// Gets/Sets the interval of the timer.
207         /// </summary>
208         /// <remarks>For setter, this sets a new interval on the timer and starts the timer. <br />
209         /// Cancels the previous timer.
210         /// </remarks>
211         /// <since_tizen> 4 </since_tizen>
212         public uint Interval
213         {
214             get
215             {
216                 return GetInterval();
217             }
218             set
219             {
220                 SetInterval(value);
221             }
222         }
223
224         /// <summary>
225         /// Sets a new interval on the timer and starts the timer.<br />
226         /// Cancels the previous timer.<br />
227         /// </summary>
228         /// <param name="milliSec">MilliSec interval in milliseconds.</param>
229         internal void SetInterval(uint milliSec)
230         {
231             NUILog.Debug($"(0x{swigCPtr.Handle:X})SetInterval({milliSec})");
232
233             played = true;
234
235             NDalicPINVOKE.Timer_SetInterval(swigCPtr, milliSec);
236             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
237         }
238
239         internal uint GetInterval()
240         {
241             uint ret = NDalicPINVOKE.Timer_GetInterval(swigCPtr);
242             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
243             return ret;
244         }
245
246         /// <summary>
247         /// Tells whether the timer is running.
248         /// </summary>
249         /// <returns>Whether the timer is started or not.</returns>
250         /// <since_tizen> 3 </since_tizen>
251         public bool IsRunning()
252         {
253             bool ret = NDalicPINVOKE.Timer_IsRunning(swigCPtr);
254             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
255             return ret;
256         }
257
258         internal TimerSignalType TickSignal()
259         {
260             TimerSignalType ret = new TimerSignalType(NDalicPINVOKE.Timer_TickSignal(swigCPtr), false);
261             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
262             return ret;
263         }
264
265     }
266
267 }
268