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)
|
sc.hold().pins.pin(t.table, r)
|
||||||
render(s, t.table.pinnedRow, sc)
|
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:
|
case t.repeat > 1:
|
||||||
expand(s, t, sc)
|
expand(s, t, sc)
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -29,11 +29,7 @@ type draw struct {
|
|||||||
// linkRefs prove every step, so the walk cannot fail.
|
// linkRefs prove every step, so the walk cannot fail.
|
||||||
func readField(s *session, t *template, held *hold, sc renderScope, a arm) draw {
|
func readField(s *session, t *template, held *hold, sc renderScope, a arm) draw {
|
||||||
if s.trace != nil {
|
if s.trace != nil {
|
||||||
var table string
|
traceRead(s.trace, t, sc, a)
|
||||||
if sc.t != nil {
|
|
||||||
table = strings.Clone(sc.t.path)
|
|
||||||
}
|
|
||||||
s.trace.read(strings.Clone(sc.group), table, sc.row, a)
|
|
||||||
}
|
}
|
||||||
if !t.held[a.key] {
|
if !t.held[a.key] {
|
||||||
if len(a.tail) > 0 {
|
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 {
|
if r, done := d.value[a.path]; done {
|
||||||
return r
|
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)
|
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 {
|
if d.value == nil {
|
||||||
d.value = map[string]draw{}
|
d.value = map[string]draw{}
|
||||||
@@ -59,6 +56,18 @@ type renderTrace struct {
|
|||||||
repeatDepth int
|
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,
|
// 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
|
// the render's hold for its group, so its draw spans the render; for a sibling, or a
|
||||||
// bare reference, held.
|
// bare reference, held.
|
||||||
@@ -73,14 +82,15 @@ func readHold(held *hold, sc renderScope, a arm) *hold {
|
|||||||
// reference alone whose read drew null.
|
// reference alone whose read drew null.
|
||||||
func renderLeaf(s *session, n node, sc renderScope) draw {
|
func renderLeaf(s *session, n node, sc renderScope) draw {
|
||||||
n = resolveChoice(s, n)
|
n = resolveChoice(s, n)
|
||||||
if _, isNull := n.(*nullItem); isNull {
|
switch leaf := n.(type) {
|
||||||
|
case *nullItem:
|
||||||
return draw{null: true}
|
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)}
|
return 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolveChoice resolves a choice to one variant, so a bound head is a concrete node the
|
// 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
|
// 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
|
// template rendering, and the pin set a table's columns read their row from: a whole read's own,
|
||||||
// by value, and what is read from it reaches a map key, an interface or a func value only as a
|
// else the hold's. It passes by value, and what is read from it reaches a map key, an interface or
|
||||||
// copy; else sc, and with it every render's hold set, moves to the heap.
|
// a func value only as a copy; else sc, and with it every render's hold set, moves to the heap.
|
||||||
type renderScope struct {
|
type renderScope struct {
|
||||||
set *holdSet
|
set *holdSet
|
||||||
group string
|
group string
|
||||||
t *table
|
pins *pinSet
|
||||||
row int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func eagerHoldSet() holdSet {
|
func eagerHoldSet() holdSet {
|
||||||
@@ -52,6 +51,13 @@ func (sc renderScope) in(t *template) renderScope {
|
|||||||
return sc
|
return sc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sc renderScope) rows() *pinSet {
|
||||||
|
if sc.pins != nil {
|
||||||
|
return sc.pins
|
||||||
|
}
|
||||||
|
return &sc.hold().pins
|
||||||
|
}
|
||||||
|
|
||||||
func (sc renderScope) hold() *hold {
|
func (sc renderScope) hold() *hold {
|
||||||
if sc.group == "" {
|
if sc.group == "" {
|
||||||
return &sc.set.unnamed
|
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.
|
// over sc's hold; a table's columns read the row pinned there.
|
||||||
func renderRecord(s *session, t *template, columns []Column, sc renderScope) *Record {
|
func renderRecord(s *session, t *template, columns []Column, sc renderScope) *Record {
|
||||||
sc = sc.in(t)
|
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...)}
|
r := &Record{columns: append([]Column(nil), columns...)}
|
||||||
for i := range r.columns {
|
for i := range r.columns {
|
||||||
column := renderLeaf(s, t.fields[r.columns[i].Name], sc)
|
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:
|
case *nullItem:
|
||||||
return ""
|
return ""
|
||||||
case *table:
|
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)
|
return expand(s, n.formatTemplate, sc)
|
||||||
case *tableRow:
|
case *tableRow:
|
||||||
sc.t, sc.row = n.t, sc.hold().pins.mustRow(n.t)
|
|
||||||
return expand(s, n.t.formatTemplate, sc)
|
return expand(s, n.t.formatTemplate, sc)
|
||||||
case *tableColumn:
|
case *tableColumn:
|
||||||
if sc.t != n.t {
|
row := sc.rows().mustRow(n.t)
|
||||||
sc.t, sc.row = n.t, sc.hold().pins.mustRow(n.t)
|
if cell := n.t.cellTemplate(row, n.i); cell != nil {
|
||||||
}
|
|
||||||
if cell := n.t.cellTemplate(sc.row, n.i); cell != nil {
|
|
||||||
return render(s, cell, sc)
|
return render(s, cell, sc)
|
||||||
}
|
}
|
||||||
return n.t.cell(sc.row, n.i)
|
return n.t.cell(row, n.i)
|
||||||
case *template:
|
case *template:
|
||||||
sc = sc.in(n)
|
sc = sc.in(n)
|
||||||
if n.repeat == 1 {
|
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:
|
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
|
- 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.
|
`level`, `leaf`, `pins`, `drawn` and `draws` it leaves nil.
|
||||||
- Gather the family fence beside `drawWalk.check`: `checkFamilies`, `replayPairs`,
|
- Gather the family fence beside `drawWalk.check`: `checkFamilies`, `replayPairs`,
|
||||||
|
|||||||
Reference in New Issue
Block a user