Class: VER::Undo::Tree

Inherits:
Struct
  • Object
show all
Defined in:
lib/ver/undo.rb

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).

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#appliedObject

Returns the value of attribute applied

Returns:

  • (Object)

    the current value of applied



27
28
29
# File 'lib/ver/undo.rb', line 27

def applied
  @applied
end

#pendingObject

Returns the value of attribute pending

Returns:

  • (Object)

    the current value of pending



27
28
29
# File 'lib/ver/undo.rb', line 27

def pending
  @pending
end

#widgetObject

Returns the value of attribute widget

Returns:

  • (Object)

    the current value of widget



27
28
29
# File 'lib/ver/undo.rb', line 27

def widget
  @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.



79
80
81
82
83
# File 'lib/ver/undo.rb', line 79

def compact!
  return unless applied
  applied.compact!
  self.pending = applied.next
end

#record {|current| ... } ⇒ Object

Yields:

  • (current)


36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/ver/undo.rb', line 36

def record
  current = Record.new(widget, applied)

  yield current

  applied.next = current if applied = self.applied

  self.applied = current
  self.applied = current
  self.pending = nil

  compact!
end

#record_multiObject



28
29
30
31
32
33
34
# File 'lib/ver/undo.rb', line 28

def record_multi
  AutoSeparator.new self do |auto_separator|
    yield auto_separator
  end

  compact!
end

#redoObject

Redo pending change so it becomes the new applied change. If the pending change has a next child, it becomes the new pending one.



65
66
67
68
69
70
71
72
73
74
# File 'lib/ver/undo.rb', line 65

def redo
  while pending = self.pending
    pending.redo

    self.applied = pending
    self.pending = pending.next

    break if pending && pending.separator
  end
end

#separate!Object



85
86
87
# File 'lib/ver/undo.rb', line 85

def separate!
  applied.separator = true if applied
end

#undoObject

Undo last applied change so it becomes the next pending change. Parent of the applied change becomes the next applied change.



52
53
54
55
56
57
58
59
60
61
# File 'lib/ver/undo.rb', line 52

def undo
  while applied = self.applied
    applied.undo

    self.pending = applied
    self.applied = applied = applied.parent

    break if applied && applied.separator
  end
end