Last modified 3 years ago
Serialization in Lively Kernel (Brainstorming)
Problem
General storing and loading of Lively Worlds, or in other Words: How to serialize and a Object Graph into a tree structure and creating a meaningful ans sustainable structure / file format.
How it Works now
- Morphs are serialized as XML nodes in the DOM
- the DOM hierarchy resembles the submorph relationship
<g type="TextMorph" id="338:TextMorph" ...> <rect x="0" y="0" width="90" height="21.2" stroke-width="1" stroke="rgb(0,0,0)" fill="rgb(243,243,243)"/> <g type="TextSelectionMorph" id="339:TextSelectionMorph" ...> <g stroke-width="0" fill="none"/> <field name="origin" family="Point"><![CDATA[{"x":0,"y":0}]]></field> <field name="fullBounds" family="Rectangle"><![CDATA[{"x":-3,"y":-3,"width":6,"height":6}]]></field> <field name="mouseHandler">null</field> </g> <text kerning="0" fill="rgb(0,0,0)" font-size="12" font-family="Helvetica"> <tspan x="6" y="14.8">sd1</tspan> </text> <field name="textString"><![CDATA["sd1"]]></field> <field name="origin" family="Point"><![CDATA[{"x":10,"y":10}]]></field> <field name="fullBounds" family="Rectangle"><![CDATA[{"x":8,"y":8,"width":94,"height":24}]]></field> <field name="textSelection" ref="339:TextSelectionMorph"/> <field name="widget" ref="335:DummyWidget"/> <relay name="formalModel" ref="336:anonymous_87"> <binding formal="Text" actual="MyText"/> </relay> ... </g>
- references between Morphs are encoded and resolved into urls of the form: ' ref="339:TextSelectionMorph?" '
- the loading and saving of the DOM is handled by the browser
- Strings and Numbers are encoded as normal attributes
- more complex objects are encoded with JSON
APIs
- Record
- Widget
- Wrapper.prepareForSerialization(extraNodes)
- Wrapper.preparePropertyForSerialization(prop, propValue, extraNodes) converts properties to attributes, subnodes, JSON , and references...
- Morph.deserialize
- restoreFromSubnodes
- restoreFromSubnode
- restorePersistentState
- initializeTransientState
- restoreFromSubnodes
- Widgets can be integrated into the serialization by explicitly by putting it into the ownerWidget of a morph
Serializing Process
- Exporter class.shrinkWrapMorph(morph)
- Exporter.serialize(newDoc)
- Exporter.extendForSerialization
- withAllSubmorphsDo
- Wrapper.prepareForSerialization
- for all properties
- Wrapper.preparePropertyForSerialization
- for all properties
- Wrapper.prepareForSerialization
- withAllSubmorphsDo
- Exporter.extendForSerialization
- Exporter.serialize(newDoc)
Scenarios
Only Morphs
- only standard Morphs are used to create graphics, and text
Rotating Star
- Morphs can be animated registering stepping methods (standard messages and simple parameters)
Morphs and Model
- One Morphs has one Model
Sharing Models
- Two Morph share one Model
Simple Widgets: Weather Widget
- a widgets consists of several Morphs
- the Morphs relay to the widgets model
- no cross-references other than the relay
Widgets, Models, Morphs with Cross-References
- besides the graphical hierarchy is a second widget hierarchy
- references are between widgets, morphs and models
- models have dynamical attributes
Open Questions
Where do the widgets and models go?
- Widgets don't fit naturally into SVG DOM because they are no graphical objects
What about Models
- Models sounds like they should be persistable in a form of database? Does it make sense?
Where is the difference between Morphs, Widgets, and Models?
- And for what do we need to differentiate?
How do I serialize Observers ?
Concepts and Ideas
JSON Heap of Widgets and Models
- one possible Solution is to treat widgets completely different
- e.g. use JSON to create a heap of widgets and models
- encode and resolve the references with ids like the morphs do
- store the whole JSON string in one place in the World / Widgets
- needs several passes in (de-)serialization
- Contra:
- not as such human readable
- Morph gets separated from Widgets and Models
- logical structure and relation of widgets are lost
- copy and paste need to be clever to find which references to models and widgets belong to the morph the user wants to copy
- Pro:
- it is very general
- no annotation or special serialization code is needed
- resembles perhaps a bit the smalltalk image concept with all its advantages and disadvantages
XML Tree of Widgets
- serialize the logical structure of widgets as pseudo morphs into the DOM Tree
- Pro:
- separates models from views
- Contra:
- separates models from views
- Pro:
Merge Widgets into Morph Tree
- merge the widgets into the morph tree
- associate widgets and models with their morphs and store them in the morph tree
- pro
- keeps things that belong together in one place
- easier copy and paste because the graphical tree contains all relevant information
- contra
- can be a bit messy, the distinction between model and view is lost and the question would be, why was there one in the first place
- not complete: what about widgets that don't explicitly belong to morph and that are still referenced?
Proposed Serialization Strategy (Jens)
- Morphs are stored in the DOM through their SVG Nodes (at it is now).
- Widgets and models may get a defined place in the DOM, e.g. the morph that displays them. Perhaps the owner relationship of a model can be used for that.
- Widgets and models that are not already in the tree and have no defined place there, may the be serialized in the place that first references them.
- Morphs, Widgets, and Models that are not directly or indirectly referenced from graphical objects or are special objects are not serialized.
- The serialization process can act as a garbage collector for unused widgets.
- The problem was, that after the first serialization widgets may be referenced in the DOM but forgotten by the user, so these have to be cleared out before a serialization.
- The serialization process can act as a garbage collector for unused widgets.
Related Work
- Object Serialization in Smalltalk images
- Object / Relational / XML Databases?
- Etoys / Tweak serialization in TinLizzie?, where the player / costumes are embedded into standard open office XML
Summary
It seems there is no perfect solution yet, so we should implement something that works and hope for the best.
