]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/scout/lib/src/history.h
update
[l4.git] / l4 / pkg / scout / lib / src / history.h
1 /*
2  * \brief   Browser history buffer
3  * \date    2005-11-03
4  * \author  Norman Feske <norman.feske@genode-labs.com>
5  */
6
7 /*
8  * Copyright (C) 2005-2009
9  * Genode Labs, Feske & Helmuth Systementwicklung GbR
10  *
11  * This file is part of the Genode OS framework, which is distributed
12  * under the terms of the GNU General Public License version 2.
13  */
14
15 #ifndef _HISTORY_H_
16 #define _HISTORY_H_
17
18 #include <cstring>
19
20 using Scout_gfx::Widget;
21
22 class History
23 {
24 private:
25
26   static const int _size = 128;    /* history size */
27
28   int     _idx;                  /* current position in history       */
29   Widget *_history[_size];       /* ring buffer of history references */
30
31   /**
32    * Increment history position
33    *
34    * \offset  The incrementation offset must be higher than -_size
35    */
36   inline void _inc(int offset) { _idx = (_idx + _size + offset) % _size; }
37
38   /**
39    * Return next index of current position
40    */
41   inline int _next() { return (_idx + 1) % _size; }
42
43   /**
44    * Return previous index of current position
45    */
46   inline int _prev() { return (_idx + _size - 1) % _size; }
47
48 public:
49
50   /**
51    * Constructor
52    */
53   History() : _idx(0)
54   {
55     memset(_history, 0, sizeof(_history));
56   }
57
58   /**
59    * Request element at current history position
60    */
61   Widget *curr() { return _history[_idx]; }
62
63   /**
64    * Add element to history.
65    *
66    * We increment the current history position and insert the
67    * new element there. If the new element is identical with
68    * with the old element at that position, we keep the following
69    * history elements. Otherwise, we follow a new link 'branch'
70    * and cut off the old one.
71    */
72   void add(Widget *e)
73   {
74     /* discard invalid history elements */
75     if (!e)
76       return;
77
78     /* increment history position */
79     _inc(1);
80
81     /* do we just follow the forward path? */
82     if (curr() == e)
83       return;
84
85     /* cut off old forward history branch */
86     _history[_next()] = 0;
87
88     /* insert new element */
89     _history[_idx] = e;
90   }
91
92   /**
93    * Assign new element to current history entry
94    */
95   void assign(Widget *e) { if (e) _history[_idx] = e; }
96
97   /**
98    * Travel forward or backward in history
99    *
100    * \return  1 on success,
101    *          0 if end of history is reached
102    */
103   enum direction { FORWARD, BACKWARD };
104   int go(direction dir)
105   {
106     /* stop at the boundaries of the history */
107     if (!_history[dir == FORWARD ? _next() : _prev()]) return 0;
108
109     /* travel in history */
110     _inc(dir == FORWARD ? 1 : -1);
111     return 1;
112   }
113 };
114
115
116 #endif