93 lines
4.4 KiB
Plaintext
93 lines
4.4 KiB
Plaintext
OVERVIEW
|
|
|
|
The system for writing out objects works as follows.
|
|
|
|
There are 2 types of managers that control the overall process for
|
|
reading and writing, BamWriter and BamReader. The initial request to
|
|
write/read an object is made to the manager. The manager will take
|
|
care of breaking/regenerating circular dependencies, making sure that
|
|
type information is written/read correctly, ensuring shared memory
|
|
references are refelected in or regenerated from the binary media,
|
|
etc...
|
|
|
|
The overall process goes as follows.
|
|
1) BamWriter needs to be created and given an appropriate DatagramSink for it to send
|
|
datagrams into.
|
|
2) Request to write an object is made to BamWriter
|
|
3) BamWriter checks to see if that Type of object has been written before or not, if it has then
|
|
the index of that type is written, otherwise the index and type name are written.
|
|
4) BamWriter then has the Object write itself into the datagram, and passes a reference to itself
|
|
to the object.
|
|
5) The object will write all information necessary to regenerate itself into the datagram, with
|
|
2 exceptions.
|
|
A) Any pointers to other objects needing to be written, are actually written through
|
|
requests to BamWriter. This ensures that the object being pointed to does get
|
|
written to the datagram, and that multiple references do not cause the object
|
|
to be written multiple times.
|
|
B) Any PointerToArrays are also written through requests to BamWriter. This ensures
|
|
that multiple references to the same PTA are not fully written multiple times and
|
|
that the information necessary to regenerate that sharing is written. There is a
|
|
an interaction between the object and BamWriter that ensures this that is taken
|
|
care of in an #define function called WRITE_PTA defined in BamWriter.h (with the
|
|
equivalent READ_PTA defined in BamReader.h)
|
|
6) Once the object has completed writing itself, BamWriter will send the datagram to the
|
|
DatagramSink.
|
|
|
|
|
|
Due to BamWriter's ability to handle pointer requests, only one write on the root of any linked
|
|
structure will be necessary if all of the objects are correctly "writeable".
|
|
|
|
For reading the process goes as follows
|
|
1) Create a BamReader with an appropriate DatagramGenerator source.
|
|
2) Requets to read an object from BamReader
|
|
3) BamReader will then read in the type of the object, and check that type against the current
|
|
dynamic index.
|
|
4) BamReader will then make a call to the TypedWriteable factory to generate an object of that
|
|
type. Passing a reference to itself and the datagram defining that object as params.
|
|
5) The make method of that type will be called
|
|
6) The make method of that type of object will create a new object and "fillin" in itself from the
|
|
data in the datagram.
|
|
7) As with Writing any Pointers to objects or PTA's will be filled through requests to BamReader.
|
|
Pointers will not be completed at this time, as the object may not have been read in. BamReader
|
|
will register the requestor and when resolve is called, BamReader will pass all the pointers
|
|
requested back to the caller through the common interface complete_pointers.
|
|
8) Finally, if the object needs to have any code run only after all pointers have been completed
|
|
it can register itself with BamReader to be "finalized"
|
|
|
|
|
|
CREATING A WRITEABLE CLASS
|
|
|
|
There is a file called template_for_typedWriteables.C that has the
|
|
"outline" code necessary to make a class writeable that is mostly
|
|
self-explanatory. A few clarifications are that not all of the
|
|
functions in that file are needed by every class. The finalize
|
|
function is currently only needed by PartBundles so you probably won't
|
|
need it. And complete_pointers is only needed if the object
|
|
writes/reads pointers to other objects. The make functions should
|
|
only be defined in classes that are non-abstract, that are actually
|
|
created and used.
|
|
|
|
Any class that is writeable has one last step besides adding all the
|
|
functionality into it. Every "makeable" class needs to have a call to
|
|
it's register_with_read_factory method put into the config file for
|
|
the package that is is apart of.
|
|
|
|
For working examples see
|
|
NodeRelation in the package graph
|
|
PartBundle in the package chan
|
|
Geom in the package gobj
|
|
|
|
For examples of the classes that are not TypedWriteable but it is useful for them to write and read
|
|
themselves into/from datagrams see
|
|
LVecBase(2)(3)(4) in the package linmath
|
|
ComputedVerticesMorph in the package char
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|