mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 18:05:35 +00:00
ui: let OpsReader keep track of references
Instead of exposing the entire reference slice, return the relevant references from Next. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
@@ -667,7 +667,7 @@ func (d *drawOps) newPathOp() *pathOp {
|
|||||||
func (d *drawOps) collectOps(r *ui.OpsReader, state drawState) int {
|
func (d *drawOps) collectOps(r *ui.OpsReader, state drawState) int {
|
||||||
loop:
|
loop:
|
||||||
for {
|
for {
|
||||||
data, ok := r.Decode()
|
data, refs, ok := r.Decode()
|
||||||
if !ok {
|
if !ok {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -678,7 +678,7 @@ loop:
|
|||||||
state.t = state.t.Mul(op.Transform)
|
state.t = state.t.Mul(op.Transform)
|
||||||
case ops.TypeClip:
|
case ops.TypeClip:
|
||||||
var op gdraw.OpClip
|
var op gdraw.OpClip
|
||||||
op.Decode(data, r.Refs)
|
op.Decode(data, refs)
|
||||||
if op.Path == nil {
|
if op.Path == nil {
|
||||||
state.clip = f32.Rectangle{}
|
state.clip = f32.Rectangle{}
|
||||||
continue
|
continue
|
||||||
@@ -702,17 +702,17 @@ loop:
|
|||||||
}
|
}
|
||||||
case ops.TypeColor:
|
case ops.TypeColor:
|
||||||
var op gdraw.OpColor
|
var op gdraw.OpColor
|
||||||
op.Decode(data, r.Refs)
|
op.Decode(data, refs)
|
||||||
state.img = nil
|
state.img = nil
|
||||||
state.color = op.Col
|
state.color = op.Col
|
||||||
case ops.TypeImage:
|
case ops.TypeImage:
|
||||||
var op gdraw.OpImage
|
var op gdraw.OpImage
|
||||||
op.Decode(data, r.Refs)
|
op.Decode(data, refs)
|
||||||
state.img = op.Img
|
state.img = op.Img
|
||||||
state.imgRect = op.Rect
|
state.imgRect = op.Rect
|
||||||
case ops.TypeDraw:
|
case ops.TypeDraw:
|
||||||
var op gdraw.OpDraw
|
var op gdraw.OpDraw
|
||||||
op.Decode(data, r.Refs)
|
op.Decode(data, refs)
|
||||||
off := state.t.Transform(f32.Point{})
|
off := state.t.Transform(f32.Point{})
|
||||||
clip := state.clip.Intersect(op.Rect.Add(off))
|
clip := state.clip.Intersect(op.Rect.Add(off))
|
||||||
if clip.Empty() {
|
if clip.Empty() {
|
||||||
|
|||||||
+1
-1
@@ -156,7 +156,7 @@ func collectRedraws(r *ui.OpsReader) (time.Time, bool) {
|
|||||||
var t time.Time
|
var t time.Time
|
||||||
redraw := false
|
redraw := false
|
||||||
for {
|
for {
|
||||||
data, ok := r.Decode()
|
data, _, ok := r.Decode()
|
||||||
if !ok {
|
if !ok {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-15
@@ -31,13 +31,11 @@ func (i OpImage) Add(o *ui.Ops) {
|
|||||||
data := make([]byte, ops.TypeImageLen)
|
data := make([]byte, ops.TypeImageLen)
|
||||||
data[0] = byte(ops.TypeImage)
|
data[0] = byte(ops.TypeImage)
|
||||||
bo := binary.LittleEndian
|
bo := binary.LittleEndian
|
||||||
ref := o.Ref(i.Img)
|
bo.PutUint32(data[1:], uint32(i.Rect.Min.X))
|
||||||
bo.PutUint32(data[1:], uint32(ref))
|
bo.PutUint32(data[5:], uint32(i.Rect.Min.Y))
|
||||||
bo.PutUint32(data[5:], uint32(i.Rect.Min.X))
|
bo.PutUint32(data[9:], uint32(i.Rect.Max.X))
|
||||||
bo.PutUint32(data[9:], uint32(i.Rect.Min.Y))
|
bo.PutUint32(data[13:], uint32(i.Rect.Max.Y))
|
||||||
bo.PutUint32(data[13:], uint32(i.Rect.Max.X))
|
o.Write(data, []interface{}{i.Img})
|
||||||
bo.PutUint32(data[17:], uint32(i.Rect.Max.Y))
|
|
||||||
o.Write(data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *OpImage) Decode(data []byte, refs []interface{}) {
|
func (i *OpImage) Decode(data []byte, refs []interface{}) {
|
||||||
@@ -45,19 +43,18 @@ func (i *OpImage) Decode(data []byte, refs []interface{}) {
|
|||||||
if ops.OpType(data[0]) != ops.TypeImage {
|
if ops.OpType(data[0]) != ops.TypeImage {
|
||||||
panic("invalid op")
|
panic("invalid op")
|
||||||
}
|
}
|
||||||
ref := int(bo.Uint32(data[1:]))
|
|
||||||
sr := image.Rectangle{
|
sr := image.Rectangle{
|
||||||
Min: image.Point{
|
Min: image.Point{
|
||||||
X: int(bo.Uint32(data[5:])),
|
X: int(bo.Uint32(data[1:])),
|
||||||
Y: int(bo.Uint32(data[9:])),
|
Y: int(bo.Uint32(data[5:])),
|
||||||
},
|
},
|
||||||
Max: image.Point{
|
Max: image.Point{
|
||||||
X: int(bo.Uint32(data[13:])),
|
X: int(bo.Uint32(data[9:])),
|
||||||
Y: int(bo.Uint32(data[17:])),
|
Y: int(bo.Uint32(data[13:])),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
*i = OpImage{
|
*i = OpImage{
|
||||||
Img: refs[ref].(image.Image),
|
Img: refs[0].(image.Image),
|
||||||
Rect: sr,
|
Rect: sr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,7 +66,7 @@ func (c OpColor) Add(o *ui.Ops) {
|
|||||||
data[2] = c.Col.G
|
data[2] = c.Col.G
|
||||||
data[3] = c.Col.B
|
data[3] = c.Col.B
|
||||||
data[4] = c.Col.A
|
data[4] = c.Col.A
|
||||||
o.Write(data)
|
o.Write(data, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *OpColor) Decode(data []byte, refs []interface{}) {
|
func (c *OpColor) Decode(data []byte, refs []interface{}) {
|
||||||
@@ -94,7 +91,7 @@ func (d OpDraw) Add(o *ui.Ops) {
|
|||||||
bo.PutUint32(data[5:], math.Float32bits(d.Rect.Min.Y))
|
bo.PutUint32(data[5:], math.Float32bits(d.Rect.Min.Y))
|
||||||
bo.PutUint32(data[9:], math.Float32bits(d.Rect.Max.X))
|
bo.PutUint32(data[9:], math.Float32bits(d.Rect.Max.X))
|
||||||
bo.PutUint32(data[13:], math.Float32bits(d.Rect.Max.Y))
|
bo.PutUint32(data[13:], math.Float32bits(d.Rect.Max.Y))
|
||||||
o.Write(data)
|
o.Write(data, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *OpDraw) Decode(data []byte, refs []interface{}) {
|
func (d *OpDraw) Decode(data []byte, refs []interface{}) {
|
||||||
|
|||||||
+2
-8
@@ -3,7 +3,6 @@
|
|||||||
package draw
|
package draw
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"gioui.org/ui"
|
"gioui.org/ui"
|
||||||
@@ -37,20 +36,15 @@ func (p *Path) Data() interface{} {
|
|||||||
func (c OpClip) Add(o *ui.Ops) {
|
func (c OpClip) Add(o *ui.Ops) {
|
||||||
data := make([]byte, ops.TypeClipLen)
|
data := make([]byte, ops.TypeClipLen)
|
||||||
data[0] = byte(ops.TypeClip)
|
data[0] = byte(ops.TypeClip)
|
||||||
bo := binary.LittleEndian
|
o.Write(data, []interface{}{c.Path})
|
||||||
ref := o.Ref(c.Path)
|
|
||||||
bo.PutUint32(data[1:], uint32(ref))
|
|
||||||
o.Write(data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *OpClip) Decode(d []byte, refs []interface{}) {
|
func (c *OpClip) Decode(d []byte, refs []interface{}) {
|
||||||
bo := binary.LittleEndian
|
|
||||||
if ops.OpType(d[0]) != ops.TypeClip {
|
if ops.OpType(d[0]) != ops.TypeClip {
|
||||||
panic("invalid op")
|
panic("invalid op")
|
||||||
}
|
}
|
||||||
ref := int(bo.Uint32(d[1:]))
|
|
||||||
*c = OpClip{
|
*c = OpClip{
|
||||||
Path: refs[ref].(*Path),
|
Path: refs[0].(*Path),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+25
-7
@@ -2,8 +2,11 @@ package ops
|
|||||||
|
|
||||||
type OpType byte
|
type OpType byte
|
||||||
|
|
||||||
|
// Start at a high number for easier debugging.
|
||||||
|
const FirstOpIndex = 200
|
||||||
|
|
||||||
const (
|
const (
|
||||||
TypeBlockDef OpType = iota
|
TypeBlockDef OpType = iota + FirstOpIndex
|
||||||
TypeBlock
|
TypeBlock
|
||||||
TypeTransform
|
TypeTransform
|
||||||
TypeLayer
|
TypeLayer
|
||||||
@@ -20,18 +23,33 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
TypeBlockDefLen = 1 + 4
|
TypeBlockDefLen = 1 + 4 + 4
|
||||||
TypeBlockLen = 1 + 4
|
TypeBlockLen = 1 + 4 + 4
|
||||||
TypeTransformLen = 1 + 4*2
|
TypeTransformLen = 1 + 4*2
|
||||||
TypeLayerLen = 1
|
TypeLayerLen = 1
|
||||||
TypeRedrawLen = 1 + 8
|
TypeRedrawLen = 1 + 8
|
||||||
TypeClipLen = 1 + 4
|
TypeClipLen = 1
|
||||||
TypeImageLen = 1 + 4 + 4*4
|
TypeImageLen = 1 + 4*4
|
||||||
TypeDrawLen = 1 + 4*4
|
TypeDrawLen = 1 + 4*4
|
||||||
TypeColorLen = 1 + 4
|
TypeColorLen = 1 + 4
|
||||||
TypePointerHandlerLen = 1 + 4 + 4 + 1
|
TypePointerHandlerLen = 1 + 1
|
||||||
TypeKeyHandlerLen = 1 + 4 + 1
|
TypeKeyHandlerLen = 1 + 1
|
||||||
TypeHideInputLen = 1
|
TypeHideInputLen = 1
|
||||||
TypePushLen = 1
|
TypePushLen = 1
|
||||||
TypePopLen = 1
|
TypePopLen = 1
|
||||||
|
|
||||||
|
TypeBlockDefRefs = 0
|
||||||
|
TypeBlockRefs = 0
|
||||||
|
TypeTransformRefs = 0
|
||||||
|
TypeLayerRefs = 0
|
||||||
|
TypeRedrawRefs = 0
|
||||||
|
TypeClipRefs = 1
|
||||||
|
TypeImageRefs = 1
|
||||||
|
TypeDrawRefs = 0
|
||||||
|
TypeColorRefs = 0
|
||||||
|
TypePointerHandlerRefs = 2
|
||||||
|
TypeKeyHandlerRefs = 1
|
||||||
|
TypeHideInputRefs = 0
|
||||||
|
TypePushRefs = 0
|
||||||
|
TypePopRefs = 0
|
||||||
)
|
)
|
||||||
|
|||||||
+3
-9
@@ -3,8 +3,6 @@
|
|||||||
package key
|
package key
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
|
||||||
|
|
||||||
"gioui.org/ui"
|
"gioui.org/ui"
|
||||||
"gioui.org/ui/internal/ops"
|
"gioui.org/ui/internal/ops"
|
||||||
)
|
)
|
||||||
@@ -73,30 +71,26 @@ const (
|
|||||||
func (h OpHandler) Add(o *ui.Ops) {
|
func (h OpHandler) Add(o *ui.Ops) {
|
||||||
data := make([]byte, ops.TypeKeyHandlerLen)
|
data := make([]byte, ops.TypeKeyHandlerLen)
|
||||||
data[0] = byte(ops.TypeKeyHandler)
|
data[0] = byte(ops.TypeKeyHandler)
|
||||||
bo := binary.LittleEndian
|
|
||||||
if h.Focus {
|
if h.Focus {
|
||||||
data[1] = 1
|
data[1] = 1
|
||||||
}
|
}
|
||||||
bo.PutUint32(data[2:], uint32(o.Ref(h.Key)))
|
o.Write(data, []interface{}{h.Key})
|
||||||
o.Write(data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *OpHandler) Decode(d []byte, refs []interface{}) {
|
func (h *OpHandler) Decode(d []byte, refs []interface{}) {
|
||||||
bo := binary.LittleEndian
|
|
||||||
if ops.OpType(d[0]) != ops.TypeKeyHandler {
|
if ops.OpType(d[0]) != ops.TypeKeyHandler {
|
||||||
panic("invalid op")
|
panic("invalid op")
|
||||||
}
|
}
|
||||||
key := int(bo.Uint32(d[2:]))
|
|
||||||
*h = OpHandler{
|
*h = OpHandler{
|
||||||
Focus: d[1] != 0,
|
Focus: d[1] != 0,
|
||||||
Key: refs[key].(Key),
|
Key: refs[0].(Key),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h OpHideInput) Add(o *ui.Ops) {
|
func (h OpHideInput) Add(o *ui.Ops) {
|
||||||
data := make([]byte, ops.TypeHideInputLen)
|
data := make([]byte, ops.TypeHideInputLen)
|
||||||
data[0] = byte(ops.TypeHideInput)
|
data[0] = byte(ops.TypeHideInput)
|
||||||
o.Write(data)
|
o.Write(data, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Edit) ImplementsEvent() {}
|
func (Edit) ImplementsEvent() {}
|
||||||
|
|||||||
+2
-2
@@ -80,14 +80,14 @@ func resolveFocus(r *ui.OpsReader, focus Key) (Key, listenerPriority, bool) {
|
|||||||
var hide bool
|
var hide bool
|
||||||
loop:
|
loop:
|
||||||
for {
|
for {
|
||||||
data, ok := r.Decode()
|
data, refs, ok := r.Decode()
|
||||||
if !ok {
|
if !ok {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch ops.OpType(data[0]) {
|
switch ops.OpType(data[0]) {
|
||||||
case ops.TypeKeyHandler:
|
case ops.TypeKeyHandler:
|
||||||
var op OpHandler
|
var op OpHandler
|
||||||
op.Decode(data, r.Refs)
|
op.Decode(data, refs)
|
||||||
var newPri listenerPriority
|
var newPri listenerPriority
|
||||||
switch {
|
switch {
|
||||||
case op.Focus:
|
case op.Focus:
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
// Ops holds a list of serialized Ops.
|
// Ops holds a list of serialized Ops.
|
||||||
type Ops struct {
|
type Ops struct {
|
||||||
// Stack of block start indices.
|
// Stack of block start indices.
|
||||||
stack []int
|
stack []pc
|
||||||
// Serialized ops.
|
// Serialized ops.
|
||||||
data []byte
|
data []byte
|
||||||
// Op references.
|
// Op references.
|
||||||
@@ -17,17 +17,22 @@ type Ops struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type OpsReader struct {
|
type OpsReader struct {
|
||||||
pc int
|
pc pc
|
||||||
stack []block
|
stack []block
|
||||||
Refs []interface{}
|
refs []interface{}
|
||||||
data []byte
|
data []byte
|
||||||
|
|
||||||
pseudoOp [1]byte
|
pseudoOp [1]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
type block struct {
|
type block struct {
|
||||||
retPC int
|
retPC pc
|
||||||
endPC int
|
endPC pc
|
||||||
|
}
|
||||||
|
|
||||||
|
type pc struct {
|
||||||
|
data int
|
||||||
|
refs int
|
||||||
}
|
}
|
||||||
|
|
||||||
var typeLengths = [...]int{
|
var typeLengths = [...]int{
|
||||||
@@ -47,16 +52,51 @@ var typeLengths = [...]int{
|
|||||||
ops.TypePopLen,
|
ops.TypePopLen,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var refLengths = [...]int{
|
||||||
|
ops.TypeBlockDefRefs,
|
||||||
|
ops.TypeBlockRefs,
|
||||||
|
ops.TypeTransformRefs,
|
||||||
|
ops.TypeLayerRefs,
|
||||||
|
ops.TypeRedrawRefs,
|
||||||
|
ops.TypeClipRefs,
|
||||||
|
ops.TypeImageRefs,
|
||||||
|
ops.TypeDrawRefs,
|
||||||
|
ops.TypeColorRefs,
|
||||||
|
ops.TypePointerHandlerRefs,
|
||||||
|
ops.TypeKeyHandlerRefs,
|
||||||
|
ops.TypeHideInputRefs,
|
||||||
|
ops.TypePushRefs,
|
||||||
|
ops.TypePopRefs,
|
||||||
|
}
|
||||||
|
|
||||||
type OpBlock struct {
|
type OpBlock struct {
|
||||||
idx int
|
pc pc
|
||||||
|
}
|
||||||
|
|
||||||
|
type opBlockDef struct {
|
||||||
|
endpc pc
|
||||||
}
|
}
|
||||||
|
|
||||||
// Begin a block of ops.
|
// Begin a block of ops.
|
||||||
func (o *Ops) Begin() {
|
func (o *Ops) Begin() {
|
||||||
o.stack = append(o.stack, o.Size())
|
o.stack = append(o.stack, o.pc())
|
||||||
data := make([]byte, ops.TypeBlockDefLen)
|
// Make room for a block definition. Filled out in End.
|
||||||
data[0] = byte(ops.TypeBlockDef)
|
o.data = append(o.data, make([]byte, ops.TypeBlockDefLen)...)
|
||||||
o.Write(data)
|
}
|
||||||
|
|
||||||
|
func (op *opBlockDef) decode(data []byte) {
|
||||||
|
if ops.OpType(data[0]) != ops.TypeBlockDef {
|
||||||
|
panic("invalid op")
|
||||||
|
}
|
||||||
|
bo := binary.LittleEndian
|
||||||
|
dataIdx := int(bo.Uint32(data[1:]))
|
||||||
|
refsIdx := int(bo.Uint32(data[5:]))
|
||||||
|
*op = opBlockDef{
|
||||||
|
endpc: pc{
|
||||||
|
data: dataIdx,
|
||||||
|
refs: refsIdx,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// End the most recent block and return
|
// End the most recent block and return
|
||||||
@@ -64,9 +104,13 @@ func (o *Ops) Begin() {
|
|||||||
func (o *Ops) End() OpBlock {
|
func (o *Ops) End() OpBlock {
|
||||||
start := o.stack[len(o.stack)-1]
|
start := o.stack[len(o.stack)-1]
|
||||||
o.stack = o.stack[:len(o.stack)-1]
|
o.stack = o.stack[:len(o.stack)-1]
|
||||||
blockLen := o.Size() - start
|
pc := o.pc()
|
||||||
|
// Write the block header reserved in Begin.
|
||||||
|
data := o.data[start.data : start.data+ops.TypeBlockDefLen]
|
||||||
|
data[0] = byte(ops.TypeBlockDef)
|
||||||
bo := binary.LittleEndian
|
bo := binary.LittleEndian
|
||||||
bo.PutUint32(o.data[start+1:], uint32(blockLen))
|
bo.PutUint32(data[1:], uint32(pc.data))
|
||||||
|
bo.PutUint32(data[5:], uint32(pc.refs))
|
||||||
return OpBlock{start}
|
return OpBlock{start}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,41 +121,51 @@ func (o *Ops) Reset() {
|
|||||||
o.data = o.data[:0]
|
o.data = o.data[:0]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Ops) Ref(r interface{}) int {
|
func (o *Ops) Write(op []byte, refs []interface{}) {
|
||||||
o.refs = append(o.refs, r)
|
|
||||||
return len(o.refs) - 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *Ops) Write(op []byte) {
|
|
||||||
o.data = append(o.data, op...)
|
o.data = append(o.data, op...)
|
||||||
|
o.refs = append(o.refs, refs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size returns the length of the serialized Op data.
|
func (o *Ops) pc() pc {
|
||||||
func (o *Ops) Size() int {
|
return pc{data: len(o.data), refs: len(o.refs)}
|
||||||
return len(o.data)
|
}
|
||||||
|
|
||||||
|
func (b *OpBlock) decode(data []byte) {
|
||||||
|
if ops.OpType(data[0]) != ops.TypeBlock {
|
||||||
|
panic("invalid op")
|
||||||
|
}
|
||||||
|
bo := binary.LittleEndian
|
||||||
|
dataIdx := int(bo.Uint32(data[1:]))
|
||||||
|
refsIdx := int(bo.Uint32(data[5:]))
|
||||||
|
*b = OpBlock{
|
||||||
|
pc: pc{
|
||||||
|
data: dataIdx,
|
||||||
|
refs: refsIdx,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b OpBlock) Add(o *Ops) {
|
func (b OpBlock) Add(o *Ops) {
|
||||||
data := make([]byte, ops.TypeBlockLen)
|
data := make([]byte, ops.TypeBlockLen)
|
||||||
data[0] = byte(ops.TypeBlock)
|
data[0] = byte(ops.TypeBlock)
|
||||||
bo := binary.LittleEndian
|
bo := binary.LittleEndian
|
||||||
bo.PutUint32(data[1:], uint32(b.idx))
|
bo.PutUint32(data[1:], uint32(b.pc.data))
|
||||||
o.Write(data)
|
bo.PutUint32(data[5:], uint32(b.pc.refs))
|
||||||
|
o.Write(data, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset start reading from the op list.
|
// Reset start reading from the op list.
|
||||||
func (r *OpsReader) Reset(ops *Ops) {
|
func (r *OpsReader) Reset(ops *Ops) {
|
||||||
r.Refs = ops.refs
|
r.refs = ops.refs
|
||||||
r.data = ops.data
|
r.data = ops.data
|
||||||
r.stack = r.stack[:0]
|
r.stack = r.stack[:0]
|
||||||
r.pc = 0
|
r.pc = pc{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *OpsReader) Decode() ([]byte, bool) {
|
func (r *OpsReader) Decode() ([]byte, []interface{}, bool) {
|
||||||
bo := binary.LittleEndian
|
|
||||||
for {
|
for {
|
||||||
if r.pc == len(r.data) {
|
if r.pc.data == len(r.data) {
|
||||||
return nil, false
|
return nil, nil, false
|
||||||
}
|
}
|
||||||
if len(r.stack) > 0 {
|
if len(r.stack) > 0 {
|
||||||
b := r.stack[len(r.stack)-1]
|
b := r.stack[len(r.stack)-1]
|
||||||
@@ -119,28 +173,40 @@ func (r *OpsReader) Decode() ([]byte, bool) {
|
|||||||
r.pc = b.retPC
|
r.pc = b.retPC
|
||||||
r.stack = r.stack[:len(r.stack)-1]
|
r.stack = r.stack[:len(r.stack)-1]
|
||||||
r.pseudoOp[0] = byte(ops.TypePop)
|
r.pseudoOp[0] = byte(ops.TypePop)
|
||||||
return r.pseudoOp[:], true
|
return r.pseudoOp[:], nil, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t := ops.OpType(r.data[r.pc])
|
t := ops.OpType(r.data[r.pc.data])
|
||||||
n := typeLengths[t]
|
n := typeLengths[t-ops.FirstOpIndex]
|
||||||
data := r.data[r.pc : r.pc+n]
|
nrefs := refLengths[t-ops.FirstOpIndex]
|
||||||
|
data := r.data[r.pc.data : r.pc.data+n]
|
||||||
|
refs := r.refs[r.pc.refs : r.pc.refs+nrefs]
|
||||||
switch t {
|
switch t {
|
||||||
case ops.TypeBlock:
|
case ops.TypeBlock:
|
||||||
blockIdx := int(bo.Uint32(data[1:]))
|
var op OpBlock
|
||||||
if ops.OpType(r.data[blockIdx]) != ops.TypeBlockDef {
|
op.decode(data)
|
||||||
|
if ops.OpType(r.data[op.pc.data]) != ops.TypeBlockDef {
|
||||||
panic("invalid block reference")
|
panic("invalid block reference")
|
||||||
}
|
}
|
||||||
blockLen := int(bo.Uint32(r.data[blockIdx+1:]))
|
var opDef opBlockDef
|
||||||
r.stack = append(r.stack, block{r.pc + n, blockIdx + blockLen})
|
opDef.decode(r.data[op.pc.data : op.pc.data+ops.TypeBlockDefLen])
|
||||||
r.pc = blockIdx + ops.TypeBlockDefLen
|
retPC := r.pc
|
||||||
|
retPC.data += n
|
||||||
|
retPC.refs += nrefs
|
||||||
|
r.stack = append(r.stack, block{retPC: retPC, endPC: opDef.endpc})
|
||||||
|
r.pc = op.pc
|
||||||
|
r.pc.data += ops.TypeBlockDefLen
|
||||||
|
r.pc.refs += ops.TypeBlockDefRefs
|
||||||
r.pseudoOp[0] = byte(ops.TypePush)
|
r.pseudoOp[0] = byte(ops.TypePush)
|
||||||
return r.pseudoOp[:], true
|
return r.pseudoOp[:], nil, true
|
||||||
case ops.TypeBlockDef:
|
case ops.TypeBlockDef:
|
||||||
r.pc += int(bo.Uint32(data[1:]))
|
var op opBlockDef
|
||||||
|
op.decode(data)
|
||||||
|
r.pc = op.endpc
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
r.pc += n
|
r.pc.data += n
|
||||||
return data, true
|
r.pc.refs += nrefs
|
||||||
|
return data, refs, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-10
@@ -3,7 +3,6 @@
|
|||||||
package pointer
|
package pointer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gioui.org/ui"
|
"gioui.org/ui"
|
||||||
@@ -72,26 +71,20 @@ const (
|
|||||||
func (h OpHandler) Add(o *ui.Ops) {
|
func (h OpHandler) Add(o *ui.Ops) {
|
||||||
data := make([]byte, ops.TypePointerHandlerLen)
|
data := make([]byte, ops.TypePointerHandlerLen)
|
||||||
data[0] = byte(ops.TypePointerHandler)
|
data[0] = byte(ops.TypePointerHandler)
|
||||||
bo := binary.LittleEndian
|
|
||||||
if h.Grab {
|
if h.Grab {
|
||||||
data[1] = 1
|
data[1] = 1
|
||||||
}
|
}
|
||||||
bo.PutUint32(data[2:], uint32(o.Ref(h.Key)))
|
o.Write(data, []interface{}{h.Key, h.Area})
|
||||||
bo.PutUint32(data[6:], uint32(o.Ref(h.Area)))
|
|
||||||
o.Write(data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *OpHandler) Decode(d []byte, refs []interface{}) {
|
func (h *OpHandler) Decode(d []byte, refs []interface{}) {
|
||||||
bo := binary.LittleEndian
|
|
||||||
if ops.OpType(d[0]) != ops.TypePointerHandler {
|
if ops.OpType(d[0]) != ops.TypePointerHandler {
|
||||||
panic("invalid op")
|
panic("invalid op")
|
||||||
}
|
}
|
||||||
key := int(bo.Uint32(d[2:]))
|
|
||||||
area := int(bo.Uint32(d[6:]))
|
|
||||||
*h = OpHandler{
|
*h = OpHandler{
|
||||||
Grab: d[1] != 0,
|
Grab: d[1] != 0,
|
||||||
Key: refs[key].(Key),
|
Key: refs[0].(Key),
|
||||||
Area: refs[area].(Area),
|
Area: refs[1].(Area),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -39,7 +39,7 @@ type handler struct {
|
|||||||
|
|
||||||
func (q *Queue) collectHandlers(r *ui.OpsReader, t ui.Transform, layer int) {
|
func (q *Queue) collectHandlers(r *ui.OpsReader, t ui.Transform, layer int) {
|
||||||
for {
|
for {
|
||||||
data, ok := r.Decode()
|
data, refs, ok := r.Decode()
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ func (q *Queue) collectHandlers(r *ui.OpsReader, t ui.Transform, layer int) {
|
|||||||
t = t.Mul(op.Transform)
|
t = t.Mul(op.Transform)
|
||||||
case ops.TypePointerHandler:
|
case ops.TypePointerHandler:
|
||||||
var op OpHandler
|
var op OpHandler
|
||||||
op.Decode(data, r.Refs)
|
op.Decode(data, refs)
|
||||||
q.hitTree = append(q.hitTree, hitNode{level: layer, key: op.Key})
|
q.hitTree = append(q.hitTree, hitNode{level: layer, key: op.Key})
|
||||||
h, ok := q.handlers[op.Key]
|
h, ok := q.handlers[op.Key]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ func (r OpRedraw) Add(o *Ops) {
|
|||||||
bo.PutUint64(data[1:], uint64(nanos))
|
bo.PutUint64(data[1:], uint64(nanos))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
o.Write(data)
|
o.Write(data, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *OpRedraw) Decode(d []byte) {
|
func (r *OpRedraw) Decode(d []byte) {
|
||||||
@@ -110,7 +110,7 @@ func (t OpTransform) Add(o *Ops) {
|
|||||||
bo := binary.LittleEndian
|
bo := binary.LittleEndian
|
||||||
bo.PutUint32(data[1:], math.Float32bits(t.Transform.offset.X))
|
bo.PutUint32(data[1:], math.Float32bits(t.Transform.offset.X))
|
||||||
bo.PutUint32(data[5:], math.Float32bits(t.Transform.offset.Y))
|
bo.PutUint32(data[5:], math.Float32bits(t.Transform.offset.Y))
|
||||||
o.Write(data)
|
o.Write(data, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *OpTransform) Decode(d []byte) {
|
func (t *OpTransform) Decode(d []byte) {
|
||||||
@@ -129,7 +129,7 @@ func (t *OpTransform) Decode(d []byte) {
|
|||||||
func (l OpLayer) Add(o *Ops) {
|
func (l OpLayer) Add(o *Ops) {
|
||||||
data := make([]byte, ops.TypeLayerLen)
|
data := make([]byte, ops.TypeLayerLen)
|
||||||
data[0] = byte(ops.TypeLayer)
|
data[0] = byte(ops.TypeLayer)
|
||||||
o.Write(data)
|
o.Write(data, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *OpLayer) Decode(d []byte) {
|
func (l *OpLayer) Decode(d []byte) {
|
||||||
|
|||||||
Reference in New Issue
Block a user