Example #1
0
File: timer.c Project: fshunj/LCUI
/** 更新定时器在定时器列表中的位置 */
static void TimerList_UpdateTimerPos(	LCUI_Queue *timer_list,
					timer_data *p_timer )
{
	int n, src_i=-1, des_i=-1;
	int64_t time_left, tmp_time_left;
	timer_data *p_tmp_timer;
	/* 计算该定时器的剩余定时时长 */
	time_left = LCUI_GetTicks( p_timer->start_time );
	time_left -= p_timer->pause_ms;
	time_left = p_timer->total_ms - time_left;
	/* 锁上定时器列表 */
	Queue_Lock( &global_timer_list );
	n = Queue_GetTotal( &global_timer_list );
	while(n--) {
		p_tmp_timer = (timer_data*)Queue_Get( &global_timer_list, n );
		if( !p_tmp_timer ) {
			continue;
		}
		/* 若找到自己的位置,则记录 */
		if( p_tmp_timer->id == p_timer->id ) {
			src_i = n;
			/* 如果已经找到目标位置,则退出循环 */
			if( des_i != -1 ) {
				break;
			}
			continue;
		}
		tmp_time_left = LCUI_GetTicks( p_tmp_timer->start_time );
		tmp_time_left -= p_tmp_timer->pause_ms;
		tmp_time_left = p_tmp_timer->total_ms - tmp_time_left;
		/* 若该定时器的剩余定时时长不大于当前定时器,则记录 */
		if( des_i == -1 && time_left >= tmp_time_left ) {
			DEBUG_MSG("src timer: %d, pos: %d, , cur_ms: %I64dms, des timer: %d, pos: %d, cur_ms: %I64dms\n",
				p_timer->id, src_i, LCUI_GetTicks(p_timer->start_time), 
				p_tmp_timer->id, des_i, LCUI_GetTicks(p_tmp_timer->start_time) );
			des_i = n;
			/* 如果已经找到源位置,则退出循环 */
			if( src_i != -1 ) {
				break;
			}
		}
	}
	/* 若目标位置无效,则将末尾作为目标位置 */
	if( des_i == -1 ) {
		DEBUG_MSG("tip\n");
		des_i = Queue_GetTotal( &global_timer_list )-1;
	}
	/* 若源位置和目标位置有效,则开始移动 */
	if( src_i != -1 ) {
		DEBUG_MSG("src: %d, des: %d\n", src_i, des_i );
		Queue_Move( &global_timer_list, des_i, src_i );
	}
	Queue_Unlock( &global_timer_list );
}
Example #2
0
File: timer.c Project: fshunj/LCUI
/**
 * 继续定时器的倒计时
 * @param timer_id
 *	目标定时器的标识符
 * @return
 *	正常返回0,指定ID的定时器不存在则返回-1.
 * */
LCUI_API int LCUITimer_Continue( int timer_id )
{
	timer_data *timer;
	
	LCUISleeper_BreakSleep( &timer_sleeper );
	Queue_Lock( &global_timer_list );
	timer = TimerList_Find( timer_id );
	if( timer ) {
		/* 计算处于暂停状态的时长 */
		timer->pause_ms += (long int)LCUI_GetTicks( timer->pause_time );
		timer->state = STATE_RUN;
		Queue_Unlock( &global_timer_list );
		return 0;
	}
	Queue_Unlock( &global_timer_list );
	return -1;
}
Example #3
0
File: timer.c Project: fshunj/LCUI
/** 打印列表中的定时器信息 */
static void TimerList_Print( LCUI_Queue *timer_list )
{
	int i, total;
	timer_data *timer;

	total = Queue_GetTotal( timer_list );
	_DEBUG_MSG("timer list(%d) start:\n", total);
	for(i=0; i<total; ++i) {
		timer = (timer_data*)Queue_Get( timer_list , i);
		if( !timer ) {
			continue;
		}
		_DEBUG_MSG("[%02d] %d, cur_ms: %dms, total_ms: %dms\n",
			i, timer->id, timer->total_ms - (long int)LCUI_GetTicks(timer->start_time), timer->total_ms );
	}
	_DEBUG_MSG("timer list end\n\n");
}
Example #4
0
File: timer.c Project: fshunj/LCUI
/**
 * 设置定时器
 * 定时器的作用是让一个任务在经过指定时间后才执行
 * @param n_ms
 *	等待的时间,单位为毫秒
 * @param callback_func
 *	用于响应定时器的回调函数
 * @param reuse
 *	指示该定时器是否重复使用,如果要用于循环定时处理某些
 *	任务,可将它置为 TRUE,否则置于 FALSE。
 * @return
 *	该定时器的标识符
 * */
