还是继续 MTK 的 history 机制吧,主要的执行过程已近些完了。说白里,历史记录就是一个栈,先进后出,当然,严格的按照栈的特性,不够灵活,可能会从一个屏幕跳转到特殊的屏幕,这样就需要特殊接口。先把 GoBackHistory 说完,还有一个函数 decrement。
static U8 decrement(void) { // 这个变量是用于判断是否要停止删除 U8 is_stop_delete = MMI_HIST_ALLOW_DELETING; static U16 cb_history_idx = 0; U16 scrnID; //这个标志表示是否是从历史记录返回 //这个标志使用表示 这个动作删除的不是top history //在 GoBackHistroy 里面,这个变量被设置成 TURE,所以不会执行。 //因为 GoBackHistroy 删除的就是 top history,而这个删除动作由 ExecTopScrnCallbackHandler 完成了 //这里不需要在执行 if (!bBackHistoryFlag) { //判断是否有注册过,这个screen id 的 del 回调函数 if (SearchDelScrnIDCallbackHandler(historyData[currHistoryIndex].scrnID, &cb_history_idx)) { // 这个回调函数是否为空 if (historyCBHandler[cb_history_idx].historydelCBPtr) { scrnID = historyData[currHistoryIndex].scrnID; // 回调 del sreen callback // 这里由一个参数,回调函数可以根据这个参数判断是正常的GoBackHistory 删除 // 还是 不是 is_stop_delete = historyCBHandler[cb_history_idx].historydelCBPtr((void*)MMI_HIST_DELETE_SCREEN_TYPE); // 根据返回值,判断是否要真正删除 // 这样当 莫一个屏幕不允许删除时,就可以返回 MMI_HIST_STOP_DELETING // 防止这个屏幕被删除 if (is_stop_delete == MMI_HIST_STOP_DELETING) { return MMI_HIST_STOP_DELETING; } // 清楚这个回调函数 ClearDelScrnIDCallbackHandler(scrnID, NULL); } } } //是否 history 相关内存 mmi_free_history_buffer(currHistoryIndex); //清空 top 栈,然后 减少一个index memset(&historyData[currHistoryIndex], 0, sizeof(historyNode)); --currHistoryIndex; MMI_ASSERT((currHistoryIndex >= MIN_HISTORY - 1)&&(currHistoryIndex < MAX_HISTORY) ); return is_stop_delete; }
这里又要唠叨一句: decrement 做了很多事情,而对应的 increment 就做了一点事情,让人迷惑,这代码写的
还是接着说GoBackToHistory,这个函数可以直接返回到一个指定screen id,对于一些特殊的条件,就方便多了,比如产生了一个错误,要从头开始,那么直接可以调用这个。当然history 栈里的比这个指定screen id 后进的,还是会被有序的退出。具体看程序吧
U8 GoBackToHistory(U16 scrnid) { S16 count = 0; U8 Status = ST_FAILURE; // 1 执行 top screen 删除 回调函数 ExecTopScrnCallbackHandler(); // 判断是否 orderly exit screen // 设置了这个标志,表示是否要执行top screen 退出函数 // if (mmi_is_orderly_exit_screen) { IsBackHistory = MMI_TRUE; CheckMainLCDHistoryBack = MMI_TRUE; bBackHistoryFlag = MMI_TRUE; ExecuteCurrExitHandler(); IsBackHistory = MMI_FALSE; CheckMainLCDHistoryBack = MMI_FALSE; bBackHistoryFlag = MMI_FALSE; } count = currHistoryIndex; do { // 判断是否找到 if (historyData[currHistoryIndex].scrnID == scrnid) { Status = ST_SUCCESS; break; } // 如果history stack 里面还有,继续查找 if (currHistoryIndex > 0) { //删除当前top history,如果返回 stop,则退出 // 这里就是可以通过 注册的 del screen call back 返回值,防止被删除 if (decrement() == MMI_HIST_STOP_DELETING) { Status = ST_SUCCESS; break; } } // 条件里的 count != currHistoryIndex 不明白。什么情况下会相等? } while ((count != currHistoryIndex) && (historyData[currHistoryIndex].entryFuncPtr != NULL) && (currHistoryIndex > 0)); // 找到这个screen id if (Status) { // 执行这个screen id 的 入口函数 entry ExecutePopHistory(); } // 出错处理,返回到idle else if (currHistoryIndex > -1) { ExecTopScrnCallbackHandler(); IsBackHistory = MMI_TRUE; CheckMainLCDHistoryBack = MMI_TRUE; bBackHistoryFlag = MMI_TRUE; (*(historyData[0].entryFuncPtr)) (); IsBackHistory = MMI_FALSE; CheckMainLCDHistoryBack = MMI_FALSE; bBackHistoryFlag = MMI_FALSE; currHistoryIndex = -1; } return Status; }