1 /*
2    Drawpile - a collaborative drawing program.
3 
4    Copyright (C) 2008-2019 Calle Laakkonen
5 
6    Drawpile is free software: you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation, either version 3 of the License, or
9    (at your option) any later version.
10 
11    Drawpile is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with Drawpile.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #ifndef CANVAS_HISTORY_H
21 #define CANVAS_HISTORY_H
22 
23 #include <QList>
24 
25 #include "../libshared/net/message.h"
26 
27 namespace canvas {
28 
29 /**
30  * @brief Sequence of messages to reproduce the canvas state
31  *
32  * The whole session history might not be in memory, but it
33  * should always contain enough messages to reach
34  * end of the Undo history.
35  */
36 class History {
37 public:
38 	History();
39 
40 	/**
41 	 * @brief Get the current stream offset
42 	 *
43 	 * The indexes of the messages in the stream should not change
44 	 * even if older parts of it are discarded to save memory.
45 	 *
46 	 * @return index of first stored message
47 	 */
offset()48 	int offset() const { return m_offset; }
49 
50 	/**
51 	 * @brief Get the end index of the stream
52 	 * @return
53 	 */
end()54 	int end() const { return m_offset + m_messages.size(); }
55 
56 	/**
57 	 * @brief Check if a message at the given index is in memory
58 	 * @param i
59 	 * @return true if message can be got with at(i)
60 	 */
isValidIndex(int i)61 	bool isValidIndex(int i) const { return i >= offset() && i < end(); }
62 
63 	/**
64 	 * @brief at Get the message at the given index
65 	 */
at(int pos)66 	protocol::MessagePtr at(int pos) const { return m_messages.at(pos-m_offset); }
67 
68 	/**
69 	 * @brief Add a new command to the stream
70 	 * @param msg command to add
71 	 */
72 	void append(protocol::MessagePtr msg);
73 
74 	/**
75 	 * @brief Delete old messages until the given index
76 	 */
77 	void cleanup(int until);
78 
79 	/**
80 	 * @brief Remove all messages and change the offset
81 	 *
82 	 * @param newoffset
83 	 */
84 	void resetTo(int newoffset);
85 
86 	/**
87 	 * @brief Get the length of the stored message stream in bytes.
88 	 *
89 	 * This returns the length of the serialized messages, not the in-memory
90 	 * representation.
91 	 * @return (serialized) length in bytes
92 	 */
lengthInBytes()93 	uint lengthInBytes() const { return m_bytes; }
94 
95 	/**
96 	 * @brief return the whole stream as a list
97 	 * @return list of messages
98 	 */
toList()99 	protocol::MessageList toList() const { return m_messages; }
100 
101 private:
102 	protocol::MessageList m_messages;
103 	int m_offset;
104 	uint m_bytes;
105 };
106 
107 }
108 
109 #endif
110 
111