1f127ad6f723af2fbbbc6cd452cc06475590482c
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / Adaptor.cs
1 /*
2  * Copyright(c) 2018 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
20 namespace Tizen.NUI
21 {
22     /// <summary>
23     /// An Adaptor object is used to initialize and control how Dali runs.
24     ///
25     /// It provides the lifecycle interface that allows the application
26     /// writer to provide their own main loop and other platform related
27     /// features.
28     ///
29     /// The Adaptor class provides a means for initialising the resources required by the Dali::Core.
30     ///
31     /// When dealing with platform events, the application writer must ensure that DALi is called in a
32     /// thread-safe manner.
33     ///
34     /// As soon as the Adaptor class is created and started, the application writer can initialise their
35     /// view objects straight away or as required by the main loop they intend to use (there is no
36     /// need to wait for an initialize signal as per the Tizen.NUI.Application class).
37     ///
38     /// </summary>
39     /// <since_tizen> 4 </since_tizen>
40     public class Adaptor : global::System.IDisposable
41     {
42         /// <summary>swigCMemOwn.</summary>
43         /// <since_tizen> 4 </since_tizen>
44         protected bool swigCMemOwn;
45
46         /// <summary>
47         /// A Flat to check if it is already disposed.
48         /// </summary>
49         /// <since_tizen> 4 </since_tizen>
50         protected bool disposed = false;
51
52         private static readonly Adaptor instance = Adaptor.Get();
53         private global::System.Runtime.InteropServices.HandleRef swigCPtr;
54
55         //A Flag to check who called Dispose(). (By User or DisposeQueue)
56         private bool isDisposeQueued = false;
57
58         private EventHandler<ResizedEventArgs> _resizedEventHandler;
59         private ResizedCallbackDelegate _resizedCallbackDelegate;
60
61         private EventHandler<LanguageChangedEventArgs> _languageChangedEventHandler;
62         private LanguageChangedCallbackDelegate _languageChangedCallbackDelegate;
63
64         internal Adaptor(global::System.IntPtr cPtr, bool cMemoryOwn)
65         {
66             swigCMemOwn = cMemoryOwn;
67             swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
68         }
69
70         /// <summary>
71         /// Dispose.
72         /// </summary>
73         /// <since_tizen> 3 </since_tizen>
74         ~Adaptor()
75         {
76             if (!isDisposeQueued)
77             {
78                 isDisposeQueued = true;
79                 DisposeQueue.Instance.Add(this);
80             }
81         }
82
83         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
84         private delegate void ResizedCallbackDelegate(IntPtr adaptor);
85
86         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
87         private delegate void LanguageChangedCallbackDelegate(IntPtr adaptor);
88
89         /// <summary>
90         /// An event for the Resized signal which can be used to subscribe or unsubscribe the event handler
91         /// provided by the user. The Resized signal is emitted when the size changes.<br />
92         /// </summary>
93         internal event EventHandler<ResizedEventArgs> Resized
94         {
95             add
96             {
97                 if (_resizedEventHandler == null)
98                 {
99                     _resizedCallbackDelegate = (OnResized);
100                     ResizedSignal().Connect(_resizedCallbackDelegate);
101                 }
102                 _resizedEventHandler += value;
103             }
104             remove
105             {
106                 _resizedEventHandler -= value;
107                 if (_resizedEventHandler == null && ResizedSignal().Empty() == false)
108                 {
109                     ResizedSignal().Disconnect(_resizedCallbackDelegate);
110                 }
111             }
112         }
113
114         /// <summary>
115         /// An event for LanguageChanged signal which can be used to subscribe or unsubscribe the event handler
116         /// provided by the user. The LanguageChanged signal is emitted when the language changes.<br />
117         /// </summary>
118         internal event EventHandler<LanguageChangedEventArgs> LanguageChanged
119         {
120             add
121             {
122                 if (_languageChangedEventHandler == null)
123                 {
124                     _languageChangedCallbackDelegate = (OnLanguageChanged);
125                     LanguageChangedSignal().Connect(_languageChangedCallbackDelegate);
126                 }
127                 _languageChangedEventHandler += value;
128             }
129             remove
130             {
131                 _languageChangedEventHandler -= value;
132                 if (_languageChangedEventHandler == null && LanguageChangedSignal().Empty() == false)
133                 {
134                     LanguageChangedSignal().Disconnect(_languageChangedCallbackDelegate);
135                 }
136             }
137         }
138
139         /// <summary>
140         /// Returns a reference to the instance of the adaptor used by the current thread.
141         /// </summary>
142         /// <remarks>The adaptor has been initialized. This is only valid in the main thread.</remarks>
143         /// <since_tizen> 4 </since_tizen>
144         public static Adaptor Instance
145         {
146             get
147             {
148                 return instance;
149             }
150         }
151
152         /// <since_tizen> 4 </since_tizen>
153         public void Dispose()
154         {
155             //Throw excpetion if Dispose() is called in separate thread.
156             if (!Window.IsInstalled())
157             {
158                 throw new System.InvalidOperationException("This API called from separate thread. This API must be called from MainThread.");
159             }
160
161             if (isDisposeQueued)
162             {
163                 Dispose(DisposeTypes.Implicit);
164             }
165             else
166             {
167                 Dispose(DisposeTypes.Explicit);
168                 System.GC.SuppressFinalize(this);
169             }
170         }
171
172         /// <summary>
173         /// Feeds a wheel event to the adaptor.
174         /// </summary>
175         /// <param name="wheelEvent">The wheel event.</param>
176         /// <since_tizen> 4 </since_tizen>
177         public void FeedWheelEvent(Wheel wheelEvent)
178         {
179             Interop.Adaptor.Adaptor_FeedWheelEvent(swigCPtr, Wheel.getCPtr(wheelEvent));
180             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
181         }
182
183         /// <summary>
184         /// Feeds a key event to the adaptor.
185         /// </summary>
186         /// <param name="keyEvent">The key event holding the key information.</param>
187         /// <since_tizen> 4 </since_tizen>
188         public void FeedKeyEvent(Key keyEvent)
189         {
190             Interop.Adaptor.Adaptor_FeedKeyEvent(swigCPtr, Key.getCPtr(keyEvent));
191             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
192         }
193
194         internal static global::System.Runtime.InteropServices.HandleRef getCPtr(Adaptor obj)
195         {
196             return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
197         }
198
199         internal static Adaptor GetAdaptorFromPtr(global::System.IntPtr cPtr)
200         {
201             Adaptor ret = new Adaptor(cPtr, false);
202             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
203             return ret;
204         }
205
206         internal static Adaptor New(Window window)
207         {
208             Adaptor ret = new Adaptor(Interop.Adaptor.Adaptor_New__SWIG_0(Window.getCPtr(window)), false);
209             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
210             return ret;
211         }
212
213         internal static Adaptor New(Window window, SWIGTYPE_p_Configuration__ContextLoss configuration)
214         {
215             Adaptor ret = new Adaptor(Interop.Adaptor.Adaptor_New__SWIG_1(Window.getCPtr(window), SWIGTYPE_p_Configuration__ContextLoss.getCPtr(configuration)), false);
216             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
217             return ret;
218         }
219
220         internal static Adaptor New(Any nativeWindow, SWIGTYPE_p_Dali__RenderSurface surface)
221         {
222             Adaptor ret = new Adaptor(Interop.Adaptor.Adaptor_New__SWIG_2(Any.getCPtr(nativeWindow), SWIGTYPE_p_Dali__RenderSurface.getCPtr(surface)), false);
223             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
224             return ret;
225         }
226
227         internal static Adaptor New(Any nativeWindow, SWIGTYPE_p_Dali__RenderSurface surface, SWIGTYPE_p_Configuration__ContextLoss configuration)
228         {
229             Adaptor ret = new Adaptor(Interop.Adaptor.Adaptor_New__SWIG_3(Any.getCPtr(nativeWindow), SWIGTYPE_p_Dali__RenderSurface.getCPtr(surface), SWIGTYPE_p_Configuration__ContextLoss.getCPtr(configuration)), false);
230             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
231             return ret;
232         }
233
234         internal static Adaptor Get()
235         {
236             Adaptor ret = new Adaptor(Interop.Adaptor.Adaptor_Get(), false);
237             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
238             return ret;
239         }
240
241         /// <summary>
242         /// Checks whether the adaptor is available.
243         /// </summary>
244         /// <returns>True if it is available, false otherwise.</returns>
245         internal static bool IsAvailable()
246         {
247             bool ret = Interop.Adaptor.Adaptor_IsAvailable();
248             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
249             return ret;
250         }
251
252         /// <summary>
253         /// Starts the adaptor.
254         /// </summary>
255         internal void Start()
256         {
257             Interop.Adaptor.Adaptor_Start(swigCPtr);
258             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
259         }
260
261         /// <summary>
262         /// Pauses the adaptor.
263         /// </summary>
264         internal void Pause()
265         {
266             Interop.Adaptor.Adaptor_Pause(swigCPtr);
267             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
268         }
269
270         /// <summary>
271         /// Resumes the adaptor, if previously paused.
272         /// </summary>
273         /// <remarks>If the adaptor is not paused, this does not do anything.</remarks>
274         internal void Resume()
275         {
276             Interop.Adaptor.Adaptor_Resume(swigCPtr);
277             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
278         }
279
280         /// <summary>
281         /// Stops the adaptor.
282         /// </summary>
283         internal void Stop()
284         {
285             Interop.Adaptor.Adaptor_Stop(swigCPtr);
286             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
287         }
288
289         internal bool AddIdle(SWIGTYPE_p_Dali__CallbackBase callback)
290         {
291             bool ret = Interop.Adaptor.Adaptor_AddIdle(swigCPtr, SWIGTYPE_p_Dali__CallbackBase.getCPtr(callback));
292             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
293             return ret;
294         }
295
296         internal void RemoveIdle(SWIGTYPE_p_Dali__CallbackBase callback)
297         {
298             Interop.Adaptor.Adaptor_RemoveIdle(swigCPtr, SWIGTYPE_p_Dali__CallbackBase.getCPtr(callback));
299             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
300         }
301
302         internal void ReplaceSurface(Any nativeWindow, SWIGTYPE_p_Dali__RenderSurface surface)
303         {
304             Interop.Adaptor.Adaptor_ReplaceSurface(swigCPtr, Any.getCPtr(nativeWindow), SWIGTYPE_p_Dali__RenderSurface.getCPtr(surface));
305             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
306         }
307
308         internal SWIGTYPE_p_Dali__RenderSurface GetSurface()
309         {
310             SWIGTYPE_p_Dali__RenderSurface ret = new SWIGTYPE_p_Dali__RenderSurface(Interop.Adaptor.Adaptor_GetSurface(swigCPtr), false);
311             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
312             return ret;
313         }
314
315         internal Any GetNativeWindowHandle()
316         {
317             Any ret = new Any(Interop.Adaptor.Adaptor_GetNativeWindowHandle(swigCPtr), true);
318             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
319             return ret;
320         }
321
322         /// <summary>
323         /// Releases any locks the surface may hold.
324         /// </summary>
325         /// <remarks>
326         /// For example, after compositing an offscreen surface, use this method to allow rendering to continue.
327         /// </remarks>
328         internal void ReleaseSurfaceLock()
329         {
330             Interop.Adaptor.Adaptor_ReleaseSurfaceLock(swigCPtr);
331             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
332         }
333
334         /// <summary>
335         /// Sets the number of frames per render.
336         /// </summary>
337         /// <param name="numberOfVSyncsPerRender">The number of vsyncs between successive renders.</param>
338         /// <remarks>
339         /// Suggest this is a power of two:
340         /// 1 - render each vsync frame.
341         /// 2 - render every other vsync frame.
342         /// 4 - render every fourth vsync frame.
343         /// 8 - render every eighth vsync frame.
344         ///</remarks>
345         internal void SetRenderRefreshRate(uint numberOfVSyncsPerRender)
346         {
347             Interop.Adaptor.Adaptor_SetRenderRefreshRate(swigCPtr, numberOfVSyncsPerRender);
348             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
349         }
350
351         /// <summary>
352         /// Calls this method to notify DALi when a scene is created and initialized.
353         /// Notify the adaptor that the scene has been created.
354         /// </summary>
355         internal void NotifySceneCreated()
356         {
357             Interop.Adaptor.Adaptor_NotifySceneCreated(swigCPtr);
358             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
359         }
360
361         /// <summary>
362         /// Calls this method to notify DALi when the system language changes.
363         ///
364         /// Use this only when not using Dali::Application. As the application is created, using the
365         /// application will automatically receive notification of the language change.
366         /// When Dali::Application is not used, the application developer should
367         /// use app-core to receive the language change notifications and should update DALi
368         /// by calling this method.
369         /// </summary>
370         internal void NotifyLanguageChanged()
371         {
372             Interop.Adaptor.Adaptor_NotifyLanguageChanged(swigCPtr);
373             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
374         }
375
376         internal void FeedTouchPoint(TouchPoint point, int timeStamp)
377         {
378             Interop.Adaptor.Adaptor_FeedTouchPoint(swigCPtr, TouchPoint.getCPtr(point), timeStamp);
379             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
380         }
381
382         /// <summary>
383         /// Notifies core that the scene has been created.
384         /// </summary>
385         internal void SceneCreated()
386         {
387             Interop.Adaptor.Adaptor_SceneCreated(swigCPtr);
388             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
389         }
390
391         internal AdaptorSignalType ResizedSignal()
392         {
393             AdaptorSignalType ret = new AdaptorSignalType(Interop.Adaptor.Adaptor_ResizedSignal(swigCPtr), false);
394             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
395             return ret;
396         }
397
398         internal AdaptorSignalType LanguageChangedSignal()
399         {
400             AdaptorSignalType ret = new AdaptorSignalType(Interop.Adaptor.Adaptor_LanguageChangedSignal(swigCPtr), false);
401             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
402             return ret;
403         }
404
405         /// <summary>
406         /// Dispose.
407         /// </summary>
408         /// <since_tizen> 4 </since_tizen>
409         protected virtual void Dispose(DisposeTypes type)
410         {
411             if (disposed)
412             {
413                 return;
414             }
415
416             if (type == DisposeTypes.Explicit)
417             {
418                 //Called by User
419                 //Release your own managed resources here.
420                 //You should release all of your own disposable objects here.
421
422             }
423
424             //Release your own unmanaged resources here.
425             //You should not access any managed member here except static instance.
426             //because the execution order of Finalizes is non-deterministic.
427
428             if (swigCPtr.Handle != global::System.IntPtr.Zero)
429             {
430                 swigCMemOwn = false;
431                 Interop.Adaptor.delete_Adaptor(swigCPtr);
432                 swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
433             }
434
435             disposed = true;
436         }
437
438         private void OnResized(IntPtr adaptor)
439         {
440             ResizedEventArgs e = new ResizedEventArgs();
441             if (adaptor != null)
442             {
443                 e.Adaptor = Adaptor.GetAdaptorFromPtr(adaptor);
444             }
445
446             if (_resizedEventHandler != null)
447             {
448                 //here we send all data to user event handlers
449                 _resizedEventHandler(this, e);
450             }
451         }
452
453         private void OnLanguageChanged(IntPtr adaptor)
454         {
455             LanguageChangedEventArgs e = new LanguageChangedEventArgs();
456             e.Adaptor = Adaptor.GetAdaptorFromPtr(adaptor);
457
458             if (_languageChangedEventHandler != null)
459             {
460                 //here we send all data to user event handlers
461                 _languageChangedEventHandler(this, e);
462             }
463         }
464
465         /// <summary>
466         /// Event arguments that passed via the Resized signal.
467         /// </summary>
468         internal class ResizedEventArgs : EventArgs
469         {
470
471             /// <summary>
472             /// Adaptor - is the adaptor which has size changed.
473             /// </summary>
474             /// <since_tizen> 4 </since_tizen>
475             public Adaptor Adaptor
476             {
477                 get;
478                 set;
479             }
480         }
481
482         /// <summary>
483         /// Event arguments that passed via the LanguageChanged signal.
484         /// </summary>
485         internal class LanguageChangedEventArgs : EventArgs
486         {
487
488             /// <summary>
489             /// Adaptor - is the adaptor which has language changed.
490             /// </summary>
491             /// <since_tizen> 4 </since_tizen>
492             public Adaptor Adaptor
493             {
494                 get;
495                 set;
496             }
497         }
498
499     }
500
501 }