[NUI] Add played flag to Timer class
[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         private string stackTrace;
41
42         internal Timer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(NDalicPINVOKE.Timer_SWIGUpcast(cPtr), cMemoryOwn)
43         {
44             swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
45         }
46
47         internal static global::System.Runtime.InteropServices.HandleRef getCPtr(Timer obj)
48         {
49             return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
50         }
51
52         /// <summary>
53         /// Dispose.
54         /// </summary>
55         /// <since_tizen> 3 </since_tizen>
56         protected override void Dispose(DisposeTypes type)
57         {
58             if(disposed)
59             {
60                 return;
61             }
62
63             if(type == DisposeTypes.Explicit)
64             {
65                 //Called by User
66                 //Release your own managed resources here.
67                 //You should release all of your own disposable objects here.
68             }
69
70             //Release your own unmanaged resources here.
71             //You should not access any managed member here except static instance.
72             //because the execution order of Finalizes is non-deterministic.
73
74             if (_timerTickCallbackDelegate != null)
75             {
76                 TickSignal().Disconnect(_timerTickCallbackDelegate);
77             }
78
79             if (swigCPtr.Handle != global::System.IntPtr.Zero)
80             {
81                 if (swigCMemOwn)
82                 {
83                     swigCMemOwn = false;
84                     NDalicPINVOKE.delete_Timer(swigCPtr);
85                 }
86                 swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
87             }
88
89             played = false;
90             base.Dispose(type);
91         }
92
93
94         /// <summary>
95         /// Event arguments that passed via the tick event.
96         /// </summary>
97         /// <since_tizen> 3 </since_tizen>
98         public class TickEventArgs : EventArgs
99         {
100         }
101
102         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
103         private delegate bool TickCallbackDelegate(IntPtr data);
104         private EventHandlerWithReturnType<object, TickEventArgs, bool> _timerTickEventHandler;
105         private TickCallbackDelegate _timerTickCallbackDelegate;
106
107         /// <summary>
108         /// @brief Event for the ticked signal, which can be used to subscribe or unsubscribe the event handler
109         /// provided by the user. The ticked signal is emitted after specified time interval.<br />
110         /// </summary>
111         /// <since_tizen> 3 </since_tizen>
112         public event EventHandlerWithReturnType<object, TickEventArgs, bool> Tick
113         {
114             add
115             {
116                 if (_timerTickEventHandler == null)
117                 {
118                     _timerTickCallbackDelegate = new TickCallbackDelegate(OnTick);
119                     TickSignal().Connect(_timerTickCallbackDelegate);
120                 }
121                 _timerTickEventHandler += value;
122             }
123             remove
124             {
125                 _timerTickEventHandler -= value;
126                 if (_timerTickEventHandler == null && TickSignal().Empty() == false)
127                 {
128                     TickSignal().Disconnect(_timerTickCallbackDelegate);
129                 }
130             }
131         }
132
133         private bool OnTick(IntPtr data)
134         {
135             TickEventArgs e = new TickEventArgs();
136
137             if (played == false)
138             {
139                 Tizen.Log.Fatal("NUI", $"should not be here! OnTick()!swigCPtr={swigCPtr.Handle}");
140                 Tizen.Log.Fatal("NUI", "should not be here! #################### TID = " + global::System.Threading.Thread.CurrentThread.ManagedThreadId);
141                 Tizen.Log.Fatal("NUI", stackTrace);
142             }
143
144             if (_timerTickEventHandler != null && played == true)
145             {
146                 //here we send all data to user event handlers
147                 return _timerTickEventHandler(this, e);
148             }
149             return false;
150         }
151
152         /// <summary>
153         /// Creates a tick timer that emits periodic signal.
154         /// </summary>
155         /// <param name="milliSec">Interval in milliseconds.</param>
156         /// <returns>A new timer.</returns>
157         /// <since_tizen> 3 </since_tizen>
158         public Timer(uint milliSec) : this(NDalicPINVOKE.Timer_New(milliSec), true)
159         {
160             stackTrace = Environment.StackTrace;
161             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
162
163         }
164         internal Timer(Timer timer) : this(NDalicPINVOKE.new_Timer__SWIG_1(Timer.getCPtr(timer)), true)
165         {
166             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
167         }
168
169         /// <summary>
170         /// Downcasts a handle to Timer handle.
171         /// </summary>
172         /// <since_tizen> 3 </since_tizen>
173         /// Please do not use! this will be deprecated!
174         /// Instead please use as keyword.
175         [Obsolete("Please do not use! This will be deprecated! Please use as keyword instead!")]
176         [EditorBrowsable(EditorBrowsableState.Never)]
177         public static Timer DownCast(BaseHandle handle)
178         {
179             Timer ret =  Registry.GetManagedBaseHandleFromNativePtr(handle) as Timer;
180             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
181             return ret;
182         }
183
184         /// <summary>
185         /// Starts the timer.<br />
186         /// In case a timer is already running, its time is reset and the timer is restarted.<br />
187         /// </summary>
188         /// <since_tizen> 3 </since_tizen>
189         public void Start()
190         {
191             played = true;
192             NDalicPINVOKE.Timer_Start(swigCPtr);
193
194             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
195         }
196
197         /// <summary>
198         /// Stops the timer.
199         /// </summary>
200         /// <since_tizen> 3 </since_tizen>
201         public void Stop()
202         {
203             played = false;
204             NDalicPINVOKE.Timer_Stop(swigCPtr);
205
206             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
207         }
208
209         /// <summary>
210         /// Gets/Sets the interval of the timer.
211         /// </summary>
212         /// <since_tizen> 4 </since_tizen>
213         public uint Interval
214         {
215             get
216             {
217                 return GetInterval();
218             }
219             set
220             {
221                 SetInterval(value);
222             }
223         }
224
225         /// <summary>
226         /// Sets a new interval on the timer and starts the timer.<br />
227         /// Cancels the previous timer.<br />
228         /// </summary>
229         /// <param name="milliSec">MilliSec interval in milliseconds.</param>
230         internal void SetInterval(uint milliSec)
231         {
232             NDalicPINVOKE.Timer_SetInterval(swigCPtr, milliSec);
233             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
234         }
235
236         internal uint GetInterval()
237         {
238             uint ret = NDalicPINVOKE.Timer_GetInterval(swigCPtr);
239             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
240             return ret;
241         }
242
243         /// <summary>
244         /// Tells whether the timer is running.
245         /// </summary>
246         /// <returns>Whether the timer is started or not.</returns>
247         /// <since_tizen> 3 </since_tizen>
248         public bool IsRunning()
249         {
250             bool ret = NDalicPINVOKE.Timer_IsRunning(swigCPtr);
251             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
252             return ret;
253         }
254
255         internal TimerSignalType TickSignal()
256         {
257             TimerSignalType ret = new TimerSignalType(NDalicPINVOKE.Timer_TickSignal(swigCPtr), false);
258             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
259             return ret;
260         }
261
262     }
263
264 }
265