/************************************************************************
 * AUTHOR: NiuJiuRu
 * FILENAME: swtimer.c
 * CONTENT: 定时器
 * NOTE:
 * HISTORY:
 * 1, [2010-09-14] created by NiuJiuRu
 ***********************************************************************/
#include "swapi.h"
#include "swmem.h"
#include "swthrd.h"
#include "swtimer.h"

typedef struct
{
	// 定时器的名称
	char name[32];
	// 定时器的间隔时间(ms)
	int period;
	// 定时器的线程句柄
	void *hThrd;
	// 定时器的(用户)回调函数
	PTimerProc proc;
	unsigned long wParam;
	unsigned long lParam;
} STimer;

// 匿名定时器计数器
static int s_nameless_timer_counter = 0;

// 定时器的节拍函数(线程回调)
static int TimerProc(unsigned long wParam, unsigned long lParam);

/* 创建定时器(ms), 成功后默认处于暂停状态 */
void *sw_timer_create(const char *name, int period, PTimerProc proc, unsigned long wParam, unsigned long lParam)
{
	STimer *t = NULL;
	
	t = (STimer *)sw_heap_malloc(sizeof(STimer));
	if(!t) goto ErrorP;
	
	memset(t, 0, sizeof(STimer));
	if(name) strncpy(t->name, name, sizeof(t->name)-1);
	else snprintf(t->name, sizeof(t->name)-1, "nameless%d timer", s_nameless_timer_counter++);
	t->period = period;
	t->proc = proc;
	t->wParam = wParam; t->lParam = lParam;
	t->hThrd = sw_thrd_create(t->name, THREAD_DEFAULT_PRIORITY, THREAD_DEFAULT_STACK_SIZE, TimerProc, (unsigned long)t, 0);
	if(!t->hThrd) goto ErrorP;
	
	return t;
	
ErrorP:
	sw_timer_destroy(t, 0);	
	return NULL;
}

/* 销毁定时器, 超时前尝试安全的销毁, 超时后则强制销毁 */
void sw_timer_destroy(void *hTimer, int timeout)
{
	STimer *t = (STimer *)hTimer;
	
	if(!t) return;
	
	if(t->hThrd)
	{
		sw_thrd_destroy(t->hThrd, timeout); // destroy thread
		t->hThrd = NULL;
	}
	
	sw_heap_free(t);
}

/* 暂停运行定时器 */
void sw_timer_pause(void *hTimer)
{
	STimer *t = (STimer *)hTimer;
	if(!t) return;
	if(t->hThrd) sw_thrd_pause(t->hThrd);
}

/* 继续运行定时器 */
void sw_timer_resume(void *hTimer)
{
	STimer *t = (STimer *)hTimer;
	if(!t) return;
	if(t->hThrd) sw_thrd_resume(t->hThrd);
}

/* 设置定时器的节拍时间(ms) */
void sw_timer_setPeriod(void *hTimer, int period)
{
	STimer *t = (STimer *)hTimer;
	if(!t) return;
	t->period = period;
}

// 定时器的节拍函数
static int TimerProc(unsigned long wParam, unsigned long lParam)
{
	STimer *t = (STimer *)wParam;
	if(!sw_thrd_isAlive(t->hThrd)) return -1;
	if(t->proc) t->proc(t->wParam, t->lParam); // 执行定时器的节拍回调函数
	return t->period;
}
