1 #ifndef DALI_ASYNC_TASK_MANAGER_H
2 #define DALI_ASYNC_TASK_MANAGER_H
5 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 #include <dali/public-api/common/intrusive-ptr.h>
22 #include <dali/public-api/object/base-handle.h>
23 #include <dali/public-api/signals/callback.h>
25 #include <string_view>
28 #include <dali/public-api/dali-adaptor-common.h>
32 namespace Internal DALI_INTERNAL
36 class AsyncTaskManager;
38 } // namespace DALI_INTERNAL
41 using AsyncTaskPtr = IntrusivePtr<AsyncTask>;
44 * The async tasks to be processed in the worker thread.
47 class DALI_ADAPTOR_API AsyncTask : public RefObject
50 // The Type of invocation thread
58 * @brief The priority of this task what user think.
59 * To avoid long term tasks (like remote image download) block whole threads,
60 * Let user set the priority type of this task.
62 * Low priority task means it doesn't need to process by FIFO logic.
63 * So we make that Low priority don't take whole threads.
65 * Task selection algorithm defined internally.
67 * @note Task cannot change the priority type after create.
71 enum class PriorityType
73 HIGH = 0, ///< Highest priority to process task. @SINCE_2_2.17
74 LOW = 1, ///< Lowest priority to process task. @SINCE_2_2.17
76 PRIORITY_COUNT, ///< The number of priority type. @SINCE_2_2.17
78 DEFAULT = HIGH, ///< Default priority value if nothing defined. @SINCE_2_2.17
84 * @param[in] callback The callback to invoke on task completion, either on the main thread on the worker thread. The ownership of callback is taken by this class.
85 * @param[in] priority The proirity type of this task.
86 * @param[in] threadType The thread type of invocation callback.
88 AsyncTask(CallbackBase* callback, PriorityType priority = PriorityType::DEFAULT, ThreadType threadType = AsyncTask::ThreadType::MAIN_THREAD);
91 * Get the complated callback
94 CallbackBase* GetCompletedCallback();
97 * Get the thread of the invocation callback
99 * @return the type of invocation callback.
101 ThreadType GetCallbackInvocationThread() const;
104 * Get the priority of this task
106 * @return the type of priority.
108 PriorityType GetPriorityType() const;
114 virtual ~AsyncTask() = default;
120 virtual void Process() = 0;
123 * Whether the task is ready to process.
125 * @return True if the task is ready to process.
127 virtual bool IsReady() = 0;
130 * Get the name of this task if we setup.
132 * @return The name of this task.
134 virtual std::string_view GetTaskName() const
136 Dali::DaliPrintBackTrace();
141 std::unique_ptr<CallbackBase> mCompletedCallback;
142 const PriorityType mPriorityType;
143 ThreadType mThreadType;
146 AsyncTask(const AsyncTask& task) = delete;
149 AsyncTask& operator=(const AsyncTask& task) = delete;
153 * The manager for async task
156 class DALI_ADAPTOR_API AsyncTaskManager : public BaseHandle
172 * @brief Gets the singleton of AsyncTaskManager object.
175 * @return A handle to the AsyncTaskManager
177 static AsyncTaskManager Get();
180 * @brief Add the async task into the waiting queue, called by main thread.
183 * @param[in] task The task added to the queue.
185 void AddTask(AsyncTaskPtr task);
188 * @brief Remove the task from the waiting queue, called by main thread.
191 * @param[in] task The task pointer.
193 void RemoveTask(AsyncTaskPtr task);
196 using TasksCompletedId = uint32_t;
198 enum CompletedCallbackTraceMask
200 THREAD_MASK_MAIN = 1u << 0, ///< Trace only main thread tasks.
201 THREAD_MASK_WORKER = 1u << 1, ///< Trace only worker thread tasks.
203 PRIORITY_MASK_HIGH = 1u << 2, ///< Trace only high priority tasks.
204 PRIORITY_MASK_LOW = 1u << 3, ///< Trace only low priority tasks.
206 THREAD_MASK_ALL = THREAD_MASK_MAIN | THREAD_MASK_WORKER,
207 PRIORITY_MASK_ALL = PRIORITY_MASK_HIGH | PRIORITY_MASK_LOW,
209 // Useful preset of task mask.
211 MAIN_THREAD_TASKS = THREAD_MASK_MAIN | PRIORITY_MASK_ALL,
212 WORKER_THREAD_TASKS = THREAD_MASK_WORKER | PRIORITY_MASK_ALL,
213 HIGH_PRIORITY_TASKS = THREAD_MASK_ALL | PRIORITY_MASK_HIGH,
214 LOW_PRIORITY_TASKS = THREAD_MASK_ALL | PRIORITY_MASK_LOW,
216 MAIN_THREAD_HIGH_PRIORITY_TASKS = THREAD_MASK_MAIN | PRIORITY_MASK_HIGH,
217 MAIN_THREAD_LOW_PRIORITY_TASKS = THREAD_MASK_MAIN | PRIORITY_MASK_LOW,
219 ALL_TASKS = THREAD_MASK_ALL | PRIORITY_MASK_ALL,
225 * @brief Set the async tasks completed callback.
226 * Inputed callback will be emitted after all tasks what user added are completed.
230 * void OnTasksCompleted(TasksCompletedId id);
231 * auto id0 = AsyncTaskManager::Get().SetCompletedCallback(MakeCallback(OnTasksCompleted), CompletedCallbackTraceMask::MASK_ALL);
232 * // OnTasksCompleted(id0); called at next Idler.
234 * AsyncTaskManager::Get().AddTask(task1);
235 * auto id1 = AsyncTaskManager::Get().SetCompletedCallback(MakeCallback(OnTasksCompleted), CompletedCallbackTraceMask::MASK_ALL);
236 * // OnTasksCompleted(id1); called after task1 completed.
238 * AsyncTaskManager::Get().AddTask(task2WhichIsLowPriority);
239 * AsyncTaskManager::Get().AddTask(task3WhichIsWorkerThread);
240 * AsyncTaskManager::Get().AddTask(task4);
241 * auto id2 = AsyncTaskManager::Get().SetCompletedCallback(MakeCallback(OnTasksCompleted), static_cast<CompletedCallbackTraceMask>(CompletedCallbackTraceMask::THREAD_MASK_MAIN | CompletedCallbackTraceMask::PRIORITY_MASK_HIGH));
242 * // OnTasksCompleted(id2); called after task1 and task4 completed.
244 * AsyncTaskManager::Get().RemoveCompletedCallback(id1);
245 * // OnTasksCompleted(id1); will not be called.
247 * @note The ownership of callback will be hold AsyncTaskManager itself.
248 * @note The callback will be emmited at Process() timming.
251 * @param[in] callback The callback base when all AsyncTasks completed.
252 * This callback will be void return, and single input argument ; TasksCompletedId.
253 * @param[in] mask Mask info s.t. what kind of async task we want to detact.
254 * For example, if we set this value as MASK_ALL & ~PRIORITY_MASK_LOW, we will ignore low priority tasks.
255 * Default is MASK_ALL.
256 * @return The unique id for callback. It can be used when we want to remove callback.
258 TasksCompletedId SetCompletedCallback(CallbackBase* callback, CompletedCallbackTraceMask mask = CompletedCallbackTraceMask::DEFAULT);
261 * @brief Remove the async tasks completed callback.
262 * @note It will not execute setted callback.
265 * @param[in] tasksCompletedId The id for callback that want to remove.
266 * @return True if we success to removed. False if it already removed, or callback already emitted.
268 bool RemoveCompletedCallback(TasksCompletedId tasksCompletedId);
273 * @brief Allows the creation of a AsyncTaskManager handle from an internal pointer.
275 * @note Not intended for application developers
277 * @param[in] impl A pointer to the object
279 explicit DALI_INTERNAL AsyncTaskManager(Internal::Adaptor::AsyncTaskManager* impl);