Give a table's current row one owner, the pin set, and return a column's null from its read
This commit is contained in:
@@ -131,9 +131,6 @@ func renderRoot(s *session, t *template) {
|
||||
sc.hold().pins.pin(t.table, r)
|
||||
render(s, t.table.pinnedRow, sc)
|
||||
}
|
||||
case t.cellOf != nil:
|
||||
sc.t, sc.row = t.cellOf, t.cellRow
|
||||
render(s, t, sc)
|
||||
case t.repeat > 1:
|
||||
expand(s, t, sc)
|
||||
default:
|
||||
|
||||
@@ -29,11 +29,7 @@ type draw struct {
|
||||
// linkRefs prove every step, so the walk cannot fail.
|
||||
func readField(s *session, t *template, held *hold, sc renderScope, a arm) draw {
|
||||
if s.trace != nil {
|
||||
var table string
|
||||
if sc.t != nil {
|
||||
table = strings.Clone(sc.t.path)
|
||||
}
|
||||
s.trace.read(strings.Clone(sc.group), table, sc.row, a)
|
||||
traceRead(s.trace, t, sc, a)
|
||||
}
|
||||
if !t.held[a.key] {
|
||||
if len(a.tail) > 0 {
|
||||
@@ -45,6 +41,7 @@ func readField(s *session, t *template, held *hold, sc renderScope, a arm) draw
|
||||
if r, done := d.value[a.path]; done {
|
||||
return r
|
||||
}
|
||||
sc.pins = &d.pins
|
||||
r := renderLeaf(s, drawPath(t.head(a.key), a.tail, a.key, &d.pins, &pathDraws{s: s, held: d, a: &a}), sc)
|
||||
if d.value == nil {
|
||||
d.value = map[string]draw{}
|
||||
@@ -59,6 +56,18 @@ type renderTrace struct {
|
||||
repeatDepth int
|
||||
}
|
||||
|
||||
func traceRead(trace *renderTrace, t *template, sc renderScope, a arm) {
|
||||
var table string
|
||||
var row int
|
||||
switch {
|
||||
case t.cellOf != nil:
|
||||
table, row = t.cellOf.path, t.cellRow
|
||||
case t.table != nil:
|
||||
table, row = t.table.path, sc.rows().mustRow(t.table)
|
||||
}
|
||||
trace.read(strings.Clone(sc.group), strings.Clone(table), row, a)
|
||||
}
|
||||
|
||||
// readHold is the hold a held read keeps its draw in: for a reference that reads a path,
|
||||
// the render's hold for its group, so its draw spans the render; for a sibling, or a
|
||||
// bare reference, held.
|
||||
@@ -73,14 +82,15 @@ func readHold(held *hold, sc renderScope, a arm) *hold {
|
||||
// reference alone whose read drew null.
|
||||
func renderLeaf(s *session, n node, sc renderScope) draw {
|
||||
n = resolveChoice(s, n)
|
||||
if _, isNull := n.(*nullItem); isNull {
|
||||
switch leaf := n.(type) {
|
||||
case *nullItem:
|
||||
return draw{null: true}
|
||||
case *template:
|
||||
if leaf.readsColumn != nil {
|
||||
return readField(s, leaf, nil, sc.in(leaf), leaf.readsColumn.a)
|
||||
}
|
||||
r := draw{text: render(s, n, sc)}
|
||||
if t, _ := n.(*template); t != nil && t.readsColumn != nil {
|
||||
r.null = sc.in(t).hold().value[t.readsColumn.a.path].null
|
||||
}
|
||||
return r
|
||||
return draw{text: render(s, n, sc)}
|
||||
}
|
||||
|
||||
// resolveChoice resolves a choice to one variant, so a bound head is a concrete node the
|
||||
|
||||
+11
-5
@@ -11,14 +11,13 @@ type holdSet struct {
|
||||
}
|
||||
|
||||
// renderScope is where a render reads its reference paths: a hold set, in the draw group of the
|
||||
// template rendering, and the row a table's format is rendering, which its columns read. It passes
|
||||
// by value, and what is read from it reaches a map key, an interface or a func value only as a
|
||||
// copy; else sc, and with it every render's hold set, moves to the heap.
|
||||
// template rendering, and the pin set a table's columns read their row from: a whole read's own,
|
||||
// else the hold's. It passes by value, and what is read from it reaches a map key, an interface or
|
||||
// a func value only as a copy; else sc, and with it every render's hold set, moves to the heap.
|
||||
type renderScope struct {
|
||||
set *holdSet
|
||||
group string
|
||||
t *table
|
||||
row int
|
||||
pins *pinSet
|
||||
}
|
||||
|
||||
func eagerHoldSet() holdSet {
|
||||
@@ -52,6 +51,13 @@ func (sc renderScope) in(t *template) renderScope {
|
||||
return sc
|
||||
}
|
||||
|
||||
func (sc renderScope) rows() *pinSet {
|
||||
if sc.pins != nil {
|
||||
return sc.pins
|
||||
}
|
||||
return &sc.hold().pins
|
||||
}
|
||||
|
||||
func (sc renderScope) hold() *hold {
|
||||
if sc.group == "" {
|
||||
return &sc.set.unnamed
|
||||
|
||||
@@ -264,9 +264,6 @@ func recordOf(n node) (*template, []Column, error) {
|
||||
// over sc's hold; a table's columns read the row pinned there.
|
||||
func renderRecord(s *session, t *template, columns []Column, sc renderScope) *Record {
|
||||
sc = sc.in(t)
|
||||
if t.table != nil {
|
||||
sc.t, sc.row = t.table, sc.hold().pins.mustRow(t.table)
|
||||
}
|
||||
r := &Record{columns: append([]Column(nil), columns...)}
|
||||
for i := range r.columns {
|
||||
column := renderLeaf(s, t.fields[r.columns[i].Name], sc)
|
||||
|
||||
@@ -61,19 +61,18 @@ func render(s *session, n node, sc renderScope) string {
|
||||
case *nullItem:
|
||||
return ""
|
||||
case *table:
|
||||
sc.t, sc.row = n, n.drawRow(s)
|
||||
var own pinSet
|
||||
own.add(n, n.drawRow(s))
|
||||
sc.pins = &own
|
||||
return expand(s, n.formatTemplate, sc)
|
||||
case *tableRow:
|
||||
sc.t, sc.row = n.t, sc.hold().pins.mustRow(n.t)
|
||||
return expand(s, n.t.formatTemplate, sc)
|
||||
case *tableColumn:
|
||||
if sc.t != n.t {
|
||||
sc.t, sc.row = n.t, sc.hold().pins.mustRow(n.t)
|
||||
}
|
||||
if cell := n.t.cellTemplate(sc.row, n.i); cell != nil {
|
||||
row := sc.rows().mustRow(n.t)
|
||||
if cell := n.t.cellTemplate(row, n.i); cell != nil {
|
||||
return render(s, cell, sc)
|
||||
}
|
||||
return n.t.cell(sc.row, n.i)
|
||||
return n.t.cell(row, n.i)
|
||||
case *template:
|
||||
sc = sc.in(n)
|
||||
if n.repeat == 1 {
|
||||
|
||||
@@ -21,8 +21,6 @@ Self-sufficiency 5.6), every seat capped by Locality, and all nine naming
|
||||
|
||||
This round, in order:
|
||||
|
||||
- Give a table's current row one owner: `renderScope.t` and `row` hold it beside the
|
||||
`pinSet`, and `renderLeaf` reads a column's null back from a hold `readField` wrote.
|
||||
- Split `walkPath`'s four modes, so a caller does not select a behaviour by which of
|
||||
`level`, `leaf`, `pins`, `drawn` and `draws` it leaves nil.
|
||||
- Gather the family fence beside `drawWalk.check`: `checkFamilies`, `replayPairs`,
|
||||
|
||||
Reference in New Issue
Block a user