lib/gamefic/plot/darkroom.rb in gamefic-2.2.1 vs lib/gamefic/plot/darkroom.rb in gamefic-2.2.2
- old
+ new
@@ -1,35 +1,25 @@
module Gamefic
# Create and restore plot snapshots.
#
class Plot
class Darkroom
- # @return [Gamefic::Plot]
+ # @return [Plot]
attr_reader :plot
+ # @param plot [Plot]
def initialize plot
@plot = plot
end
# Create a snapshot of the plot.
#
# @return [Hash]
def save
- index = plot.static + plot.players
- plot.to_serial(index)
{
'program' => {}, # @todo Metadata for version control, etc.
- 'index' => index.map do |i|
- if i.is_a?(Gamefic::Serialize)
- {
- 'class' => i.class.to_s,
- 'ivars' => i.serialize_instance_variables(index)
- }
- else
- i.to_serial(index)
- end
- end
+ 'index' => index.map { |obj| serialize_indexed(obj) }
}
end
# Restore a snapshot.
#
@@ -71,9 +61,59 @@
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
+
+ private
+
+ def index
+ @index ||= begin
+ populate_full_index_from(plot)
+ Set.new(plot.static + plot.players).merge(full_index).to_a
+ end
+ end
+
+ def full_index
+ @full_index ||= Set.new
+ end
+
+ 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
+
+ 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
end
end
end