
(yay, I'm back, sorta)
Since it's been brought up I don't think the suggestion of merging SPObject and SPRepr to solve our update problems is necessarily a good idea.
The main reason is just that with a unified representation we have to make a tradeoff between:
* an efficient representation for editing
or
* a representation that preserves the XML syntax tree during every transformation (i.e. we don't want Inkscape to chew up or discard arbitrary XML fragments which have no semantic meaning to us, but are important for other uses..)
Both of these are important goals for us, so I think dividing our representation into separate classes to address each of these needs is necessary.
We could still wrap SPObject/SPRepr pairs in another object, which would encapsulate our updating strategies for them. That _might_ be helpful, but I'd need to think about that some more.
FWIW, here are some of the updating problems I see:
1. the id binding problem
Currently, the SPObject <-> SPRepr binding is maintained by using XML fragment ids. This is IMO, more problematic than it's worth and forces us to impose ids on all XML nodes (including text nodes).
My existing plan is to do the mapping directly rather than relying on ids (I've done some of the preliminary work on this already; new code should use SPDocument::getObjectByRepr rather than SPDocument::getObjectById).
2. the authority problem
Are SPObjects or SPReprs authoritative? Not all our code is consistent in this regard, especially as it's often more convenient/efficient to update the SPObject directly.
I believe the answer should be that SPReprs are authoritative, though SPObjects can temporarily be out of sync ("dirty") with new changes, provided those changes are flushed to the SPRepr layer at key points, e.g. before committing an undo log.
(i.e. SPObject is essentially a cache for SPRepr, which functions as a backing store)
3. the manual update problem
Many times it's more efficient to make changes at the SPObject level rather than to the SPRepr.
Under the present system, this requires explicit calls to SPObject::updateRepr() to synchronize the state; if updateRepr() is called for every SPObject change, it becomes grossly inefficient. On the other hand, it's very tricky to defer these update calls until later, because mistakes are easy and they often get missed.
I think the solution is to automate the "lazy" updating of SPReprs, so we get the performance benefits of lazy updates without having to debug manual updating code in a bajillion places.
This is one thing that could (conceivably) be addressed in a wrapper class.
-mental