class Gamefic::Plot::Darkroom

Attributes

plot[R]

@return [Plot]

Public Class Methods

new(plot) click to toggle source

@param plot [Plot]

# File lib/gamefic/plot/darkroom.rb, line 10
def initialize plot
  @plot = plot
end

Public Instance Methods

restore(snapshot) click to toggle source

Restore a snapshot.

@param snapshot [Hash]

# File lib/gamefic/plot/darkroom.rb, line 27
def restore snapshot
  # @todo Use `program` for verification

  plot.subplots.each(&:conclude)
  plot.subplots.clear

  index = plot.static + plot.players
  snapshot['index'].each_with_index do |obj, idx|
    next if index[idx]
    elematch = obj['class'].match(/^#<ELE_([\d]+)>$/)
    if elematch
      klass = index[elematch[1].to_i]
    else
      klass = Gamefic::Serialize.string_to_constant(obj['class'])
    end
    index.push klass.allocate
  end

  snapshot['index'].each_with_index do |obj, idx|
    if index[idx].class.to_s != obj['class']
      STDERR.puts "MISMATCH: #{index[idx].class} is not #{obj['class']}"
      STDERR.puts obj.inspect
    end
    obj['ivars'].each_pair do |k, v|
      next if k == '@subplots'
      uns = v.from_serial(index)
      next if uns == "#<UNKNOWN>"
      index[idx].instance_variable_set(k, uns)
    end
    if index[idx].is_a?(Gamefic::Subplot)
      index[idx].extend Gamefic::Scriptable
      index[idx].instance_variable_set(:@theater, nil)
      index[idx].send(:run_scripts)
      index[idx].players.each do |pl|
        pl.playbooks.push index[idx].playbook unless pl.playbooks.include?(index[idx].playbook)
      end
      index[idx].instance_variable_set(:@static, [index[idx]] + index[idx].scene_classes + index[idx].entities)
      plot.subplots.push index[idx]
    end
  end
end
save() click to toggle source

Create a snapshot of the plot.

@return [Hash]

# File lib/gamefic/plot/darkroom.rb, line 17
def save
  {
    'program' => {}, # @todo Metadata for version control, etc.
    'index' => index.map { |obj| serialize_indexed(obj) }
  }
end

Private Instance Methods

full_index() click to toggle source
# File lib/gamefic/plot/darkroom.rb, line 78
def full_index
  @full_index ||= Set.new
end
index() click to toggle source
# File lib/gamefic/plot/darkroom.rb, line 71
def index
  @index ||= begin
    populate_full_index_from(plot)
    Set.new(plot.static + plot.players).merge(full_index).to_a
  end
end
populate_full_index_from(object) click to toggle source
# File lib/gamefic/plot/darkroom.rb, line 82
def populate_full_index_from(object)
  return if full_index.include?(object)
  if object.is_a?(Array) || object.is_a?(Set)
    object.each { |ele| populate_full_index_from(ele) }
  elsif object.is_a?(Hash)
    object.each_pair do |k, v|
      populate_full_index_from(k)
      populate_full_index_from(v)
    end
  else
    if object.is_a?(Gamefic::Serialize)
      full_index.add object unless object.is_a?(Module) && object.name
      object.instance_variables.each do |v|
        next if object.class.excluded_from_serial.include?(v)
        populate_full_index_from(object.instance_variable_get(v))
      end
    else
      object.instance_variables.each do |v|
        populate_full_index_from(object.instance_variable_get(v))
      end
    end
  end
end
serialize_indexed(object) click to toggle source
# File lib/gamefic/plot/darkroom.rb, line 106
def serialize_indexed object
  if object.is_a?(Gamefic::Serialize)
    # Serialized objects in the index should be a full serialization.
    # Serialize#to_serial rturns a reference to the indexed object.
    {
      'class' => object.class.to_s,
      'ivars' => object.serialize_instance_variables(index)
    }
  else
    object.to_serial(index)
  end
end