2012/10/13 Johan Engelen <jbc.engelen@...2592...>:
Hi all, For backwards compatibility with old-style guides, we want to convert the old-style guides to new-style in sp_namedview_build. Removing the old-style guides from XML and adding new ones works fine, however, this is not represented at all in the SPObject tree. After removing the old-style guides, the SPObjects are still in memory and hooked up to namedview. Also, adding new guides to XML does not create SPObjects belonging to them. This all works fine outside sp_namedview_build (the mechanism is used in hundreds of places in the code), but for some reason does not work within sp_namedview_build. Is that expected behavior? Where should we move the conversion code to?
When the SP tree is initially created, the XML node observers, which are responsible for keeping the SP tree up to date, are not yet active. They are added by SPObject::invoke_build only once the build function for your SPObject finishes executing. The children of each object are created by its virtual build function, such as sp_namedview_build. For this document skeleton:
<svg> <g> <path> <path> </g> </svg>
The order of actions is:
call SPRoot::build call SPItemGroup::build call SPPath::build for the first path add first path observer call SPPath::build for the second path add second path observer add group observer add root observer
The XML observers do not send a notification when an object is destroyed. Deleting and creating SP nodes for children is the responsibility of the parent's listeners. This is the fundamental cause of some still unsolved crashes in the node tool (for example, undoing 2 or more stacked LPE applications through the undo history dialog). In particular, if you first create the child SPObject of the namedview, then remove their XML nodes and add some others, there will be no change in the SP tree because the listener for namedview will only activate once you return from sp_namedview_build. I hope this explains the problem.
A quick hack is to explicitly invoke the necessary listeners (SPObject::sp_object_repr_child_removed, SPObject::sp_object_repr_child_added, etc.) on SPNamedview in the build function, but this is rather ugly. A far better solution is to change the build function for the new SPObject for guides. First, check the XML element name. If you encounter the old guide XML, convert it to the new XML using a series of setAttribute() calls and finally call your XML node's setCodeUnsafe() function to change its element name to the one for new guides. After that, execute normally like for new guide XML. Once this is ready, modify sp-object-repr.cpp so that the new SPObject is created for both old and new guide elements. This way the compatibility code is kept in the element it's related to, rather than in its parent.
Regards, Krzysztof