git subrepo clone https://github.com/libretro/libretro-common.git deps/libretro-common
[pcsx_rearmed.git] / deps / libretro-common / include / queues / task_queue.h
1 /* Copyright  (C) 2010-2020 The RetroArch team
2  *
3  * ---------------------------------------------------------------------------------------
4  * The following license statement only applies to this file (task_queue.h).
5  * ---------------------------------------------------------------------------------------
6  *
7  * Permission is hereby granted, free of charge,
8  * to any person obtaining a copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
11  * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
16  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22
23 #ifndef __LIBRETRO_SDK_TASK_QUEUE_H__
24 #define __LIBRETRO_SDK_TASK_QUEUE_H__
25
26 #include <stdint.h>
27 #include <stddef.h>
28 #include <boolean.h>
29
30 #include <retro_common.h>
31 #include <retro_common_api.h>
32
33 #include <libretro.h>
34
35 RETRO_BEGIN_DECLS
36
37 enum task_type
38 {
39    TASK_TYPE_NONE,
40    /* Only one blocking task can exist in the queue at a time.
41     * Attempts to add a new one while another is running is
42     * ignored.
43     */
44    TASK_TYPE_BLOCKING
45 };
46
47 typedef struct retro_task retro_task_t;
48 typedef void (*retro_task_callback_t)(retro_task_t *task,
49       void *task_data,
50       void *user_data, const char *error);
51
52 typedef void (*retro_task_handler_t)(retro_task_t *task);
53
54 typedef bool (*retro_task_finder_t)(retro_task_t *task,
55       void *userdata);
56
57 typedef void (*retro_task_queue_msg_t)(retro_task_t *task,
58       const char *msg,
59       unsigned prio, unsigned duration, bool flush);
60
61 typedef bool (*retro_task_retriever_t)(retro_task_t *task, void *data);
62
63 typedef bool (*retro_task_condition_fn_t)(void *data);
64
65 typedef struct
66 {
67    char *source_file;
68 } decompress_task_data_t;
69
70 struct retro_task
71 {
72    /* when the task should run (0 for as soon as possible) */
73    retro_time_t when;
74
75    retro_task_handler_t  handler;
76
77    /* always called from the main loop */
78    retro_task_callback_t callback;
79
80    /* task cleanup handler to free allocated resources, will
81     * be called immediately after running the main callback */
82    retro_task_handler_t cleanup;
83
84    /* created by the handler, destroyed by the user */
85    void *task_data;
86
87    /* owned by the user */
88    void *user_data;
89
90    /* created and destroyed by the code related to the handler */
91    void *state;
92
93    /* created by task handler; destroyed by main loop
94     * (after calling the callback) */
95    char *error;
96
97    void (*progress_cb)(retro_task_t*);
98
99    /* handler can modify but will be
100     * free()d automatically if non-NULL. */
101    char *title;
102
103    /* frontend userdata
104     * (e.g. associate a sticky notification to a task) */
105    void *frontend_userdata;
106
107    /* don't touch this. */
108    retro_task_t *next;
109
110    /* -1 = unmetered/indeterminate, 0-100 = current progress percentage */
111    int8_t progress;
112
113    /* task identifier */
114    uint32_t ident;
115
116    enum task_type type;
117
118    /* if set to true, frontend will
119    use an alternative look for the
120    task progress display */
121    bool alternative_look;
122
123    /* set to true by the handler to signal
124     * the task has finished executing. */
125    bool finished;
126
127    /* set to true by the task system
128     * to signal the task *must* end. */
129    bool cancelled;
130
131    /* if true no OSD messages will be displayed. */
132    bool mute;
133 };
134
135 typedef struct task_finder_data
136 {
137    retro_task_finder_t func;
138    void *userdata;
139 } task_finder_data_t;
140
141 typedef struct task_retriever_info
142 {
143    struct task_retriever_info *next;
144    void *data;
145 } task_retriever_info_t;
146
147 typedef struct task_retriever_data
148 {
149    task_retriever_info_t *list;
150    retro_task_handler_t handler;
151    retro_task_retriever_t func;
152    size_t element_size;
153 } task_retriever_data_t;
154
155 void *task_queue_retriever_info_next(task_retriever_info_t **link);
156
157 void task_queue_retriever_info_free(task_retriever_info_t *list);
158
159 /**
160  * Signals a task to end without waiting for
161  * it to complete. */
162 void task_queue_cancel_task(void *task);
163
164 void task_set_finished(retro_task_t *task, bool finished);
165
166 void task_set_mute(retro_task_t *task, bool mute);
167
168 void task_set_error(retro_task_t *task, char *error);
169
170 void task_set_progress(retro_task_t *task, int8_t progress);
171
172 void task_set_title(retro_task_t *task, char *title);
173
174 void task_set_data(retro_task_t *task, void *data);
175
176 void task_set_cancelled(retro_task_t *task, bool cancelled);
177
178 void task_free_title(retro_task_t *task);
179
180 bool task_get_cancelled(retro_task_t *task);
181
182 bool task_get_finished(retro_task_t *task);
183
184 bool task_get_mute(retro_task_t *task);
185
186 char* task_get_error(retro_task_t *task);
187
188 int8_t task_get_progress(retro_task_t *task);
189
190 char* task_get_title(retro_task_t *task);
191
192 void* task_get_data(retro_task_t *task);
193
194 bool task_is_on_main_thread(void);
195
196 void task_queue_set_threaded(void);
197
198 void task_queue_unset_threaded(void);
199
200 bool task_queue_is_threaded(void);
201
202 /**
203  * Calls func for every running task
204  * until it returns true.
205  * Returns a task or NULL if not found.
206  */
207 bool task_queue_find(task_finder_data_t *find_data);
208
209 /**
210  * Calls func for every running task when handler
211  * parameter matches task handler, allowing the
212  * list parameter to be filled with user-defined
213  * data.
214  */
215 void task_queue_retrieve(task_retriever_data_t *data);
216
217  /* Checks for finished tasks
218   * Takes the finished tasks, if any,
219   * and runs their callbacks.
220   * This must only be called from the main thread. */
221 void task_queue_check(void);
222
223 /* Pushes a task
224  * The task will start as soon as possible.
225  * If a second blocking task is attempted, false will be returned
226  * and the task will be ignored. */
227 bool task_queue_push(retro_task_t *task);
228
229 /* Blocks until all non-scheduled tasks have finished.
230  * Will return early if cond is not NULL
231  * and cond(data) returns false.
232  * This must only be called from the main thread. */
233 void task_queue_wait(retro_task_condition_fn_t cond, void* data);
234
235 /* Sends a signal to terminate all the tasks.
236  *
237  * This won't terminate the tasks immediately.
238  * They will finish as soon as possible.
239  *
240  * This must only be called from the main thread. */
241 void task_queue_reset(void);
242
243 /* Deinitializes the task system.
244  * This deinitializes the task system.
245  * The tasks that are running at
246  * the moment will stay on hold */
247 void task_queue_deinit(void);
248
249 /* Initializes the task system.
250  * This initializes the task system
251  * and chooses an appropriate
252  * implementation according to the settings.
253  *
254  * This must only be called from the main thread. */
255 void task_queue_init(bool threaded, retro_task_queue_msg_t msg_push);
256
257 /* Allocates and inits a new retro_task_t */
258 retro_task_t *task_init(void);
259
260 RETRO_END_DECLS
261
262 #endif