4834c751d438105db5a30e4379c66ff7c3774a96
[platform/core/csapi/tizenfx.git] / src / ElmSharp / ElmSharp / EcoreMainloop.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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.Collections.Generic;
19
20 namespace ElmSharp
21 {
22     public static class EcoreMainloop
23     {
24         static readonly Dictionary<int, Func<bool>> _taskMap = new Dictionary<int, Func<bool>>();
25         static readonly Object _taskLock = new Object();
26         static int _newTaskId = 0;
27
28         static Interop.Ecore.EcoreTaskCallback _nativeHandler;
29
30         static EcoreMainloop()
31         {
32             Interop.Ecore.ecore_init();
33             Interop.Ecore.ecore_main_loop_glib_integrate();
34             _nativeHandler = NativeHandler;
35         }
36
37         public static bool IsMainThread => Interop.Eina.eina_main_loop_is();
38
39         public static void Begin()
40         {
41             Interop.Ecore.ecore_main_loop_begin();
42         }
43
44         public static void Quit()
45         {
46             Interop.Ecore.ecore_main_loop_quit();
47         }
48
49         public static void Post(Action task)
50         {
51             int id = RegistHandler(() => { task(); return false; });
52             Interop.Ecore.ecore_idler_add(_nativeHandler, (IntPtr)id);
53         }
54
55         public static void PostAndWakeUp(Action task)
56         {
57             int id = RegistHandler(() => { task(); return false; });
58             Interop.Ecore.ecore_main_loop_thread_safe_call_async(_nativeHandler, (IntPtr)id);
59         }
60
61         public static void Send(Action task)
62         {
63             int id = RegistHandler(() => { task(); return false; });
64             Interop.Ecore.ecore_main_loop_thread_safe_call_sync(_nativeHandler, (IntPtr)id);
65         }
66
67         public static IntPtr AddTimer(double interval, Func<bool> handler)
68         {
69             int id = RegistHandler(handler);
70             return Interop.Ecore.ecore_timer_add(interval, _nativeHandler, (IntPtr)id);
71         }
72
73         public static void RemoveTimer(IntPtr id)
74         {
75             int taskId = (int)Interop.Ecore.ecore_timer_del(id);
76             _taskMap.Remove(taskId);
77         }
78
79         static int RegistHandler(Func<bool> task)
80         {
81             int taskId;
82             lock (_taskLock)
83             {
84                 taskId = _newTaskId++;
85             }
86             _taskMap[taskId] = task;
87             return taskId;
88         }
89
90         static bool NativeHandler(IntPtr user_data)
91         {
92             int task_id = (int)user_data;
93             Func<bool> userAction = null;
94             _taskMap.TryGetValue(task_id, out userAction);
95             if (userAction != null)
96             {
97                 _taskMap.Remove(task_id);
98                 return userAction();
99             }
100             return false;
101         }
102
103     }
104 }