#ifndef __NAVIGATION_H #define __NAVIGATION_H #include #include const size_t NAVIGATION_HISTORY_SIZE = 32; template class CNavigation_base { protected: T history[NAVIGATION_HISTORY_SIZE]; size_t historystart, historyend, historycurrent; public: CNavigation_base() : historystart(0),historyend(0),historycurrent(0) {} void saveposn(T posn); void writeposn(T posn); bool forward(T& loc); bool back(T& loc); }; class CNavigation : public CNavigation_base { public: void setSaveData(unsigned char*& data, unsigned short& len, unsigned char* src, unsigned short srclen); void putSaveData(unsigned char*& src, unsigned short& srclen); }; template inline void CNavigation_base::saveposn(T posn) { history[historycurrent] = posn; historycurrent=(historycurrent+1)%NAVIGATION_HISTORY_SIZE; if (historycurrent==historystart) { historystart=(historystart+1)%NAVIGATION_HISTORY_SIZE; } historyend = historycurrent; } template inline void CNavigation_base::writeposn(T posn) { history[historycurrent] = posn; } template inline bool CNavigation_base::back(T& posn) { if (historycurrent!=historystart) { // buffer is not empty if (historycurrent==0) { historycurrent=NAVIGATION_HISTORY_SIZE-1; } else { historycurrent--; } posn=history[historycurrent]; return true; } else { // circular buffer empty return false; } } template inline bool CNavigation_base::forward(T& posn) { if (historycurrent!=historyend) { historycurrent=(historycurrent+1)%NAVIGATION_HISTORY_SIZE; posn = history[historycurrent]; return true; } else { return false; } } #endif