diff --git a/doc.go b/doc.go index cbd54d0..7b39821 100644 --- a/doc.go +++ b/doc.go @@ -29,7 +29,7 @@ package fejkdata // `template.drawGroup` as the data spells it, `template.drawGroupKey` as a // render reads it, `holdSet`, `renderScope`. // - pin — fixing which row of a table the render uses, which the draw fences replay: -// `pinSet`, `pinSet.pin`, `pathDraws.row`. +// `pinSet`, `pinSet.pin`, `table.drawIn`. // - family — a table and every table reaching it through a chain of // `table.parentT`, named by the root that chain ends at: `table.family`. // - whole — a read that lands on a `row`, so the row renders through its table's diff --git a/path.go b/path.go index 3fe216e..a65abd5 100644 --- a/path.go +++ b/path.go @@ -142,13 +142,12 @@ type pathWalk struct { draws *pathDraws } -// pathDraws is what a walk draws with: the session, and, for a held read of a, the -// hold keeping the variant drawn at each level, so paths sharing a prefix share it. -// a is a pointer: held inline, its level keys take an eager hold set to the heap. +// pathDraws is what a walk draws with: the session, and, for a held read, the hold +// keeping the variant drawn at each level of a, so paths sharing a prefix share it. type pathDraws struct { s *session held *hold - a *arm + a *arm // a pointer: its levels slice held here moves the render's hold set to the heap } // walkPath descends tail from n and returns the node it ends at: a folder or @@ -290,36 +289,11 @@ func readRow(p *pinSet, draws *pathDraws, t *table, sel string, draw bool) error return p.selectRow(t, sel) } if draw && draws != nil { - draws.row(p, t) + t.drawIn(draws.s, p) } return nil } -// row is the render's row of t: the one pinned in p, else one drawn inside the -// nearest pinned ancestor — its parent drawn inside that first where the ancestor -// is further up — or over the whole table, and pinned with its ancestors. -func (d *pathDraws) row(p *pinSet, t *table) int { - if r, ok := p.pinned(t); ok { - return r - } - r := -1 - for a := t.parentT; a != nil && r < 0; a = a.parentT { - if _, ok := p.pinned(a); !ok { - continue - } - if t.parentT != a { - d.row(p, t.parentT) - } - pr, _ := p.pinned(t.parentT) - r = t.drawUnder(d.s, pr) - } - if r < 0 { - r = t.draw(d.s) - } - p.pin(t, r) - return r -} - // variant is the variant of c the walk continues into: the one held for this level // of the read, drawn once, where the walk holds its draws; else one drawn afresh. func (d *pathDraws) variant(c *choice, rest []string) node { diff --git a/record.go b/record.go index b7e1067..7e4d868 100644 --- a/record.go +++ b/record.go @@ -159,7 +159,7 @@ func tableRecord(s *session, t *table, tail []string, sc renderScope) (node, err } switch n := n.(type) { case *table: - (&pathDraws{s: s}).row(&sc.hold().pins, n) + n.drawIn(s, &sc.hold().pins) return n, nil case *row: return n.t, nil diff --git a/table.go b/table.go index df254cb..23a9081 100644 --- a/table.go +++ b/table.go @@ -487,6 +487,31 @@ func (t *table) drawUnder(s *session, pr int) int { return rows[pickCum(s, ix.childCum[k])] } +// drawIn is the render's row of t: the one pinned in p, else one drawn inside the nearest +// pinned ancestor — its parent drawn inside that first where the ancestor is further up — or +// over the whole table, and pinned with its ancestors. +func (t *table) drawIn(s *session, p *pinSet) int { + if r, ok := p.pinned(t); ok { + return r + } + r := -1 + for a := t.parentT; a != nil && r < 0; a = a.parentT { + if _, ok := p.pinned(a); !ok { + continue + } + if t.parentT != a { + t.parentT.drawIn(s, p) + } + pr, _ := p.pinned(t.parentT) + r = t.drawUnder(s, pr) + } + if r < 0 { + r = t.draw(s) + } + p.pin(t, r) + return r +} + // descendant is the table named name among those linked to t, at any depth. func (t *table) descendant(name string) *table { if c, ok := t.children[name]; ok { diff --git a/todo.md b/todo.md index 2a87b86..274ce22 100644 --- a/todo.md +++ b/todo.md @@ -43,7 +43,7 @@ This round, in order: none is set. - Have the check mode report the tables a read draws, so `tableRead.drawn` and `entered`'s `pinsAncestors` flag stop restating `walkTable`'s draw condition and - `pathDraws.row`'s ancestor rule: a change to how a render draws rows still leaves the + `table.drawIn`'s ancestor rule: a change to how a render draws rows still leaves the fence proving the old rule. Hold a row rendered whole in `drawAt` beside `drawn`, so `pinSet` holds only what `pin` pins and `alternatives` needs no exception. Settle a cell of a municipality drawn whole beside a path pinning a region it is not in. Needs