Exemplo n.º 1
0
void FrameControl_Remain( FrameControl ctx )
{
	int64_t current_time;
	unsigned int n_ms, lost_ms;

	if( ctx->state == STATE_QUIT ) {
		return;
	}
	lost_ms = 0;
	current_time = LCUI_GetTime();
	LCUIMutex_Lock( &ctx->mutex );
	n_ms = (unsigned 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;
	}
	/* 睡眠一段时间 */
	while( lost_ms < n_ms && ctx->state == STATE_RUN ) {
		LCUICond_TimedWait( &ctx->cond, &ctx->mutex, n_ms - lost_ms );
		lost_ms = (unsigned int)LCUI_GetTimeDelta( current_time );
	}
	/* 睡眠结束后,如果当前状态为 PAUSE,则说明睡眠是因为要暂停而终止的 */
	if( ctx->state == STATE_PAUSE ) {
		current_time = LCUI_GetTime();
		/* 等待状态改为“继续” */
		while( ctx->state == STATE_PAUSE ) {
			LCUICond_Wait( &ctx->cond, &ctx->mutex );
		}
		lost_ms = (unsigned int)LCUI_GetTimeDelta( current_time );
		ctx->pause_time = lost_ms;
		ctx->prev_frame_start_time += lost_ms;
		LCUIMutex_Unlock( &ctx->mutex );
		return;
	}

normal_exit:;
	current_time = LCUI_GetTime();
	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;
	LCUIMutex_Unlock( &ctx->mutex );
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
/** 运行目标主循环 */
int LCUI_MainLoop_Run( LCUI_MainLoop loop )
{
	if( loop->state == STATE_RUNNING ) {
		_DEBUG_MSG("error: main-loop already running.");
		return -1;
	}
	DEBUG_MSG("loop: %p, enter\n", loop);
	loop->state = STATE_RUNNING;
	/* 将主循环记录插入至列表表头 */
	LinkedList_Goto( &MainApp.loop_list, 0 );
	LinkedList_Insert( &MainApp.loop_list, loop );
	MainApp.loop = loop;
	LCUIMutex_Lock( &MainApp.loop_changed );
	/* 广播,让其它线程交出主循环运行权 */
	LCUICond_Broadcast( &MainApp.loop_cond );
	/* 获取运行权 */
	LCUIMutex_Lock( &MainApp.loop_mutex );
	LCUIMutex_Unlock( &MainApp.loop_changed );
	loop->tid = LCUIThread_SelfID();
	while( loop->state != STATE_EXITED ) {
		if( LinkedList_GetTotal(&MainApp.task_list) <= 0 ) {
			DEBUG_MSG("loop: %p, sleeping...\n", loop);
			LCUICond_TimedWait( &MainApp.loop_cond, 1000 );
			DEBUG_MSG("loop: %p, wakeup\n", loop);
			/** 如果当前运行的主循环不是自己 */
			if( MainApp.loop != loop ) {
				loop->state = STATE_PAUSED;
				DEBUG_MSG("loop: %p, release control.\n", loop);
				LCUIMutex_Unlock( &MainApp.loop_mutex );
				/* 等待其它线程获得主循环运行权 */
				LCUIMutex_Lock( &MainApp.loop_changed );
				LCUIMutex_Unlock( &MainApp.loop_changed );
				DEBUG_MSG("loop: %p, waiting...\n", loop);
				/* 等待其它线程释放主循环运行权 */
				LCUIMutex_Lock( &MainApp.loop_mutex );
			}
			continue;
		}
		DEBUG_MSG("loop: %p, run task.\n", loop);
		LCUI_RunTask();
	}
	loop->state = STATE_EXITED;
	LinkedList_Goto( &MainApp.loop_list, 0 );
	LinkedList_Delete( &MainApp.loop_list );
	/* 获取处于列表表头的主循环 */
	loop = (LCUI_MainLoop)LinkedList_Get( &MainApp.loop_list );
	if( loop ) {
		/* 改变当前运行的主循环 */
		MainApp.loop = loop;
		LCUICond_Broadcast( &MainApp.loop_cond );
	}
	/* 释放运行权 */
	LCUIMutex_Unlock( &MainApp.loop_mutex );
	/* 如果列表为空,一般意味着LCUI需要退出了 */
	if( LinkedList_GetTotal( &MainApp.loop_list ) <= 0 ) {
		/** 广播,通知相关线程开始进行清理操作 */
		LCUICond_Broadcast( &MainApp.loop_list_empty );
	}
	DEBUG_MSG("loop: %p, exit\n", loop);
	return 0;
}