Class: VER::Undo::Tree
Overview
The Tree keeps track of the current Record and creates new records.
It maintains a pointer to the widget and the current record in the tree. The current record is the record that was last applied.
When a record is undone: If there is a parent, it becomes the new current record. If there is no parent, it stays the current record, only flagged as unapplied. it’s parent (if there is one), becomes the new current record.
When a record is redone, it’s current child (if there is one), becomes the new current record.
The Tree doesn’t have a maximum depth at the moment, but this will be added, when old records are pruned, only the record at depth+1 that is current stays.
Eventually we have to separate records and undo/redo stepping. Some operations involve more than one record, but should be undone/redone together. It would also be handy if these operations could be identified automagically (like multiple operations within one record block).
Constant Summary
Constants inherited from Struct
Instance Attribute Summary collapse
-
#applied ⇒ Object
Returns the value of attribute applied.
-
#pending ⇒ Object
Returns the value of attribute pending.
-
#recording ⇒ Object
Returns the value of attribute recording.
-
#stack ⇒ Object
Returns the value of attribute stack.
-
#widget ⇒ Object
Returns the value of attribute widget.
Instance Method Summary collapse
-
#compact! ⇒ Object
Join previous applied changes that have only one child and that modify data consecutive.
-
#initialize(widget) ⇒ Tree
constructor
A new instance of Tree.
- #record ⇒ Object
- #record_multi ⇒ Object
-
#redo ⇒ Object
Redo pending change so it becomes the new applied change.
- #separate! ⇒ Object
-
#undo ⇒ Object
Undo last applied change so it becomes the next pending change.
Methods inherited from Struct
Constructor Details
#initialize(widget) ⇒ Tree
Returns a new instance of Tree.
28 29 30 31 |
# File 'lib/ver/undo.rb', line 28 def initialize() self. = self.stack = [] end |
Instance Attribute Details
#applied ⇒ Object
Returns the value of attribute applied
27 28 29 |
# File 'lib/ver/undo.rb', line 27 def applied @applied end |
#pending ⇒ Object
Returns the value of attribute pending
27 28 29 |
# File 'lib/ver/undo.rb', line 27 def pending @pending end |
#recording ⇒ Object
Returns the value of attribute recording
27 28 29 |
# File 'lib/ver/undo.rb', line 27 def recording @recording end |
#stack ⇒ Object
Returns the value of attribute stack
27 28 29 |
# File 'lib/ver/undo.rb', line 27 def stack @stack end |
#widget ⇒ Object
Returns the value of attribute widget
27 28 29 |
# File 'lib/ver/undo.rb', line 27 def @widget end |
Instance Method Details
#compact! ⇒ Object
Join previous applied changes that have only one child and that modify data consecutive. This rewrites already applied history only.
94 95 96 97 98 |
# File 'lib/ver/undo.rb', line 94 def compact! return unless applied applied.compact! self.pending = applied.next end |
#record ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/ver/undo.rb', line 41 def record if recording stack << Proc.new else self.recording = true current = Record.new(self, , applied) yield current applied.next = current if applied = self.applied self.applied = current self.applied = current self.pending = nil compact! self.recording = false if pending = stack.shift record(&pending) end end end |
#record_multi ⇒ Object
33 34 35 36 37 38 39 |
# File 'lib/ver/undo.rb', line 33 def record_multi AutoSeparator.new self do |auto_separator| yield auto_separator end compact! end |
#redo ⇒ Object
Redo pending change so it becomes the new applied change. If the pending change has a next child, it becomes the new pending one.
80 81 82 83 84 85 86 87 88 89 |
# File 'lib/ver/undo.rb', line 80 def redo while pending = self.pending pending.redo self.applied = pending self.pending = pending.next break if pending && pending.separator end end |
#separate! ⇒ Object
100 101 102 |
# File 'lib/ver/undo.rb', line 100 def separate! applied.separator = true if applied end |
#undo ⇒ Object
Undo last applied change so it becomes the next pending change. Parent of the applied change becomes the next applied change.
67 68 69 70 71 72 73 74 75 76 |
# File 'lib/ver/undo.rb', line 67 def undo while applied = self.applied applied.undo self.pending = applied self.applied = applied = applied.parent break if applied && applied.separator end end |