annotate nobuild/undo_manager.d @ 124:46e6dd7dce2e

Beginnings of some documentation, and miscellaneous tweaks.
author David Bryant <bagnose@gmail.com>
date Thu, 05 May 2011 00:04:41 +0930
parents 66210d8ea37a
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
96
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
1 module doodle.main.undo_manager;
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
2
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
3 class UndoManager : IUndoManager {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
4 this() {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
5 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
6
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
7 void addObserver(IUndoObserver observer) {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
8 _observers.add(observer);
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
9 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
10
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
11 void removeObserver(IUndoObserver observer) {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
12 _observers.remove(observer);
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
13 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
14
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
15 void reset() {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
16 assert(!inTransaction());
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
17 _past.clear();
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
18 _future.clear();
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
19 foreach(IUndoObserver obs; _observers) {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
20 obs.canUndo(false, "");
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
21 obs.canRedo(false, "");
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
22 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
23 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
24
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
25 void undo() {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
26 assert(canUndo());
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
27 Transaction t = _past.pop();
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
28 t.undo();
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
29 _future.push(t);
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
30 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
31
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
32 void redo() {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
33 assert(canRedo());
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
34 Transaction t = _future.pop();
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
35 t.redo();
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
36 _past.push(t);
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
37 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
38
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
39 bool canUndo() {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
40 assert(!inTransaction());
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
41 return !_past.empty();
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
42 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
43
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
44 bool canRedo() {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
45 assert(!inTransaction());
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
46 return !_future.empty();
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
47 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
48
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
49 void beginTransaction(char[] description) {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
50 assert(!inTransaction());
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
51 _current_transaction = new Transaction(description);
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
52 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
53
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
54 void cancelTransaction() {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
55 assert(inTransaction());
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
56 _current_transaction.cancel();
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
57 _current_transaction = null;
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
58 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
59
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
60 void endTransaction() {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
61 assert(inTransaction());
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
62 _current_transaction.finalise();
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
63
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
64 if (!_future.empty()) {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
65 _future.clear();
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
66 foreach(IUndoObserver obs; _observers) {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
67 obs.canRedo(false, "");
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
68 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
69 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
70
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
71 _past.push(_current_transaction);
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
72
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
73 foreach(IUndoObserver obs; _observers) {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
74 bs.canUndo(true, _current_transaction.name());
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
75 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
76
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
77 _current_transaction = null;
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
78 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
79
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
80 // IUndoManager implementations:
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
81
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
82 void addAction(Action action) {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
83 assert(inTransaction());
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
84 _current_transaction.add(action);
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
85 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
86
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
87 private {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
88 bool inTransaction() {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
89 return _current_transaction !is null;
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
90 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
91
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
92 class Transaction {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
93 enum State {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
94 Accumulating,
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
95 Finalised,
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
96 Canceled
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
97 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
98
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
99 this(char[] description) {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
100 _description = description;
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
101 _state = Accumulating;
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
102 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
103
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
104 char[] description() {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
105 return _description;
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
106 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
107
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
108 void add(Action action) {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
109 assert(_state == State.Accumulating);
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
110 _actions.addTail(action);
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
111 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
112
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
113 void finalise() {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
114 assert(_state == State.Accumulating);
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
115 assert(!_actions.empty());
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
116 _finalised = true;
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
117 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
118
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
119 void cancel() {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
120 assert(_state == State.Accumulating);
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
121 foreach_reverse(UndoAction ua; _actions) {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
122 ua.undo();
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
123 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
124 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
125
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
126 void redo() {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
127 assert(_finalised);
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
128 foreach (UndoAction ua; _actions) {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
129 ua.redo();
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
130 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
131 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
132
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
133 void undo() {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
134 assert(_finalised);
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
135 foreach_reverse(UndoAction ua; _actions) {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
136 ua.undo();
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
137 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
138 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
139
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
140 private {
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
141 char[] _description;
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
142 List!(Action) _actions;
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
143 State _state;
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
144 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
145 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
146
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
147 Transaction _current_transaction;
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
148 Stack!(Transaction) _past;
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
149 Stack!(Transaction) _future;
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
150 Set!(IUndoObserver) _observers;
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
151 }
66210d8ea37a Added some junk
David Bryant <bagnose@gmail.com>
parents:
diff changeset
152 }