mirror of
https://github.com/zlgopen/awtk.git
synced 2025-05-08 19:44:45 +08:00
135 lines
3.4 KiB
C
135 lines
3.4 KiB
C
/**
|
|
* File: timer.c
|
|
* Author: Li XianJing <xianjimli@hotmail.com>
|
|
* Brief: timer manager
|
|
*
|
|
* Copyright (c) 2018 - 2018 Li XianJing <xianjimli@hotmail.com>
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* License file for more details.
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* History:
|
|
* ================================================================
|
|
* 2018-02-22 Li XianJing <xianjimli@hotmail.com> created
|
|
*
|
|
*/
|
|
|
|
#include "base/timer.h"
|
|
#include "base/array.h"
|
|
#include "base/mem.h"
|
|
|
|
static uint32_t s_timer_id = 1;
|
|
static array_t* s_timer_manager = NULL;
|
|
static timer_get_time_t s_get_time = NULL;
|
|
|
|
ret_t timer_init(timer_get_time_t get_time) {
|
|
return_value_if_fail(get_time != NULL, RET_BAD_PARAMS);
|
|
|
|
s_get_time = get_time;
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
static ret_t ensure_timer_manager() {
|
|
if (s_timer_manager == NULL) {
|
|
s_timer_manager = array_create(5);
|
|
}
|
|
return_value_if_fail(s_timer_manager != NULL, RET_FAIL);
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
uint32_t timer_add(timer_func_t on_timer, void* ctx, uint32_t duration_ms) {
|
|
timer_info_t* timer = NULL;
|
|
return_value_if_fail(on_timer != NULL, 0);
|
|
return_value_if_fail(s_get_time != NULL && ensure_timer_manager() == RET_OK, 0);
|
|
|
|
timer = MEM_ZALLOC(timer_info_t);
|
|
return_value_if_fail(timer != NULL, 0);
|
|
|
|
timer->ctx = ctx;
|
|
timer->id = s_timer_id++;
|
|
timer->start = s_get_time();
|
|
timer->on_timer = on_timer;
|
|
timer->duration_ms = duration_ms;
|
|
|
|
return array_push(s_timer_manager, timer) ? timer->id : 0;
|
|
}
|
|
|
|
static int compare_timer(const void* a, const void* b) {
|
|
timer_info_t* t1 = (timer_info_t*)a;
|
|
timer_info_t* t2 = (timer_info_t*)b;
|
|
|
|
if (t1->id == t2->id) {
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
ret_t timer_remove(uint32_t timer_id) {
|
|
timer_info_t timer;
|
|
return_value_if_fail(timer_id > 0, RET_BAD_PARAMS);
|
|
return_value_if_fail(s_get_time != NULL && ensure_timer_manager() == RET_OK, RET_BAD_PARAMS);
|
|
|
|
timer.id = timer_id;
|
|
|
|
return array_remove(s_timer_manager, compare_timer, &timer) ? RET_OK : RET_FAIL;
|
|
}
|
|
|
|
const timer_info_t* timer_find(uint32_t timer_id) {
|
|
timer_info_t timer;
|
|
return_value_if_fail(timer_id > 0, NULL);
|
|
return_value_if_fail(s_get_time != NULL && ensure_timer_manager() == RET_OK, NULL);
|
|
|
|
timer.id = timer_id;
|
|
|
|
return (const timer_info_t*)array_find(s_timer_manager, compare_timer, &timer);
|
|
|
|
}
|
|
|
|
ret_t timer_check() {
|
|
uint32_t i = 0;
|
|
uint32_t k = 0;
|
|
uint32_t nr = 0;
|
|
uint32_t now = 0;
|
|
timer_info_t** timers = NULL;
|
|
return_value_if_fail(s_get_time != NULL && ensure_timer_manager() == RET_OK, RET_BAD_PARAMS);
|
|
|
|
if (s_timer_manager->size == 0) {
|
|
return RET_OK;
|
|
}
|
|
|
|
now = s_get_time();
|
|
timers = (timer_info_t**)s_timer_manager->elms;
|
|
for (i = 0, nr = s_timer_manager->size; i < nr; i++) {
|
|
timer_info_t* iter = timers[i];
|
|
if ((iter->start + iter->duration_ms) <= now) {
|
|
iter->repeat = RET_REPEAT == iter->on_timer(iter);
|
|
if (iter->repeat) {
|
|
iter->start = now;
|
|
}
|
|
} else {
|
|
iter->repeat = TRUE;
|
|
}
|
|
}
|
|
|
|
for (k = 0, i = 0, nr = s_timer_manager->size; i < nr; i++) {
|
|
timer_info_t* iter = timers[i];
|
|
if (iter->repeat) {
|
|
timers[k++] = timers[i];
|
|
}
|
|
}
|
|
s_timer_manager->size = k;
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
uint32_t timer_count() { return ensure_timer_manager() == RET_OK ? s_timer_manager->size : 0; }
|
|
|