breve allows simulations and individual objects within simulations to be archived into human-readable XML files, and then later extracted. The XML archive/dearchive process applies both to saving simulation objects to files and to sending objects over the network. Both techniques require object encoding and decoding, and the discussion in this chapter applies to both.
This chapter first describes how individual objects can be archived and dearchived (the section called “Saving and Loading Individual Objects”) and then how entire simulations can be archived and dearchived (the section called “Saving and Loading the Entire State of a Simulation”).
This method is used to export and import individual objects or subsets of objects in a simulation. When an object is dearchived with this method, a new instance is created for the saved object and loaded into a running simulation. This technique is in contrast to the method described in the section called “Saving and Loading the Entire State of a Simulation”, which creates an entirely new simulation from an archived world. The steps described here also apply to sending and receiving objects over a network as described in the section called “Sending and Receiving breve Objects”.
The special methods archive
and
dearchive
are called during archiving and
dearchiving respectively. The "archive" method is used, if necessary,
to prepare an object for archiving. The "dearchive" method is used, if
necessary, after an object has been loaded to prepare it for being
loaded into the simulation.
For most users, these methods are not required and should not be
implemented. If they are implemented, however, they must return 1 to indicate success and unless
the methods are specifically intended to override superclass behaviors,
they must call the superclass
implementation. In most cases, it is desirable to return
the same value as the superclass implementation so that errors are
handled correctly. Example archive
and
dearchive
methods are shown below. These
methods do no special preparation for archiving and dearchiving, but
instead fulfill the requirements lists above and print a message.
+ to archive: print "Archiving $self...". return (super archive). + to dearchive: print "Dearchiving $self...". return (super archive).
In a "simple" object archive, only a single object is encoded. If the
object has variable object
variables or
pointer
variables, they will be set to 0
when the object is dearchived. All other variable types will be
restored to their pre-archiving values. For this type of object
archiving and dearchiving, no additional code or preparation is
required.
Variables of type object
and pointer
cannot be automatically maintained without
special treatment. This is because an object
may reference another, which in turn
references several others, and so forth. If all object
variables were maintained, then a huge chain
reaction would result every time an instance was saved.
To avoid this, saving objects does not include an object variable unless the the object being saved has declared it as a dependency, using the Object method add-dependency. If you define an object, Y, as a dependency of X, then saving X will also save Y. Loading the saved instance X will also recreate the instance Y.
Because adding dependencies also has the potential to lead to chain-reactions of archiving, it should be used with care. Generally, an object should only add dependencies on objects it has created and for which it is exclusively responsible. So while a simulated creature might legitimately add a dependency on an object containing its genome or an object which determines its movement (a "brain"), it would be inappropriate for the object to add a dependency on the controller object, or other creatures in the world.
When an object is to be archived using this technique, the
user-supplied method archive
is executed
for the object. In your archive
method,
you should include code that might be needed to prepare the object for
archiving such as updating variables which will be required when the
object is dearchived. Your archive
method must, on success, return
1. Any other return value is considered failure and will
abort the archive.
When an object is to be dearchived using this method, the user-supplied
method dearchive
is executed for the
object. In your dearchive
method, you
should include code that might be needed to restore the state of the
object, or to inform the rest of the simulation of its presence if
necessary. Your dearchive method must, on
success, return 1. Any other return value is considered
failure and will abort the archive.
Once dependencies, archive methods and dearchive methods (all of which may prove to be unnecessary for most straightforward classes) are addressed, you may initiate an archive using the Object method archive-as-xml.
To dearchive an object previously archived with this technique, use the Control method dearchive-xml. Note that this creates new instances of the objects in the archived file, instead of "filling" an existing object.