class Crimson::Model

Attributes

local[R]
observers[R]
revision_number[R]
revisions[R]

Public Class Methods

new() click to toggle source
Calls superclass method
# File lib/crimson/model.rb, line 12
def initialize
  @observers = {}
  @revisions = [Mash.new]
  @revision_number = 1
  @max_number_of_revisions = 2
  @local = Mash.new

  super(local)
end

Public Instance Methods

add_observer(observer, handler = :on_commit) click to toggle source
# File lib/crimson/model.rb, line 22
def add_observer(observer, handler = :on_commit)
  observers[observer] = observer.method(handler)
end
apply_changes!(*keys) click to toggle source
# File lib/crimson/model.rb, line 74
def apply_changes!(*keys)
  if keys.empty?
    revisions << Utilities.deep_copy(local)
  else
    revisions << Utilities.deep_copy(master)
    keys.each { |key| master[key] = Utilities.deep_copy(local[key]) }
  end

  @revision_number += 1
  revisions.shift if revisions.length > @max_number_of_revisions
end
changed?(*keys) click to toggle source
# File lib/crimson/model.rb, line 38
def changed?(*keys)
  if keys.empty?
    local != master
  else
    keys.map { |key| local[key] != master[key] }.any?(true)
  end
end
changes(*keys) click to toggle source
# File lib/crimson/model.rb, line 46
def changes(*keys)
  keys = ( master.keys | local.keys ) if keys.empty?
  diff = Mash.new

  keys.each do |k|
    v1 = master[k]
    v2 = local[k]
    diff[k] = ModelChange.new(v1, v2) if v1 != v2
  end

  diff
end
commit!(*keys) click to toggle source
# File lib/crimson/model.rb, line 67
def commit!(*keys)
  if changed?(*keys)
    notify_observers(new_changes(*keys))
    apply_changes!(*keys)
  end
end
master() click to toggle source
# File lib/crimson/model.rb, line 63
def master
  revisions.last
end
modify(modifications = {}) click to toggle source
# File lib/crimson/model.rb, line 34
def modify(modifications = {})
  local.merge(modifications)
end
new_changes(*keys) click to toggle source
# File lib/crimson/model.rb, line 59
def new_changes(*keys)
  changes(*keys).transform_values(&:new_value)
end
notify_observers(changes) click to toggle source
# File lib/crimson/model.rb, line 30
def notify_observers(changes)
  observers.each { |_observer, handler| handler.call(self, changes) }
end
reload!() click to toggle source
# File lib/crimson/model.rb, line 86
def reload!
  @local = Utilities.deep_copy(master)
end
remove_observer(observer) click to toggle source
# File lib/crimson/model.rb, line 26
def remove_observer(observer)
  observers.delete(observer)
end
rollback!() click to toggle source
# File lib/crimson/model.rb, line 90
def rollback!
  if revisions.length > 1
    @local = revisions.pop
  else
    reload!
  end
end