io/router: move transform state tracking from pointerCollector to Router

We're going to need transform tracking for the upcoming meta ops.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2021-11-03 12:32:26 +01:00
parent 529baed88b
commit 48a96305c8
2 changed files with 30 additions and 33 deletions
+7 -27
View File
@@ -82,12 +82,9 @@ type collectState struct {
// pointerCollector tracks the state needed to update an pointerQueue // pointerCollector tracks the state needed to update an pointerQueue
// from pointer ops. // from pointer ops.
type pointerCollector struct { type pointerCollector struct {
q *pointerQueue q *pointerQueue
state collectState state collectState
nodeStack []int nodeStack []int
transStack []f32.Affine2D
// states holds the storage for save/restore ops.
states []f32.Affine2D
} }
const ( const (
@@ -95,15 +92,12 @@ const (
areaEllipse areaEllipse
) )
func (c *pointerCollector) save(id int) { func (c *pointerCollector) resetState() {
if extra := id - len(c.states) + 1; extra > 0 { c.state = collectState{}
c.states = append(c.states, make([]f32.Affine2D, extra)...)
}
c.states[id] = c.state.t
} }
func (c *pointerCollector) load(id int) { func (c *pointerCollector) setTrans(t f32.Affine2D) {
c.state = collectState{t: c.states[id]} c.state.t = t
} }
func (c *pointerCollector) clip(op ops.ClipOp) { func (c *pointerCollector) clip(op ops.ClipOp) {
@@ -155,19 +149,6 @@ func (c *pointerCollector) popPass() {
c.state.pass-- c.state.pass--
} }
func (c *pointerCollector) transform(t f32.Affine2D, push bool) {
if push {
c.transStack = append(c.transStack, c.state.t)
}
c.state.t = c.state.t.Mul(t)
}
func (c *pointerCollector) popTransform() {
n := len(c.transStack)
c.state.t = c.transStack[n-1]
c.transStack = c.transStack[:n-1]
}
func (c *pointerCollector) inputOp(op pointer.InputOp, events *handlerEvents) { func (c *pointerCollector) inputOp(op pointer.InputOp, events *handlerEvents) {
area := -1 area := -1
if i := c.state.nodePlusOne - 1; i != -1 { if i := c.state.nodePlusOne - 1; i != -1 {
@@ -207,7 +188,6 @@ func (c *pointerCollector) reset(q *pointerQueue) {
q.reset() q.reset()
c.state = collectState{} c.state = collectState{}
c.nodeStack = c.nodeStack[:0] c.nodeStack = c.nodeStack[:0]
c.transStack = c.transStack[:0]
c.q = q c.q = q
} }
+23 -6
View File
@@ -15,6 +15,7 @@ import (
"image" "image"
"time" "time"
"gioui.org/f32"
"gioui.org/internal/ops" "gioui.org/internal/ops"
"gioui.org/io/clipboard" "gioui.org/io/clipboard"
"gioui.org/io/event" "gioui.org/io/event"
@@ -27,7 +28,9 @@ import (
// Router is a Queue implementation that routes events // Router is a Queue implementation that routes events
// to handlers declared in operation lists. // to handlers declared in operation lists.
type Router struct { type Router struct {
pointer struct { savedTrans []f32.Affine2D
transStack []f32.Affine2D
pointer struct {
queue pointerQueue queue pointerQueue
collector pointerCollector collector pointerCollector
} }
@@ -135,11 +138,13 @@ func (q *Router) Cursor() pointer.CursorName {
} }
func (q *Router) collect() { func (q *Router) collect() {
q.transStack = q.transStack[:0]
pc := &q.pointer.collector pc := &q.pointer.collector
pc.reset(&q.pointer.queue) pc.reset(&q.pointer.queue)
kc := &q.key.collector kc := &q.key.collector
*kc = keyCollector{q: &q.key.queue} *kc = keyCollector{q: &q.key.queue}
q.key.queue.Reset() q.key.queue.Reset()
var t f32.Affine2D
for encOp, ok := q.reader.Decode(); ok; encOp, ok = q.reader.Decode() { for encOp, ok := q.reader.Decode(); ok; encOp, ok = q.reader.Decode() {
switch ops.OpType(encOp.Data[0]) { switch ops.OpType(encOp.Data[0]) {
case ops.TypeInvalidate: case ops.TypeInvalidate:
@@ -160,10 +165,15 @@ func (q *Router) collect() {
q.cqueue.ProcessWriteClipboard(encOp.Refs) q.cqueue.ProcessWriteClipboard(encOp.Refs)
case ops.TypeSave: case ops.TypeSave:
id := ops.DecodeSave(encOp.Data) id := ops.DecodeSave(encOp.Data)
pc.save(id) if extra := id - len(q.savedTrans) + 1; extra > 0 {
q.savedTrans = append(q.savedTrans, make([]f32.Affine2D, extra)...)
}
q.savedTrans[id] = t
case ops.TypeLoad: case ops.TypeLoad:
id := ops.DecodeLoad(encOp.Data) id := ops.DecodeLoad(encOp.Data)
pc.load(id) t = q.savedTrans[id]
pc.resetState()
pc.setTrans(t)
// Pointer ops. // Pointer ops.
case ops.TypeClip: case ops.TypeClip:
@@ -177,10 +187,17 @@ func (q *Router) collect() {
case ops.TypePopPass: case ops.TypePopPass:
pc.popPass() pc.popPass()
case ops.TypeTransform: case ops.TypeTransform:
t, push := ops.DecodeTransform(encOp.Data) t2, push := ops.DecodeTransform(encOp.Data)
pc.transform(t, push) if push {
q.transStack = append(q.transStack, t)
}
t = t.Mul(t2)
pc.setTrans(t)
case ops.TypePopTransform: case ops.TypePopTransform:
pc.popTransform() n := len(q.transStack)
t = q.transStack[n-1]
q.transStack = q.transStack[:n-1]
pc.setTrans(t)
case ops.TypePointerInput: case ops.TypePointerInput:
bo := binary.LittleEndian bo := binary.LittleEndian
op := pointer.InputOp{ op := pointer.InputOp{