Blender  V2.93
BLI_timer.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2018 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "BLI_timer.h"
25 #include "BLI_listbase.h"
26 
27 #include "MEM_guardedalloc.h"
28 #include "PIL_time.h"
29 
30 #define GET_TIME() PIL_check_seconds_timer()
31 
32 typedef struct TimedFunction {
33  struct TimedFunction *next, *prev;
36  void *user_data;
37  double next_time;
40  bool persistent;
42 
43 typedef struct TimerContainer {
46 
47 static TimerContainer GlobalTimer = {{0}};
48 
50  BLI_timer_func func,
51  void *user_data,
52  BLI_timer_data_free user_data_free,
53  double first_interval,
54  bool persistent)
55 {
56  TimedFunction *timed_func = MEM_callocN(sizeof(TimedFunction), __func__);
57  timed_func->func = func;
58  timed_func->user_data_free = user_data_free;
59  timed_func->user_data = user_data;
60  timed_func->next_time = GET_TIME() + first_interval;
61  timed_func->tag_removal = false;
62  timed_func->persistent = persistent;
63  timed_func->uuid = uuid;
64 
65  BLI_addtail(&GlobalTimer.funcs, timed_func);
66 }
67 
68 static void clear_user_data(TimedFunction *timed_func)
69 {
70  if (timed_func->user_data_free) {
71  timed_func->user_data_free(timed_func->uuid, timed_func->user_data);
72  timed_func->user_data_free = NULL;
73  }
74 }
75 
77 {
79  if (timed_func->uuid == uuid && !timed_func->tag_removal) {
80  timed_func->tag_removal = true;
81  clear_user_data(timed_func);
82  return true;
83  }
84  }
85  return false;
86 }
87 
89 {
91  if (timed_func->uuid == uuid && !timed_func->tag_removal) {
92  return true;
93  }
94  }
95  return false;
96 }
97 
99 {
100  double current_time = GET_TIME();
101 
102  LISTBASE_FOREACH (TimedFunction *, timed_func, &GlobalTimer.funcs) {
103  if (timed_func->tag_removal) {
104  continue;
105  }
106  if (timed_func->next_time > current_time) {
107  continue;
108  }
109 
110  double ret = timed_func->func(timed_func->uuid, timed_func->user_data);
111 
112  if (ret < 0) {
113  timed_func->tag_removal = true;
114  }
115  else {
116  timed_func->next_time = current_time + ret;
117  }
118  }
119 }
120 
121 static void remove_tagged_functions(void)
122 {
123  for (TimedFunction *timed_func = GlobalTimer.funcs.first; timed_func;) {
124  TimedFunction *next = timed_func->next;
125  if (timed_func->tag_removal) {
126  clear_user_data(timed_func);
127  BLI_freelinkN(&GlobalTimer.funcs, timed_func);
128  }
129  timed_func = next;
130  }
131 }
132 
134 {
137 }
138 
140 {
141  LISTBASE_FOREACH (TimedFunction *, timed_func, &GlobalTimer.funcs) {
142  timed_func->tag_removal = true;
143  }
144 
146 }
147 
149 {
150  LISTBASE_FOREACH (TimedFunction *, timed_func, &GlobalTimer.funcs) {
151  if (!timed_func->persistent) {
152  timed_func->tag_removal = true;
153  }
154  }
155 }
156 
158 {
160 }
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:281
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
#define GET_TIME()
Definition: BLI_timer.c:30
static TimerContainer GlobalTimer
Definition: BLI_timer.c:47
static void clear_user_data(TimedFunction *timed_func)
Definition: BLI_timer.c:68
bool BLI_timer_is_registered(uintptr_t uuid)
Definition: BLI_timer.c:88
void BLI_timer_register(uintptr_t uuid, BLI_timer_func func, void *user_data, BLI_timer_data_free user_data_free, double first_interval, bool persistent)
Definition: BLI_timer.c:49
static void remove_tagged_functions(void)
Definition: BLI_timer.c:121
static void execute_functions_if_necessary(void)
Definition: BLI_timer.c:98
struct TimerContainer TimerContainer
struct TimedFunction TimedFunction
bool BLI_timer_unregister(uintptr_t uuid)
Definition: BLI_timer.c:76
void BLI_timer_execute()
Definition: BLI_timer.c:133
static void remove_non_persistent_functions(void)
Definition: BLI_timer.c:148
void BLI_timer_free()
Definition: BLI_timer.c:139
void BLI_timer_on_file_load(void)
Definition: BLI_timer.c:157
void(* BLI_timer_data_free)(uintptr_t uuid, void *user_data)
Definition: BLI_timer.h:35
double(* BLI_timer_func)(uintptr_t uuid, void *user_data)
Definition: BLI_timer.h:34
Read Guarded memory(de)allocation.
Platform independent time functions.
void * user_data
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static ulong * next
return ret
_W64 unsigned int uintptr_t
Definition: stdint.h:122
void * first
Definition: DNA_listBase.h:47
BLI_timer_data_free user_data_free
Definition: BLI_timer.c:35
bool tag_removal
Definition: BLI_timer.c:39
double next_time
Definition: BLI_timer.c:37
void * user_data
Definition: BLI_timer.c:36
uintptr_t uuid
Definition: BLI_timer.c:38
bool persistent
Definition: BLI_timer.c:40
struct TimedFunction * prev
Definition: BLI_timer.c:33
struct TimedFunction * next
Definition: BLI_timer.c:33
BLI_timer_func func
Definition: BLI_timer.c:34
ListBase funcs
Definition: BLI_timer.c:44