void FrameControl_Pause( FrameControl ctx, LCUI_BOOL need_pause ) { if( ctx->state == STATE_RUN && need_pause ) { LCUIMutex_Lock( &ctx->mutex ); ctx->state = STATE_PAUSE; LCUICond_Signal( &ctx->cond ); LCUIMutex_Unlock( &ctx->mutex ); } else if( ctx->state == STATE_PAUSE && !need_pause ) { LCUIMutex_Lock( &ctx->mutex ); ctx->state = STATE_RUN; LCUICond_Signal( &ctx->cond ); LCUIMutex_Unlock( &ctx->mutex ); } }
void StepTimer_Pause( StepTimer timer, LCUI_BOOL need_pause ) { if( timer->state == STATE_RUN && need_pause ) { LCUIMutex_Lock( &timer->mutex ); timer->state = STATE_PAUSE; LCUICond_Signal( &timer->cond ); LCUIMutex_Unlock( &timer->mutex ); } else if( timer->state == STATE_PAUSE && !need_pause ) { LCUIMutex_Lock( &timer->mutex ); timer->state = STATE_RUN; LCUICond_Signal( &timer->cond ); LCUIMutex_Unlock( &timer->mutex ); } }
/** 暂停数据帧的更新 */ void FrameControl_Pause( FrameCtrlCtx ctx, LCUI_BOOL need_pause ) { if( ctx->state == FRAME_CTRL_STATE_RUN && need_pause ) { LCUIMutex_Lock( &ctx->mutex ); ctx->state = FRAME_CTRL_STATE_PAUSE; LCUICond_Signal( &ctx->wait_pause ); LCUIMutex_Unlock( &ctx->mutex ); } else if( ctx->state == FRAME_CTRL_STATE_PAUSE && !need_pause ){ LCUIMutex_Lock( &ctx->mutex ); ctx->state = FRAME_CTRL_STATE_RUN; LCUICond_Signal( &ctx->wait_continue ); LCUIMutex_Unlock( &ctx->mutex ); } }
LCUI_API void Graph_Free( LCUI_Graph *pic ) { LCUI_Graph *p; if( pic && pic->quote ) { pic->src = NULL; pic->quote = FALSE; return; } p = Graph_GetQuote( pic ); if( !Graph_IsValid(p)) { return; } LCUIMutex_Lock( &p->mutex ); free( p->rgba[0] ); free( p->rgba[1] ); free( p->rgba[2] ); if( p->color_type == COLOR_TYPE_RGBA ) { free( p->rgba[3] ); } free( p->rgba ); p->rgba = NULL; p->w = 0; p->h = 0; LCUIMutex_Unlock( &p->mutex ); LCUIMutex_Destroy( &pic->mutex ); }
/** 添加已被按下的按键 */ void LCUIKeyboard_HitKey(int key_code) { clock_t ct; KeyStateNode node; LCUIMutex_Lock(&self.mutex); ct = clock() * 1000 / CLOCKS_PER_SEC; node = RBTree_GetData(&self.state_tree, key_code); if (!node) { node = NEW(KeyStateNodeRec, 1); node->interval_time = -1; node->hit_time = ct; node->state = LCUI_KSTATE_PRESSED; RBTree_Insert(&self.state_tree, key_code, node); LCUIMutex_Unlock(&self.mutex); return; } if (node->state == LCUI_KSTATE_RELEASE) { node->state = LCUI_KSTATE_PRESSED; /* 记录与上次此键被按下时的时间间隔 */ node->interval_time = ct - node->hit_time; /* 记录本次此键被按下时的时间 */ node->hit_time = ct; } LCUIMutex_Unlock(&self.mutex); }
/** 添加已被按下的按键 */ void LCUIKeyBoard_HitKey( int key_code ) { clock_t ct; key_state data, *data_ptr; LCUIMutex_Lock( &record_mutex ); ct = clock()*1000 / CLOCKS_PER_SEC; data_ptr = KeyStateRecord_FindData( key_code ); if( !data_ptr ) { data.key_code = key_code; data.interval_time = -1; data.hit_time = ct; data.state = LCUIKEYSTATE_PRESSED; LinkedList_AddDataCopy( &key_state_record, &data ); LCUIMutex_Unlock( &record_mutex ); return; } if( data_ptr->state == LCUIKEYSTATE_RELEASE ) { data_ptr->state = LCUIKEYSTATE_PRESSED; /* 记录与上次此键被按下时的时间间隔 */ data_ptr->interval_time = ct - data_ptr->hit_time; /* 记录本次此键被按下时的时间 */ data_ptr->hit_time = ct; } LCUIMutex_Unlock( &record_mutex ); }
static void TestWorker_Send( TestWorker worker, const char *data ) { LCUIMutex_Lock( &worker->mutex ); strcpy( worker->data, data ); LCUICond_Signal( &worker->cond ); LCUIMutex_Unlock( &worker->mutex ); }
/** 设备处理线程 */ static void DeviceThread( void *arg ) { DeviceData *data_ptr; int n, i, timeout_count = 0; is_running = TRUE; while( is_running ) { LCUIMutex_Lock( &list_mutex ); n = LinkedList_GetTotal( &dev_list ); for( i=0; i<n; ++i ) { data_ptr = (DeviceData*)LinkedList_Get( &dev_list ); if( !data_ptr || !data_ptr->proc ) { continue; } if( data_ptr->proc() ) { ++timeout_count; } } LCUIMutex_Unlock( &list_mutex ); if( timeout_count > 20 ) { LCUI_MSleep( 10 ); timeout_count = 0; } LCUI_MSleep( 5 ); } LCUIThread_Exit(NULL); }
static int LCUI_RunTask(void) { LCUI_Task *task, task_bak; LCUIMutex_Lock( &MainApp.task_run_mutex ); LCUIMutex_Lock( &MainApp.task_list_mutex ); task = (LCUI_Task*)LinkedList_Get( &MainApp.task_list ); if( !task ) { LCUIMutex_Unlock( &MainApp.task_list_mutex ); LCUIMutex_Unlock( &MainApp.task_run_mutex ); return -1; } if( !task->func ) { LinkedList_Delete( &MainApp.task_list ); LCUIMutex_Unlock( &MainApp.task_list_mutex ); LCUIMutex_Unlock( &MainApp.task_run_mutex ); return -2; } /* 备份该任务数据 */ task_bak = *task; /* 重置数据 */ task->func = NULL; task->arg[0] = NULL; task->arg[1] = NULL; task->destroy_arg[0] = FALSE; task->destroy_arg[1] = FALSE; /* 删除之 */ LinkedList_Delete( &MainApp.task_list ); /* 解锁,现在的任务数据已经与任务列表独立开了 */ LCUIMutex_Unlock( &MainApp.task_list_mutex ); /* 调用函数指针指向的函数,并传递参数 */ task_bak.func( task_bak.arg[0], task_bak.arg[1] ); /* 若需要在调用回调函数后销毁参数 */ if( task_bak.destroy_arg[0] && task_bak.arg[0] ) { if( task_bak.destroy_func[0] ) { task_bak.destroy_func[0]( task_bak.arg[0] ); } free( task_bak.arg[0] ); } if( task_bak.destroy_arg[1] && task_bak.arg[1] ) { if( task_bak.destroy_func[1] ) { task_bak.destroy_func[1]( task_bak.arg[1] ); } free( task_bak.arg[1] ); } LCUIMutex_Unlock( &MainApp.task_run_mutex ); return 0; }
/** 标记指定键值的按键已释放 */ void LCUIKeyboard_ReleaseKey(int key_code) { KeyStateNode node; LCUIMutex_Lock(&self.mutex); node = RBTree_GetData(&self.state_tree, key_code); if (node) { node->state = LCUI_KSTATE_RELEASE; } LCUIMutex_Unlock(&self.mutex); }
void LCUIWorker_PostTask( LCUI_Worker worker, LCUI_Task task ) { LCUI_Task newtask; newtask = NEW( LCUI_TaskRec, 1 ); *newtask = *task; LCUIMutex_Lock( &worker->mutex ); LinkedList_Append( &worker->tasks, newtask ); LCUICond_Signal( &worker->cond ); LCUIMutex_Unlock( &worker->mutex ); }
/** 标记指定键值的按键已释放 */ void LCUIKeyBoard_ReleaseKey( int key_code ) { key_state *data_ptr; LCUIMutex_Lock( &record_mutex ); data_ptr = KeyStateRecord_FindData( key_code ); if( data_ptr ) { data_ptr->state = LCUIKEYSTATE_RELEASE; } LCUIMutex_Unlock( &record_mutex ); }
static void TestWorker_Destroy( TestWorker worker ) { LCUIMutex_Lock( &worker->mutex ); worker->active = FALSE; LCUICond_Signal( &worker->cond ); LCUIMutex_Unlock( &worker->mutex ); LCUIThread_Join( worker->thread, NULL ); LCUIMutex_Destroy( &worker->mutex ); LCUICond_Destroy( &worker->cond ); }
/** 添加任务 */ int LCUI_AddTask( LCUI_Task *task ) { LCUIMutex_Lock( &MainApp.task_list_mutex ); if( !LinkedList_AppendCopy( &MainApp.task_list, task ) ) { LCUIMutex_Unlock( &MainApp.task_list_mutex ); return -2; } LCUIMutex_Unlock( &MainApp.task_list_mutex ); LCUICond_Broadcast( &MainApp.loop_cond ); return 0; }
/** 检测指定键值的按键是否处于按下状态 */ LCUI_BOOL LCUIKey_IsHit( int key_code ) { KeyState *state_ptr; LCUIMutex_Lock( &record_mutex ); state_ptr = GetKeySate( key_code ); LCUIMutex_Unlock( &record_mutex ); if( state_ptr && state_ptr->state == LCUIKEYSTATE_PRESSED ) { return TRUE; } return FALSE; }
/** 检测指定键值的按键是否处于按下状态 */ LCUI_BOOL LCUIKey_IsHit( int key_code ) { key_state *data_ptr; LCUIMutex_Lock( &record_mutex ); data_ptr = KeyStateRecord_FindData( key_code ); LCUIMutex_Unlock( &record_mutex ); if( data_ptr && data_ptr->state == LCUIKEYSTATE_PRESSED ) { return TRUE; } return FALSE; }
/** 检测指定键值的按键是否处于按下状态 */ LCUI_BOOL LCUIKeyboard_IsHit(int key_code) { KeyStateNode node; LCUIMutex_Lock(&self.mutex); node = RBTree_GetData(&self.state_tree, key_code); LCUIMutex_Unlock(&self.mutex); if (node && node->state == LCUI_KSTATE_PRESSED) { return TRUE; } return FALSE; }
/** LCUI的图形显示处理线程 */ static void LCUIDisplay_Thread( void *unused ) { while( LCUI_IsActive() && display.is_working ) { LCUICursor_UpdatePos(); /* 更新鼠标位置 */ LCUIWidget_StepTask(); /* 处理所有部件任务 */ LCUIMutex_Lock( &display.mutex ); LCUIDisplay_Update(); LCUIMutex_Unlock( &display.mutex ); /* 让本帧停留一段时间 */ FrameControl_Remain( display.fc_ctx ); } LCUIThread_Exit(NULL); }
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 ); }
static void TestWorker_Thread( void *arg ) { TestWorker worker = arg; worker->active = TRUE; worker->data_count = 0; LCUIMutex_Lock( &worker->mutex ); while( worker->active ) { TEST_LOG( "waiting...\n" ); LCUICond_Wait( &worker->cond, &worker->mutex ); TEST_LOG( "get data: %s\n", worker->data ); worker->data_count += 1; } LCUIMutex_Unlock( &worker->mutex ); TEST_LOG( "count: %lu\n", worker->data_count ); }
/** 新建帧数控制实例 */ FrameCtrlCtx FrameControl_Create( void ) { FrameCtrlCtx ctx; ctx = (FrameCtrlCtx)malloc(sizeof(struct FrameControlContext)); ctx->temp_fps = 0; ctx->current_fps = 0; ctx->pause_time = 0; ctx->one_frame_remain_time = 10; ctx->prev_frame_start_time = LCUI_GetTickCount(); ctx->prev_fps_update_time = LCUI_GetTickCount(); LCUICond_Init( &ctx->wait_continue ); LCUICond_Init( &ctx->wait_pause ); LCUIMutex_Init( &ctx->mutex ); LCUIMutex_Lock( &ctx->mutex ); return ctx; }
/* 添加键盘的按键按下事件 */ void LCUI_PostKeyDownEvent( int key_code ) { key_state *data_ptr; LCUI_SystemEvent event; LCUIMutex_Lock( &record_mutex ); data_ptr = KeyStateRecord_FindData( key_code ); LCUIMutex_Unlock( &record_mutex ); /* 已经按下过的按键就不用再触发KEYDOWN事件了 */ if( data_ptr && data_ptr->state == LCUIKEYSTATE_PRESSED ) { return; } event.type = LCUI_KEYDOWN; event.which = key_code; LCUIKeyBoard_HitKey( key_code ); LCUI_PostEvent( "keydown", &event ); }
void LCUIWorker_Destroy( LCUI_Worker worker ) { if( worker->thread != 0 ) { LOG( "[worker] worker %u is stopping...\n", worker->thread ); LCUIMutex_Lock( &worker->mutex ); worker->active = FALSE; LCUICond_Signal( &worker->cond ); LCUIMutex_Unlock( &worker->mutex ); LCUIThread_Join( worker->thread, NULL ); LOG( "[worker] worker %u has stopped\n", worker->thread ); worker->thread = 0; } LCUIMutex_Destroy( &worker->mutex ); LCUICond_Destroy( &worker->cond ); LinkedList_Clear( &worker->tasks, OnDeleteTask ); free( worker ); }
LCUI_BOOL LCUIWorker_RunTask( LCUI_Worker worker ) { LCUI_Task task; LinkedListNode *node; LCUIMutex_Lock( &worker->mutex ); node = LinkedList_GetNode( &worker->tasks, 0 ); if( node ) { task = node->data; LinkedList_Unlink( &worker->tasks, node ); LCUIMutex_Unlock( &worker->mutex ); LCUITask_Run( task ); LCUITask_Destroy( task ); free( task ); free( node ); return TRUE; } LCUIMutex_Unlock( &worker->mutex ); return FALSE; }
/** 停用设备处理模块 */ void LCUIModule_Device_End(void) { int n, i; DeviceData *data_ptr; LCUIMutex_Lock( &list_mutex ); n = LinkedList_GetTotal( &dev_list ); for( i=0; i<n; ++i ) { data_ptr = (DeviceData*)LinkedList_Get( &dev_list ); if( !data_ptr ) { break; } if( data_ptr->exit ) { data_ptr->exit(); } LinkedList_ToNext( &dev_list ); } LCUIMutex_Unlock( &list_mutex ); }
/** * 功能:注册设备 * 说明:为指定设备添加处理函数 * */ int LCUIDevice_Add( LCUI_BOOL (*init)(void), LCUI_BOOL (*proc)(void), LCUI_BOOL (*exit)(void) ) { DeviceData device, *p; device.init = init; device.proc = proc; device.exit = exit; LCUIMutex_Lock( &list_mutex ); p = (DeviceData*)LinkedList_AddDataCopy( &dev_list, &device ); LCUIMutex_Unlock( &list_mutex ); if( !p ) { return -1; } if( device.init ) { device.init(); } return 0; }
/** 计时阻塞当前线程,等待条件成立 */ int LCUICond_TimedWait( LCUI_Cond *cond, LCUI_Mutex *mutex, unsigned int ms ) { int ret; LCUIMutex_Unlock( mutex ); ret = WaitForSingleObject( *cond, ms ); switch( ret ) { case WAIT_TIMEOUT: ret = ETIMEDOUT; break; case WAIT_OBJECT_0: ret = 0; break; case WAIT_FAILED: default: ret = GetLastError(); break; } LCUIMutex_Lock( mutex ); return ret; }
/* 设置呈现模式 */ int LCUIDisplay_SetMode( int mode ) { int ret; DEBUG_MSG("mode: %d\n", mode); LCUIMutex_Lock( &display.mutex ); switch( mode ) { case LCDM_WINDOWED: ret = LCUIDisplay_Windowed(); break; case LCDM_SEAMLESS: ret = LCUIDisplay_Seamless(); break; case LCDM_FULLSCREEN: default: ret = LCUIDisplay_FullScreen(); break; } LCUIMutex_Unlock( &display.mutex ); return ret; }
/** 从程序任务队列中删除有指定回调函数的任务 */ int LCUI_RemoveTask( CallBackFunc task_func, LCUI_BOOL need_lock ) { int n; LCUI_Task *exist_task; if( need_lock ) { LCUIMutex_Lock( &MainApp.task_list_mutex ); } n = LinkedList_GetTotal( &MainApp.task_list ); for ( ; n>0; --n ) { exist_task = (LCUI_Task*)LinkedList_Get( &MainApp.task_list ); if( exist_task && exist_task->func == task_func ) { LinkedList_Delete( &MainApp.task_list ); } else { LinkedList_ToNext( &MainApp.task_list ); } } if( need_lock ) { LCUIMutex_Unlock( &MainApp.task_list_mutex ); } return n; }
/** 检测指定键值的按键是否按了两次 @param key_code 要检测的按键的键值 @param interval_time 该按键倒数第二次按下时的时间与当前时间的最大间隔 */ LCUI_BOOL LCUIKey_IsDoubleHit( int key_code, int interval_time ) { clock_t ct; key_state* data_ptr; /* 计算当前时间(单位:毫秒) */ ct = clock()*1000 / CLOCKS_PER_SEC; LCUIMutex_Lock( &record_mutex ); data_ptr = KeyStateRecord_FindData( key_code ); LCUIMutex_Unlock( &record_mutex ); if( !data_ptr ) { return FALSE; } /* 间隔时间为-1,说明该键是新记录的 */ if( data_ptr->interval_time == -1 ) { return FALSE; } ct -= (data_ptr->hit_time - data_ptr->interval_time); /* 判断按键被按下两次时是否在距当前interval_time毫秒的时间内发生 */ if( ct <= interval_time ) { return TRUE; } return FALSE; }