Re: [Fresco-devel] Bogus traversals (and patch)
Stefan Seefeld <[email protected]>
| Newsgroups | gmane.comp.video.fresco.devel |
|---|---|
| Message-ID | <[email protected]> |
Nick Lewycky wrote: > I found something strange while writing a Traversal for myself: it > wouldn't traverse through an RGBDecorator. > > With some investigation I found what may have been an optimization for > performance, but it's caused some contention with correctness (at least, > as far as I understand Fresco's design.) > > The Traversal system was doing the following: > Traversal calls Graphic->draw > Graphic->draw sets the foreground colour and calls > child_graphic->traverse(Traversal) then restores the colour and returns. what graphic is that ? It's a monographic, I assume, or else it probably wouldn't have a single 'child_graphic' to traverse. Then there is a problem with calling child_graphic->traverse directly, instead of traversal->traverse_child(child_graphic), as the latter takes additional (layout) parameters, i.e. the first corrupts the traversal stack... > What's supposed to happen is: > Traversal calls Graphic->draw > Graphic->draw sets the foreground colour and returns > Traversal calls Graphic->traverse > Graphic->traverse calls Traversal->traverse_child for each child of the > Traversal. what graphic does the traversal call 'draw' on, and what 'traverse' ? What you outline is not how it works. I hope the following can make this clear: Assume a graph with parent node 'A' and child node 'B'. You call A->traverse(t); which results in t->visit(A); which results in A->draw(t); That's where the attributes are set (if A is an RGBDecorator). Now if you return directly, the traversal has no idea that 'A' is a mono-graphic, i.e. that there is a child graphic to traverse. Thus 'A' has to do that inside its 'draw' method. Since RGBDecorator derives from MonoGraphic, and since MonoGraphic::traverse does just that, we only need to call MonoGraphic::traverse(t); inside A::draw, while the DrawingKit attributes are changed. That will trigger the subgraph to be traversed. Once that is done, we restore the attributes, and return. > The bug is that some graphics will go through their children instead of > going back through the Traversal's traverse_child function. If the > Traversal never calls draw or pick, then it will never be able to > traverse that part of the tree! that's right, 'draw' and 'pick' are the only implemented traversals right now. But I don't see how this could be made differently. You are talking about 'going back through the Traversal's traverse_child function'. How can that work ? How do you know (outside the polymorphic 'draw' or 'pick') that this graphic has children ? Regards, Stefan