LCUI_API int LCUITimer_Set(	long int n_ms,
				void (*callback_func)(void*),
				void *arg,
				LCUI_BOOL reuse )
{
	int n;
	int64_t time_left;
	timer_data timer, *p_timer;
	static int id = 100;

	/* 打断定时器睡眠者的睡眠 */
	LCUISleeper_BreakSleep( &timer_sleeper );
	Queue_Lock( &global_timer_list );
	n = Queue_GetTotal( &global_timer_list );
	while(n--) {
		p_timer = (timer_data*)Queue_Get( &global_timer_list, n );
		if( !p_timer ) {
			continue;
		}
		time_left = LCUI_GetTicks( p_timer->start_time );
		time_left -= p_timer->pause_ms;
		time_left = p_timer->total_ms - time_left;
		if( time_left <= n_ms ) {
			break;
		}
	}

	timer.id = ++id;
	timer.app_id = LCUIApp_GetSelfID();
	timer.state = STATE_RUN;
	timer.reuse = reuse;
	timer.total_ms = n_ms;
	timer.pause_ms = 0;
	timer.start_time = LCUI_GetTickCount();
	timer.callback_func = callback_func;
	timer.arg = arg;

	Queue_Insert( &global_timer_list, n+1, &timer );
	Queue_Unlock( &global_timer_list );
	DEBUG_MSG("set timer, id: %d, total_ms: %d,app_id: %lu\n", timer.id, timer.total_ms, timer.app_id);
	return timer.id;
}
Example #5
0
/** 让当前帧停留一定时间 */
void FrameControl_Remain( FrameCtrlCtx ctx )
{
	unsigned int n_ms, lost_ms;
	int64_t current_time;
	
	if( ctx->state == FRAME_CTRL_STATE_QUIT ) {
		return;
	}
	current_time = LCUI_GetTickCount();
	n_ms = (int)(current_time - ctx->prev_frame_start_time);
	if( n_ms > ctx->one_frame_remain_time ) {
		goto normal_exit;
	}
	n_ms = ctx->one_frame_remain_time - n_ms;
	if( n_ms < 1 ) {
		goto normal_exit;
	}
	/* 进行睡眠,直到需要暂停为止 */
	LCUICond_TimedWait( &ctx->wait_pause, &ctx->mutex, n_ms );
	/* 睡眠结束后,如果当前状态不为PAUSE,则说明睡眠不是因为要暂停而终止的 */
	if( ctx->state != FRAME_CTRL_STATE_PAUSE ) {
		goto normal_exit;
	}
	current_time = LCUI_GetTickCount();
	/* 需要暂停,进行睡眠,直到需要继续为止 */
	LCUICond_Wait( &ctx->wait_continue, &ctx->mutex );
	lost_ms = (unsigned int)LCUI_GetTicks( current_time );
	ctx->pause_time = lost_ms;
	ctx->prev_frame_start_time += lost_ms;
	return;

normal_exit:;
	current_time = LCUI_GetTickCount();
	if( current_time - ctx->prev_fps_update_time >= 1000 ) {
		ctx->current_fps = ctx->temp_fps;
		ctx->prev_fps_update_time = current_time;
		ctx->temp_fps = 0;
	}
	ctx->prev_frame_start_time = current_time;
	++ctx->temp_fps;
}
Example #6
0
File: timer.c Project: fshunj/LCUI
/** 定时器线程,用于处理列表中各个定时器 */
static void TimerThread( void *arg )
{
	int i, n;
	long int n_ms;
	LCUI_Func func_data;
	LCUI_Queue *timer_list;
	timer_data *timer = NULL;
	int64_t lost_ms;

	timer_list = (LCUI_Queue*)arg;
	func_data.arg[0] = NULL;
	func_data.arg[1] = NULL;

	while( !LCUI_Active() ) {
		LCUI_MSleep(10);
	}
	while( timer_thread_active ) {
		Queue_Lock( timer_list );
		n = Queue_GetTotal( timer_list );
		for(i=0; i<n; ++i) {
			timer = (timer_data*)Queue_Get( timer_list , i);
			if( !timer ) {
				continue;
			}
			if( timer->state == STATE_RUN ) {
				break;
			}
		}
		Queue_Unlock( timer_list );
		/* 没有要处理的定时器,停留一段时间再进行下次循环 */
		if(i >= n || !timer ) {
			LCUI_MSleep(10);
			continue;
		}
		lost_ms = LCUI_GetTicks( timer->start_time );
		/* 减去处于暂停状态的时长 */
		lost_ms -= timer->pause_ms;
		/* 若流失的时间未达到总定时时长 */
		if( lost_ms < timer->total_ms ) {
			Queue_Lock( timer_list );
			n_ms = timer->total_ms - lost_ms;
			/* 开始睡眠 */
			LCUISleeper_StartSleep( &timer_sleeper, n_ms );
			Queue_Unlock( timer_list );
			lost_ms = LCUI_GetTicks( timer->start_time );
			lost_ms -= timer->pause_ms;
			if( lost_ms < timer->total_ms ) {
				continue;
			}
		}
		DEBUG_MSG("timer: %d, start_time: %I64dms, cur_time: %I64dms, cur_ms: %I64d, total_ms: %ld\n", 
			timer->id, timer->start_time, LCUI_GetTickCount(), timer->total_ms-lost_ms, timer->total_ms);
		/* 准备任务数据 */
		func_data.id = timer->app_id;
		func_data.func = (CallBackFunc)timer->callback_func;
		func_data.arg[0] = timer->arg;
		func_data.destroy_arg[0] = FALSE;
		/* 添加该任务至指定程序的任务队列,添加模式是覆盖 */
		AppTasks_CustomAdd( ADD_MODE_REPLACE | AND_ARG_F, &func_data );
		Queue_Lock( timer_list );
		/* 若需要重复使用,则重置剩余等待时间 */
		if( timer->reuse ) {
			timer->start_time = LCUI_GetTickCount();
			timer->pause_ms = 0;
			TimerList_UpdateTimerPos( timer_list, timer );
		} else { /* 否则,释放该定时器 */
			LCUITimer_Free( timer->id );
		}
		Queue_Unlock( timer_list );
	}
	LCUIThread_Exit(NULL);
}