📄 history.c
字号:
#include "progect.h"#include "history.h"#include "progectdb.h"// HISTORY_LENGTH _has_ to be a power of two, or everything will // break down...#define HISTORY_LENGTH 16static const UInt16 HISTORY_LENGTH_MASK = HISTORY_LENGTH-1;// 12 bytes per nodetypedef struct { LocalID dbID; // LocalID of the db UInt16 topTask; // index of the item at the top of the screen UInt16 actualTask; // index of actually selected item UInt16 parentTask; UInt8 view; // viewType UInt8 refLevel;} LinkHistoryNodeType;// for a history cyclic-buffertypedef struct { // use LinkItemFields for the nodes, and this for the ctrl. LinkHistoryNodeType history[HISTORY_LENGTH]; UInt8 first; // first item index UInt8 last; // last item index UInt8 now; // actual item index} LinkHistoryType;// prototypesvoid historyMove(UInt16 pos);static LinkHistoryType gHistory = { {{0}}, 0, 0, 0};/**************************************************************************** * Name : historyAdd * Desc : add an entry to the history, using actual db and position * Prm : - * Out : - * Auth : lb, 2001-08-06 ***************************************************************************/void historyAdd(void){ UInt16 pos; DBGMSG((DBB, "*** In HistoryAdd")); // first make sure we don't have a duplicate historyDeleteByDBID(gdbID); // add it to the history, after now, replacing last pos = (gHistory.last + 1) & HISTORY_LENGTH_MASK;DBGMSG((DBB, "*** gHistory.last %d New pos %d",gHistory.last,pos));DBGMSG((DBB, "*** gdbID %d",gdbID)); // if we have made one round of our cyclic buffer if (pos == gHistory.first) // discard the oldest item gHistory.first = (gHistory.first + 1) & HISTORY_LENGTH_MASK; gHistory.last = pos; gHistory.now = pos; gHistory.history[pos].dbID = gdbID; gHistory.history[pos].topTask = gCurrentPrefs.topTask; gHistory.history[pos].actualTask = gActualTask; gHistory.history[pos].parentTask = gParentTask; gHistory.history[pos].refLevel = gRefLevel; gHistory.history[pos].view = gCurrentPrefs.view; DBGMSG((DBB, "History Length Mask %d",HISTORY_LENGTH_MASK)); DBGMSG((DBB, "first %d last %d",gHistory.first,gHistory.last)); DBGMSG((DBB, "In HistoryAdd - exit"));} // void historyAdd(void)/**************************************************************************** * Name : historyUpdate * Desc : update the actual entry in the history * Prm : - * Out : - * Auth : lb, 2001-08-08 ***************************************************************************/void historyUpdate(void){ UInt16 pos = gHistory.now; DBGMSG((DBB, "In HistoryUpdate")); gHistory.history[pos].topTask = gCurrentPrefs.topTask; gHistory.history[pos].actualTask = gActualTask; gHistory.history[pos].parentTask = gParentTask; gHistory.history[pos].refLevel = gRefLevel; gHistory.history[pos].view = gCurrentPrefs.view; DBGMSG((DBB, "In HistoryUpdate - exit"));} // void historyUpdate(void)/**************************************************************************** * Name : historyMove * Desc : move in history * Prm : -> pos : position in history to move to * Out : - * Auth : lb, 2001-08-08 ***************************************************************************/void historyMove(UInt16 pos){ DBGMSG((DBB, "In HistoryMove")); // update history historyUpdate(); // Close actual DB CloseDB(gdbP); // open new DB OpenDBByID(0, gHistory.history[pos].dbID, &gdbP); // get info for the new DB gCurrentPrefs.topTask = gHistory.history[pos].topTask; gActualTask = gHistory.history[pos].actualTask; gParentTask = gHistory.history[pos].parentTask; gRefLevel = gHistory.history[pos].refLevel; gCurrentPrefs.view = gHistory.history[pos].view; // switch to the good view switchView(gCurrentPrefs.view); gHistory.now = pos; DBGMSG((DBB, "In HistoryMove - exit"));} // void historyMove(UInt16 pos)/**************************************************************************** * Name : historyBack * Desc : go back in history, returns pgError if there's no previous * Prm : - * Out : - * Auth : lb, 2001-08-08 ***************************************************************************/pgErr historyBack(void){ UInt16 pos; DBGMSG((DBB, "In historyBack")); DBGMSG((DBB, "now %d first %d last %d",gHistory.now,gHistory.first,gHistory.last)); // if these items are the same, list is empty // Of course this should never happen because database are added to // history when they are opened... if (gHistory.first == gHistory.last) return pgError; pos = (gHistory.now - 1) & HISTORY_LENGTH_MASK; // we are already at the first item, can't go back further if (pos == gHistory.first) return pgError; // move to the new pos historyMove(pos); return pgOK;} // pgErr historyBack(void)/**************************************************************************** * Name : historyNext * Desc : advance in history, returns pgError if there's no next * Prm : - * Out : - * Auth : lb, 2001-08-08 ***************************************************************************/pgErr historyNext(void){ UInt16 pos; DBGMSG((DBB, "In historyNext")); DBGMSG((DBB, "now %d first %d last %d",gHistory.now,gHistory.first,gHistory.last)); pos = (gHistory.now + 1) & HISTORY_LENGTH_MASK; // we are already at the last item, can't go further if (gHistory.now == gHistory.last) return pgError; // move to the new pos historyMove(pos); return pgOK;} // pgErr historyNext(void)/**************************************************************************** * Name : historyFind * Desc : Attempt to find the POS of a database given the ID * Prm : LocalID dbID (db to find) * Out : pgErr pgOk if found, pgError if not found, UInt16 &pos (position * to update if found) * Auth : rp, 2003-08-01 ***************************************************************************/pgErr historyFind(LocalID dbID, UInt16 *pos){ UInt16 loopPos; UInt16 nextLoopPos; DBGMSG((DBB, "In historyFind")); // if no items, we can't find any can we? if(gHistory.first == gHistory.last) return pgError; // We put the assignment of nextLoopPos at the top of the loop so that // we can stop when it's the same as gHistory.last // We never add at gHistory.first, we always add after, so we have to // start after gHistory.first. nextLoopPos=(gHistory.first+1)&HISTORY_LENGTH_MASK; do { loopPos=nextLoopPos; nextLoopPos=(loopPos + 1) & HISTORY_LENGTH_MASK; if (gHistory.history[loopPos].dbID == dbID) { *pos=loopPos; return pgOK; } } while (loopPos != gHistory.last); return pgError;} // pgErr historyFind(LocalID dbID, UInt16 &pos)/**************************************************************************** * Name : historyDelete * Desc : Delete the given index * Prm : UInt16 posToDelete * Out : gpErr pgOK if deleted, pgError if invalid index * Auth : rp, 2003-08-01 ***************************************************************************/pgErr historyDelete(UInt16 pos){ UInt16 loopPos; UInt16 nextLoopPos; DBGMSG((DBB, "In historyDelete")); DBGMSG((DBB, "now %d first %d last %d",gHistory.now,gHistory.first,gHistory.last)); // if no items, we can't delete any can we? if(gHistory.first == gHistory.last) return pgError; DBGMSG((DBB, "In historyDelete - starting loop")); // +++ FIX THIS +++ Need to make sure pos is in a valid range // we put the assignment of nextLoopPos at the top of the loop so that // we can delete pos when it's the same as gHistory.last nextLoopPos=pos; do { loopPos=nextLoopPos; nextLoopPos=(loopPos + 1) & HISTORY_LENGTH_MASK; gHistory.history[loopPos].dbID = gHistory.history[nextLoopPos].dbID; gHistory.history[loopPos].topTask = gHistory.history[nextLoopPos].topTask; gHistory.history[loopPos].actualTask = gHistory.history[nextLoopPos].actualTask; gHistory.history[loopPos].parentTask = gHistory.history[nextLoopPos].parentTask; gHistory.history[loopPos].view = gHistory.history[nextLoopPos].view; gHistory.history[loopPos].refLevel = gHistory.history[nextLoopPos].refLevel; } while (loopPos != gHistory.last); gHistory.last=(gHistory.last - 1) & HISTORY_LENGTH_MASK; if (pos == gHistory.now) { DBGMSG((DBB, "In historyDelete - pos == gHistory.new")); gHistory.now=gHistory.last; } return pgOK;} //pgErr historyDelete(UInt16 pos)/**************************************************************************** * Name : historyDeleteByDBID * Desc : Delete the entry for the given database from history given it's DBID * Prm : LocalID dbID (db to find) * Out : pgErr pgOk if found, pgError if not found * Auth : rp, 2003-08-01 ***************************************************************************/pgErr historyDeleteByDBID(LocalID dbID){ UInt16 foundPos; pgErr returnValue; DBGMSG((DBB, "In historyDeleteByDBID")); // if we can find an entry, then delete it... returnValue=historyFind(dbID,&foundPos); if (pgOK == returnValue) historyDelete(foundPos); return returnValue;} // pgErr historyFind(LocalID dbID, UInt16 &pos)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -