Use a shorter/simpler license convention, stops the header taking so much space. Follow the SPDX license specification: https://spdx.org/licenses - C/C++/objc/objc++ - Python - Shell Scripts - CMake, GNUmakefile While most of the source tree has been included - `./extern/` was left out. - `./intern/cycles` & `./intern/atomic` are also excluded because they use different header conventions. doc/license/SPDX-license-identifiers.txt has been added to list SPDX all used identifiers. See P2788 for the script that automated these edits. Reviewed By: brecht, mont29, sergey Ref D14069
145 lines
3.3 KiB
C
145 lines
3.3 KiB
C
/* SPDX-License-Identifier: GPL-2.0-or-later
|
|
* Copyright 2018 Blender Foundation. All rights reserved. */
|
|
|
|
/** \file
|
|
* \ingroup bli
|
|
*/
|
|
|
|
#include "BLI_timer.h"
|
|
#include "BLI_listbase.h"
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
#include "PIL_time.h"
|
|
|
|
#define GET_TIME() PIL_check_seconds_timer()
|
|
|
|
typedef struct TimedFunction {
|
|
struct TimedFunction *next, *prev;
|
|
BLI_timer_func func;
|
|
BLI_timer_data_free user_data_free;
|
|
void *user_data;
|
|
double next_time;
|
|
uintptr_t uuid;
|
|
bool tag_removal;
|
|
bool persistent;
|
|
} TimedFunction;
|
|
|
|
typedef struct TimerContainer {
|
|
ListBase funcs;
|
|
} TimerContainer;
|
|
|
|
static TimerContainer GlobalTimer = {{0}};
|
|
|
|
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)
|
|
{
|
|
TimedFunction *timed_func = MEM_callocN(sizeof(TimedFunction), __func__);
|
|
timed_func->func = func;
|
|
timed_func->user_data_free = user_data_free;
|
|
timed_func->user_data = user_data;
|
|
timed_func->next_time = GET_TIME() + first_interval;
|
|
timed_func->tag_removal = false;
|
|
timed_func->persistent = persistent;
|
|
timed_func->uuid = uuid;
|
|
|
|
BLI_addtail(&GlobalTimer.funcs, timed_func);
|
|
}
|
|
|
|
static void clear_user_data(TimedFunction *timed_func)
|
|
{
|
|
if (timed_func->user_data_free) {
|
|
timed_func->user_data_free(timed_func->uuid, timed_func->user_data);
|
|
timed_func->user_data_free = NULL;
|
|
}
|
|
}
|
|
|
|
bool BLI_timer_unregister(uintptr_t uuid)
|
|
{
|
|
LISTBASE_FOREACH (TimedFunction *, timed_func, &GlobalTimer.funcs) {
|
|
if (timed_func->uuid == uuid && !timed_func->tag_removal) {
|
|
timed_func->tag_removal = true;
|
|
clear_user_data(timed_func);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool BLI_timer_is_registered(uintptr_t uuid)
|
|
{
|
|
LISTBASE_FOREACH (TimedFunction *, timed_func, &GlobalTimer.funcs) {
|
|
if (timed_func->uuid == uuid && !timed_func->tag_removal) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static void execute_functions_if_necessary(void)
|
|
{
|
|
double current_time = GET_TIME();
|
|
|
|
LISTBASE_FOREACH (TimedFunction *, timed_func, &GlobalTimer.funcs) {
|
|
if (timed_func->tag_removal) {
|
|
continue;
|
|
}
|
|
if (timed_func->next_time > current_time) {
|
|
continue;
|
|
}
|
|
|
|
double ret = timed_func->func(timed_func->uuid, timed_func->user_data);
|
|
|
|
if (ret < 0) {
|
|
timed_func->tag_removal = true;
|
|
}
|
|
else {
|
|
timed_func->next_time = current_time + ret;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void remove_tagged_functions(void)
|
|
{
|
|
for (TimedFunction *timed_func = GlobalTimer.funcs.first; timed_func;) {
|
|
TimedFunction *next = timed_func->next;
|
|
if (timed_func->tag_removal) {
|
|
clear_user_data(timed_func);
|
|
BLI_freelinkN(&GlobalTimer.funcs, timed_func);
|
|
}
|
|
timed_func = next;
|
|
}
|
|
}
|
|
|
|
void BLI_timer_execute()
|
|
{
|
|
execute_functions_if_necessary();
|
|
remove_tagged_functions();
|
|
}
|
|
|
|
void BLI_timer_free()
|
|
{
|
|
LISTBASE_FOREACH (TimedFunction *, timed_func, &GlobalTimer.funcs) {
|
|
timed_func->tag_removal = true;
|
|
}
|
|
|
|
remove_tagged_functions();
|
|
}
|
|
|
|
static void remove_non_persistent_functions(void)
|
|
{
|
|
LISTBASE_FOREACH (TimedFunction *, timed_func, &GlobalTimer.funcs) {
|
|
if (!timed_func->persistent) {
|
|
timed_func->tag_removal = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void BLI_timer_on_file_load(void)
|
|
{
|
|
remove_non_persistent_functions();
|
|
}
|