/* * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Concurrent; namespace ElmSharp { /// /// EcoreMainloop is a helper class, which provides the functions relative to Ecore's main loop. /// /// preview [Obsolete("This has been deprecated in API12")] public static class EcoreMainloop { static readonly ConcurrentDictionary> _taskMap = new ConcurrentDictionary>(); static readonly Object _taskLock = new Object(); static int _newTaskId = 0; static Interop.Ecore.EcoreTaskCallback _nativeHandler; static EcoreMainloop() { Interop.Ecore.ecore_init(); Interop.Ecore.ecore_main_loop_glib_integrate(); _nativeHandler = NativeHandler; } /// /// Checks if you are calling this function from the main thread. /// /// True if the calling function is the same thread, false otherwise. /// preview [Obsolete("This has been deprecated in API12")] public static bool IsMainThread => Interop.Eina.eina_main_loop_is(); /// /// Runs the application main loop. /// /// preview [Obsolete("This has been deprecated in API12")] public static void Begin() { Interop.Ecore.ecore_main_loop_begin(); } /// /// Quits the main loop, once all the events currently on the queue have been processed. /// /// preview [Obsolete("This has been deprecated in API12")] public static void Quit() { Interop.Ecore.ecore_main_loop_quit(); } /// /// Adds an idler handler. /// /// The action to call when idle. /// preview [Obsolete("This has been deprecated in API12")] public static void Post(Action task) { int id = RegistHandler(() => { task(); return false; }); Interop.Ecore.ecore_idler_add(_nativeHandler, (IntPtr)id); } /// /// Calls the callback asynchronously in the main loop. /// /// The action wanted to be called. /// preview [Obsolete("This has been deprecated in API12")] public static void PostAndWakeUp(Action task) { if (IsMainThread) { Post(task); } else { int id = RegistHandler(() => { task(); return false; }); Interop.Ecore.ecore_main_loop_thread_safe_call_async(_nativeHandler, (IntPtr)id); } } /// /// Calls the callback synchronously in the main loop. /// /// The action wanted to be called. /// preview [Obsolete("This has been deprecated in API12")] public static void Send(Action task) { int id = RegistHandler(() => { task(); return false; }); Interop.Ecore.ecore_main_loop_thread_safe_call_sync(_nativeHandler, (IntPtr)id); } /// /// Creates a timer to call the given function in the given period of time. /// /// The interval in seconds. /// The given function. /// A timer object handler on success, or null on failure. /// preview [Obsolete("This has been deprecated in API12")] public static IntPtr AddTimer(double interval, Func handler) { int id = RegistHandler(handler); return Interop.Ecore.ecore_timer_add(interval, _nativeHandler, (IntPtr)id); } /// /// Removes the specified timer from the timer list. /// /// The specified timer handler /// preview [Obsolete("This has been deprecated in API12")] public static void RemoveTimer(IntPtr id) { int taskId = (int)Interop.Ecore.ecore_timer_del(id); Func unused; _taskMap.TryRemove(taskId, out unused); } static int RegistHandler(Func task) { int taskId; lock (_taskLock) { taskId = _newTaskId++; } _taskMap[taskId] = task; return taskId; } static bool NativeHandler(IntPtr user_data) { int task_id = (int)user_data; Func userAction = null; if (_taskMap.TryGetValue(task_id, out userAction)) { bool result = false; if (userAction != null) { result = userAction(); } if (!result) { _taskMap.TryRemove(task_id, out userAction); } return result; } return false; } } }