On Sat, Sep 29, 2012 at 11:35 AM, m...@mikesolomon.org <m...@mikesolomon.org> wrote: > > On 29 sept. 2012, at 10:59, Han-Wen Nienhuys <hanw...@gmail.com> wrote: > >> On Wed, Sep 26, 2012 at 10:40 PM, David Kastrup <d...@gnu.org> wrote: >>> Han-Wen Nienhuys <hanw...@gmail.com> writes: >>> >>>> In order to do cache invalidation, you will have to construct the >>>> reverse graph. If A.x depends on B.y, now A points to B. For proper >>>> cache invalidation, if B.y changes, then A.x becomes invalid. This >>>> means that A has to store a back-reference to B. Hence all pointers >>>> have to be stored both ways (including inverting 1-N relations into >>>> N-1 relations), and the both-way links have to be rewritten correctly >>>> during line breaking. >>> >>> You can assign a generational count to properties. If the generational >>> count of any dependency is higher than that of the dependent property, >>> it needs to get regenerated. As long as the dependencies don't get lost >>> (and we use arbitrary size integers, resetting for each session), this >>> should be pretty straightforward and not require backwards links. It >>> "just" requires double-checking your dependencies for change. >> >> But since the dependencies are also properties that could be >> invalidated, you'd have to recurse , so each property access would >> potentially expand into an almost infinite number of get_property >> calls. >> >> I think it is a much clearer abstraction to decide that each property >> can only be evaluated once, and that everything should be driven by >> callbacks. In fact, one thing I would suggest looking at is removing >> {before,after}_line_breaking which breaks this model somewhat. >> > > I agree 110%. The only corollary I'd add, which comes from my recent work, > is that pure properties be re-evaluatable all the time (meaning that one > should be allowed to arbitrarily flush the cache) to store better and better > approximations of things. For example, if one wants the pure heights of > cross-staff beamed stems, the approximation one can get before line breaking > is worse than that which one can get after. After line breaking, one could > theoretically run beam quanting using the pure heights and actual X > positions, whereas before, these X positions don't exist. So, pure > properties in LilyPond become progressively more accurate as they go > downstream, and once someone is positive that all the information is there to > evaluate the actual property, get_property (or get_extent or whatever) is > called.
pure-properties are misnamed. If they are always are recomputed, they should be called methods or even pure functions and not properties. Of course, if there is a cache, you have to think about a simple and rigorous scheme to know when the cache can be thrown away; the real problem is about caching data based on other grobs, since invalidation implies a lot more of pointer juggling > I agree about (before,after)_line_breaking. > > The single biggest offenders of this model, in my mind, are to be found in > the engraver stage. More specifically, I think that if we can get rid of the > Tweak_engraver such that every property is initialized via the Grob::Grob > (SCM basicprops) constructor (like in engraver.cc, for example) and not via > set_property at the engraver stage, everything else will be easier. You could make a separate routine that prepends sym/value pairs onto the immutable list; I'm not certain that this would intrinsically buy you anything, though. -- Han-Wen Nienhuys - han...@xs4all.nl - http://www.xs4all.nl/~hanwen _______________________________________________ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel