ui,internal/ops,internal/opconst: move OpsReader to internal ops package

To avoid import cycles, move the op constants to its own package,
internal/opconst.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-08-07 14:55:20 +02:00
parent fe20cde393
commit b3517a365e
14 changed files with 295 additions and 270 deletions
+8 -8
View File
@@ -3,7 +3,7 @@ package gpu
import (
"fmt"
"gioui.org/ui"
"gioui.org/ui/internal/ops"
)
type resourceCache struct {
@@ -11,11 +11,11 @@ type resourceCache struct {
newRes map[interface{}]resource
}
// opCache is like a resourceCache using the concrete OpKey
// opCache is like a resourceCache using the concrete Key
// key type to avoid allocations.
type opCache struct {
res map[ui.OpKey]resource
newRes map[ui.OpKey]resource
res map[ops.Key]resource
newRes map[ops.Key]resource
}
func newResourceCache() *resourceCache {
@@ -64,12 +64,12 @@ func (r *resourceCache) release(ctx *context) {
func newOpCache() *opCache {
return &opCache{
res: make(map[ui.OpKey]resource),
newRes: make(map[ui.OpKey]resource),
res: make(map[ops.Key]resource),
newRes: make(map[ops.Key]resource),
}
}
func (r *opCache) get(key ui.OpKey) (resource, bool) {
func (r *opCache) get(key ops.Key) (resource, bool) {
v, exists := r.res[key]
if exists {
r.newRes[key] = v
@@ -77,7 +77,7 @@ func (r *opCache) get(key ui.OpKey) (resource, bool) {
return v, exists
}
func (r *opCache) put(key ui.OpKey, val resource) {
func (r *opCache) put(key ops.Key, val resource) {
if _, exists := r.newRes[key]; exists {
panic(fmt.Errorf("key exists, %p", key))
}
+17 -16
View File
@@ -16,6 +16,7 @@ import (
"gioui.org/ui/app/internal/gl"
gdraw "gioui.org/ui/draw"
"gioui.org/ui/f32"
"gioui.org/ui/internal/opconst"
"gioui.org/ui/internal/ops"
"golang.org/x/image/draw"
)
@@ -58,7 +59,7 @@ type renderer struct {
}
type drawOps struct {
reader ui.OpsReader
reader ops.Reader
cache *resourceCache
viewport image.Point
clearColor [3]float32
@@ -90,7 +91,7 @@ type pathOp struct {
// clip is the union of all
// later clip rectangles.
clip image.Rectangle
pathKey ui.OpKey
pathKey ops.Key
path bool
pathVerts []byte
parent *pathOp
@@ -124,7 +125,7 @@ type opClip struct {
}
func (op *opClip) decode(data []byte) {
if ops.OpType(data[0]) != ops.TypeClip {
if opconst.OpType(data[0]) != opconst.TypeClip {
panic("invalid op")
}
bo := binary.LittleEndian
@@ -641,20 +642,20 @@ func (d *drawOps) newPathOp() *pathOp {
return &d.pathOpCache[len(d.pathOpCache)-1]
}
func (d *drawOps) collectOps(r *ui.OpsReader, state drawState) int {
func (d *drawOps) collectOps(r *ops.Reader, state drawState) int {
var aux []byte
var auxKey ui.OpKey
var auxKey ops.Key
loop:
for encOp, ok := r.Decode(); ok; encOp, ok = r.Decode() {
switch ops.OpType(encOp.Data[0]) {
case ops.TypeTransform:
switch opconst.OpType(encOp.Data[0]) {
case opconst.TypeTransform:
var op ui.TransformOp
op.Decode(encOp.Data)
state.t = state.t.Multiply(op)
case ops.TypeAux:
aux = encOp.Data[ops.TypeAuxLen:]
case opconst.TypeAux:
aux = encOp.Data[opconst.TypeAuxLen:]
auxKey = encOp.Key
case ops.TypeClip:
case opconst.TypeClip:
var op opClip
op.decode(encOp.Data)
off := state.t.Transform(f32.Point{})
@@ -676,18 +677,18 @@ loop:
d.pathOps = append(d.pathOps, state.cpath)
}
aux = nil
auxKey = ui.OpKey{}
case ops.TypeColor:
auxKey = ops.Key{}
case opconst.TypeColor:
var op gdraw.ColorOp
op.Decode(encOp.Data, encOp.Refs)
state.img = nil
state.color = op.Color
case ops.TypeImage:
case opconst.TypeImage:
var op gdraw.ImageOp
op.Decode(encOp.Data, encOp.Refs)
state.img = op.Src
state.imgRect = op.Rect
case ops.TypeDraw:
case opconst.TypeDraw:
var op gdraw.DrawOp
op.Decode(encOp.Data, encOp.Refs)
off := state.t.Transform(f32.Point{})
@@ -723,9 +724,9 @@ loop:
} else {
d.imageOps = append(d.imageOps, img)
}
case ops.TypePush:
case opconst.TypePush:
state.z = d.collectOps(r, state)
case ops.TypePop:
case opconst.TypePop:
break loop
}
}
+7 -6
View File
@@ -5,6 +5,7 @@ package input
import (
"gioui.org/ui"
"gioui.org/ui/input"
"gioui.org/ui/internal/opconst"
"gioui.org/ui/internal/ops"
"gioui.org/ui/key"
)
@@ -14,7 +15,7 @@ type TextInputState uint8
type keyQueue struct {
focus input.Key
handlers map[input.Key]*keyHandler
reader ui.OpsReader
reader ops.Reader
state TextInputState
}
@@ -94,8 +95,8 @@ func (q *keyQueue) resolveFocus(events *handlerEvents) (input.Key, listenerPrior
var hide bool
loop:
for encOp, ok := q.reader.Decode(); ok; encOp, ok = q.reader.Decode() {
switch ops.OpType(encOp.Data[0]) {
case ops.TypeKeyHandler:
switch opconst.OpType(encOp.Data[0]) {
case opconst.TypeKeyHandler:
var op key.HandlerOp
op.Decode(encOp.Data, encOp.Refs)
var newPri listenerPriority
@@ -119,15 +120,15 @@ loop:
events.Set(op.Key, []input.Event{key.FocusEvent{Focus: false}})
}
h.active = true
case ops.TypeHideInput:
case opconst.TypeHideInput:
hide = true
case ops.TypePush:
case opconst.TypePush:
newK, newPri, h := q.resolveFocus(events)
hide = hide || h
if newPri.replaces(pri) {
k, pri = newK, newPri
}
case ops.TypePop:
case opconst.TypePop:
break loop
}
}
+11 -10
View File
@@ -9,6 +9,7 @@ import (
"gioui.org/ui"
"gioui.org/ui/f32"
"gioui.org/ui/input"
"gioui.org/ui/internal/opconst"
"gioui.org/ui/internal/ops"
"gioui.org/ui/pointer"
)
@@ -18,7 +19,7 @@ type pointerQueue struct {
areas []areaNode
handlers map[input.Key]*pointerHandler
pointers []pointerInfo
reader ui.OpsReader
reader ops.Reader
scratch []input.Key
}
@@ -63,18 +64,18 @@ const (
areaEllipse
)
func (q *pointerQueue) collectHandlers(r *ui.OpsReader, events *handlerEvents, t ui.TransformOp, area, node int, pass bool) {
func (q *pointerQueue) collectHandlers(r *ops.Reader, events *handlerEvents, t ui.TransformOp, area, node int, pass bool) {
for encOp, ok := r.Decode(); ok; encOp, ok = r.Decode() {
switch ops.OpType(encOp.Data[0]) {
case ops.TypePush:
switch opconst.OpType(encOp.Data[0]) {
case opconst.TypePush:
q.collectHandlers(r, events, t, area, node, pass)
case ops.TypePop:
case opconst.TypePop:
return
case ops.TypePass:
case opconst.TypePass:
var op pointer.PassOp
op.Decode(encOp.Data)
pass = op.Pass
case ops.TypeArea:
case opconst.TypeArea:
var op areaOp
op.Decode(encOp.Data)
q.areas = append(q.areas, areaNode{trans: t, next: area, area: op})
@@ -85,11 +86,11 @@ func (q *pointerQueue) collectHandlers(r *ui.OpsReader, events *handlerEvents, t
pass: pass,
})
node = len(q.hitTree) - 1
case ops.TypeTransform:
case opconst.TypeTransform:
var op ui.TransformOp
op.Decode(encOp.Data)
t = t.Multiply(op)
case ops.TypePointerHandler:
case opconst.TypePointerHandler:
var op pointer.HandlerOp
op.Decode(encOp.Data, encOp.Refs)
q.hitTree = append(q.hitTree, hitNode{
@@ -264,7 +265,7 @@ func (q *pointerQueue) Push(e pointer.Event, events *handlerEvents) {
}
func (op *areaOp) Decode(d []byte) {
if ops.OpType(d[0]) != ops.TypeArea {
if opconst.OpType(d[0]) != opconst.TypeArea {
panic("invalid op")
}
bo := binary.LittleEndian
+5 -4
View File
@@ -7,6 +7,7 @@ import (
"gioui.org/ui"
"gioui.org/ui/input"
"gioui.org/ui/internal/opconst"
"gioui.org/ui/internal/ops"
"gioui.org/ui/key"
"gioui.org/ui/pointer"
@@ -21,7 +22,7 @@ type Router struct {
handlers handlerEvents
reader ui.OpsReader
reader ops.Reader
// InvalidateOp summary.
wakeup bool
@@ -71,15 +72,15 @@ func (q *Router) TextInputState() TextInputState {
func (q *Router) collect() {
for encOp, ok := q.reader.Decode(); ok; encOp, ok = q.reader.Decode() {
switch ops.OpType(encOp.Data[0]) {
case ops.TypeInvalidate:
switch opconst.OpType(encOp.Data[0]) {
case opconst.TypeInvalidate:
var op ui.InvalidateOp
op.Decode(encOp.Data)
if !q.wakeup || op.At.Before(q.wakeupTime) {
q.wakeup = true
q.wakeupTime = op.At
}
case ops.TypeProfile:
case opconst.TypeProfile:
var op system.ProfileOp
op.Decode(encOp.Data, encOp.Refs)
q.profHandlers = append(q.profHandlers, op.Key)
+10 -10
View File
@@ -10,7 +10,7 @@ import (
"gioui.org/ui"
"gioui.org/ui/f32"
"gioui.org/ui/internal/ops"
"gioui.org/ui/internal/opconst"
)
type ImageOp struct {
@@ -27,8 +27,8 @@ type DrawOp struct {
}
func (i ImageOp) Add(o *ui.Ops) {
data := make([]byte, ops.TypeImageLen)
data[0] = byte(ops.TypeImage)
data := make([]byte, opconst.TypeImageLen)
data[0] = byte(opconst.TypeImage)
bo := binary.LittleEndian
bo.PutUint32(data[1:], uint32(i.Rect.Min.X))
bo.PutUint32(data[5:], uint32(i.Rect.Min.Y))
@@ -39,7 +39,7 @@ func (i ImageOp) Add(o *ui.Ops) {
func (i *ImageOp) Decode(data []byte, refs []interface{}) {
bo := binary.LittleEndian
if ops.OpType(data[0]) != ops.TypeImage {
if opconst.OpType(data[0]) != opconst.TypeImage {
panic("invalid op")
}
sr := image.Rectangle{
@@ -59,8 +59,8 @@ func (i *ImageOp) Decode(data []byte, refs []interface{}) {
}
func (c ColorOp) Add(o *ui.Ops) {
data := make([]byte, ops.TypeColorLen)
data[0] = byte(ops.TypeColor)
data := make([]byte, opconst.TypeColorLen)
data[0] = byte(opconst.TypeColor)
data[1] = c.Color.R
data[2] = c.Color.G
data[3] = c.Color.B
@@ -69,7 +69,7 @@ func (c ColorOp) Add(o *ui.Ops) {
}
func (c *ColorOp) Decode(data []byte, refs []interface{}) {
if ops.OpType(data[0]) != ops.TypeColor {
if opconst.OpType(data[0]) != opconst.TypeColor {
panic("invalid op")
}
*c = ColorOp{
@@ -83,8 +83,8 @@ func (c *ColorOp) Decode(data []byte, refs []interface{}) {
}
func (d DrawOp) Add(o *ui.Ops) {
data := make([]byte, ops.TypeDrawLen)
data[0] = byte(ops.TypeDraw)
data := make([]byte, opconst.TypeDrawLen)
data[0] = byte(opconst.TypeDraw)
bo := binary.LittleEndian
bo.PutUint32(data[1:], math.Float32bits(d.Rect.Min.X))
bo.PutUint32(data[5:], math.Float32bits(d.Rect.Min.Y))
@@ -95,7 +95,7 @@ func (d DrawOp) Add(o *ui.Ops) {
func (d *DrawOp) Decode(data []byte, refs []interface{}) {
bo := binary.LittleEndian
if ops.OpType(data[0]) != ops.TypeDraw {
if opconst.OpType(data[0]) != opconst.TypeDraw {
panic("invalid op")
}
r := f32.Rectangle{
+4 -4
View File
@@ -9,7 +9,7 @@ import (
"gioui.org/ui"
"gioui.org/ui/f32"
"gioui.org/ui/internal/ops"
"gioui.org/ui/internal/opconst"
"gioui.org/ui/internal/path"
)
@@ -30,8 +30,8 @@ type ClipOp struct {
}
func (p ClipOp) Add(o *ui.Ops) {
data := make([]byte, ops.TypeClipLen)
data[0] = byte(ops.TypeClip)
data := make([]byte, opconst.TypeClipLen)
data[0] = byte(opconst.TypeClip)
bo := binary.LittleEndian
bo.PutUint32(data[1:], math.Float32bits(p.bounds.Min.X))
bo.PutUint32(data[5:], math.Float32bits(p.bounds.Min.Y))
@@ -239,7 +239,7 @@ func (p *PathBuilder) vertex(cornerx, cornery int16, ctrl, to f32.Point) {
ToY: to.Y,
}
data := make([]byte, path.VertStride+1)
data[0] = byte(ops.TypeAux)
data[0] = byte(opconst.TypeAux)
bo := binary.LittleEndian
data[1] = byte(uint16(v.CornerX))
data[2] = byte(uint16(v.CornerX) >> 8)
@@ -1,4 +1,4 @@
package ops
package opconst
type OpType byte
+177
View File
@@ -0,0 +1,177 @@
package ops
import (
"encoding/binary"
"gioui.org/ui"
"gioui.org/ui/internal/opconst"
)
// Reader parses an ops list.
type Reader struct {
pc pc
stack []macro
ops *ui.Ops
}
// EncodedOp represents an encoded op returned by
// Reader.
type EncodedOp struct {
Key Key
Data []byte
Refs []interface{}
}
// Key is a unique key for a given op.
type Key struct {
ops *ui.Ops
pc int
version int
}
// Shadow of ui.MacroOp.
type macroOp struct {
recording bool
ops *ui.Ops
version int
pc pc
}
type pc struct {
data int
refs int
}
type macro struct {
ops *ui.Ops
retPC pc
endPC pc
}
type opMacroDef struct {
endpc pc
}
type opAux struct {
len int
}
// Reset start reading from the op list.
func (r *Reader) Reset(ops *ui.Ops) {
r.stack = r.stack[:0]
r.pc = pc{}
r.ops = nil
if ops == nil {
return
}
r.ops = ops
}
func (r *Reader) Decode() (EncodedOp, bool) {
if r.ops == nil {
return EncodedOp{}, false
}
for {
if len(r.stack) > 0 {
b := r.stack[len(r.stack)-1]
if r.pc == b.endPC {
r.ops = b.ops
r.pc = b.retPC
r.stack = r.stack[:len(r.stack)-1]
continue
}
}
if r.pc.data == len(r.ops.Data) {
return EncodedOp{}, false
}
key := Key{ops: r.ops, pc: r.pc.data, version: r.ops.Version}
t := opconst.OpType(r.ops.Data[r.pc.data])
n := t.Size()
nrefs := t.NumRefs()
data := r.ops.Data[r.pc.data : r.pc.data+n]
refs := r.ops.Refs[r.pc.refs : r.pc.refs+nrefs]
switch t {
case opconst.TypeAux:
var op opAux
op.decode(data)
n += op.len
data = r.ops.Data[r.pc.data : r.pc.data+n]
case opconst.TypeMacro:
var op macroOp
op.decode(data, refs)
macroOps := op.ops
if opconst.OpType(macroOps.Data[op.pc.data]) != opconst.TypeMacroDef {
panic("invalid macro reference")
}
if op.version != op.ops.Version {
panic("invalid MacroOp reference to reset Ops")
}
var opDef opMacroDef
opDef.decode(macroOps.Data[op.pc.data : op.pc.data+opconst.TypeMacroDef.Size()])
retPC := r.pc
retPC.data += n
retPC.refs += nrefs
r.stack = append(r.stack, macro{
ops: r.ops,
retPC: retPC,
endPC: opDef.endpc,
})
r.ops = macroOps
r.pc = op.pc
r.pc.data += opconst.TypeMacroDef.Size()
r.pc.refs += opconst.TypeMacroDef.NumRefs()
continue
case opconst.TypeMacroDef:
var op opMacroDef
op.decode(data)
r.pc = op.endpc
continue
}
r.pc.data += n
r.pc.refs += nrefs
return EncodedOp{Key: key, Data: data, Refs: refs}, true
}
}
func (op *opMacroDef) decode(data []byte) {
if opconst.OpType(data[0]) != opconst.TypeMacroDef {
panic("invalid op")
}
bo := binary.LittleEndian
dataIdx := int(int32(bo.Uint32(data[1:])))
refsIdx := int(int32(bo.Uint32(data[5:])))
*op = opMacroDef{
endpc: pc{
data: dataIdx,
refs: refsIdx,
},
}
}
func (op *opAux) decode(data []byte) {
if opconst.OpType(data[0]) != opconst.TypeAux {
panic("invalid op")
}
bo := binary.LittleEndian
*op = opAux{
len: int(int32(bo.Uint32(data[1:]))),
}
}
func (m *macroOp) decode(data []byte, refs []interface{}) {
if opconst.OpType(data[0]) != opconst.TypeMacro {
panic("invalid op")
}
bo := binary.LittleEndian
dataIdx := int(int32(bo.Uint32(data[1:])))
refsIdx := int(int32(bo.Uint32(data[5:])))
version := int(int32(bo.Uint32(data[9:])))
*m = macroOp{
ops: refs[0].(*ui.Ops),
pc: pc{
data: dataIdx,
refs: refsIdx,
},
version: version,
}
}
+6 -6
View File
@@ -5,7 +5,7 @@ package key
import (
"gioui.org/ui"
"gioui.org/ui/input"
"gioui.org/ui/internal/ops"
"gioui.org/ui/internal/opconst"
)
type HandlerOp struct {
@@ -56,8 +56,8 @@ func (m Modifiers) Contain(m2 Modifiers) bool {
}
func (h HandlerOp) Add(o *ui.Ops) {
data := make([]byte, ops.TypeKeyHandlerLen)
data[0] = byte(ops.TypeKeyHandler)
data := make([]byte, opconst.TypeKeyHandlerLen)
data[0] = byte(opconst.TypeKeyHandler)
if h.Focus {
data[1] = 1
}
@@ -65,7 +65,7 @@ func (h HandlerOp) Add(o *ui.Ops) {
}
func (h *HandlerOp) Decode(d []byte, refs []interface{}) {
if ops.OpType(d[0]) != ops.TypeKeyHandler {
if opconst.OpType(d[0]) != opconst.TypeKeyHandler {
panic("invalid op")
}
*h = HandlerOp{
@@ -75,8 +75,8 @@ func (h *HandlerOp) Decode(d []byte, refs []interface{}) {
}
func (h HideInputOp) Add(o *ui.Ops) {
data := make([]byte, ops.TypeHideInputLen)
data[0] = byte(ops.TypeHideInput)
data := make([]byte, opconst.TypeHideInputLen)
data[0] = byte(opconst.TypeHideInput)
o.Write(data)
}
+29 -185
View File
@@ -3,16 +3,16 @@ package ui
import (
"encoding/binary"
"gioui.org/ui/internal/ops"
"gioui.org/ui/internal/opconst"
)
// Ops holds a list of serialized Ops.
type Ops struct {
version int
Version int
// Serialized ops.
data []byte
Data []byte
// Op references.
refs []interface{}
Refs []interface{}
stackDepth int
@@ -21,39 +21,6 @@ type Ops struct {
auxLen int
}
// OpsReader parses an ops list. Internal use only.
type OpsReader struct {
pc pc
stack []macro
ops *Ops
}
// EncodedOp represents an encoded op returned by
// OpsReader. Internal use only.
type EncodedOp struct {
Key OpKey
Data []byte
Refs []interface{}
}
// OpKey is a unique key for a given op. Internal use only.
type OpKey struct {
ops *Ops
pc int
version int
}
type macro struct {
ops *Ops
retPC pc
endPC pc
}
type pc struct {
data int
refs int
}
type StackOp struct {
depth int
active bool
@@ -67,12 +34,9 @@ type MacroOp struct {
pc pc
}
type opMacroDef struct {
endpc pc
}
type opAux struct {
len int
type pc struct {
data int
refs int
}
func (s *StackOp) Push(o *Ops) {
@@ -83,7 +47,7 @@ func (s *StackOp) Push(o *Ops) {
s.ops = o
o.stackDepth++
s.depth = o.stackDepth
o.Write([]byte{byte(ops.TypePush)})
o.Write([]byte{byte(opconst.TypePush)})
}
func (s *StackOp) Pop() {
@@ -96,32 +60,7 @@ func (s *StackOp) Pop() {
}
s.active = false
s.ops.stackDepth--
s.ops.Write([]byte{byte(ops.TypePop)})
}
func (op *opAux) decode(data []byte) {
if ops.OpType(data[0]) != ops.TypeAux {
panic("invalid op")
}
bo := binary.LittleEndian
*op = opAux{
len: int(int32(bo.Uint32(data[1:]))),
}
}
func (op *opMacroDef) decode(data []byte) {
if ops.OpType(data[0]) != ops.TypeMacroDef {
panic("invalid op")
}
bo := binary.LittleEndian
dataIdx := int(int32(bo.Uint32(data[1:])))
refsIdx := int(int32(bo.Uint32(data[5:])))
*op = opMacroDef{
endpc: pc{
data: dataIdx,
refs: refsIdx,
},
}
s.ops.Write([]byte{byte(opconst.TypePop)})
}
// Reset the Ops, preparing it for re-use.
@@ -129,12 +68,12 @@ func (o *Ops) Reset() {
o.inAux = false
o.stackDepth = 0
// Leave references to the GC.
for i := range o.refs {
o.refs[i] = nil
for i := range o.Refs {
o.Refs[i] = nil
}
o.data = o.data[:0]
o.refs = o.refs[:0]
o.version++
o.Data = o.Data[:0]
o.Refs = o.Refs[:0]
o.Version++
}
// Internal use only.
@@ -142,29 +81,29 @@ func (o *Ops) Aux() []byte {
if !o.inAux {
return nil
}
return o.data[o.auxOff+ops.TypeAuxLen : o.auxOff+ops.TypeAuxLen+o.auxLen]
return o.Data[o.auxOff+opconst.TypeAuxLen : o.auxOff+opconst.TypeAuxLen+o.auxLen]
}
func (d *Ops) write(op []byte, refs ...interface{}) {
d.data = append(d.data, op...)
d.refs = append(d.refs, refs...)
d.Data = append(d.Data, op...)
d.Refs = append(d.Refs, refs...)
}
func (o *Ops) Write(op []byte, refs ...interface{}) {
t := ops.OpType(op[0])
t := opconst.OpType(op[0])
if len(refs) != t.NumRefs() {
panic("invalid ref count")
}
switch t {
case ops.TypeAux:
case opconst.TypeAux:
// Write only the data.
op = op[1:]
if !o.inAux {
o.inAux = true
o.auxOff = o.pc().data
o.auxLen = 0
header := make([]byte, ops.TypeAuxLen)
header[0] = byte(ops.TypeAux)
header := make([]byte, opconst.TypeAuxLen)
header[0] = byte(opconst.TypeAux)
o.write(header)
}
o.auxLen += len(op)
@@ -172,14 +111,14 @@ func (o *Ops) Write(op []byte, refs ...interface{}) {
if o.inAux {
o.inAux = false
bo := binary.LittleEndian
bo.PutUint32(o.data[o.auxOff+1:], uint32(o.auxLen))
bo.PutUint32(o.Data[o.auxOff+1:], uint32(o.auxLen))
}
}
o.write(op, refs...)
}
func (d *Ops) pc() pc {
return pc{data: len(d.data), refs: len(d.refs)}
return pc{data: len(d.Data), refs: len(d.Refs)}
}
// Record a macro of operations.
@@ -191,7 +130,7 @@ func (m *MacroOp) Record(o *Ops) {
m.ops = o
m.pc = o.pc()
// Make room for a macro definition. Filled out in Stop.
m.ops.Write(make([]byte, ops.TypeMacroDefLen))
m.ops.Write(make([]byte, opconst.TypeMacroDefLen))
}
// Stop recording the macro.
@@ -202,30 +141,12 @@ func (m *MacroOp) Stop() {
m.recording = false
pc := m.ops.pc()
// Fill out the macro definition reserved in Record.
data := m.ops.data[m.pc.data : m.pc.data+ops.TypeMacroDefLen]
data[0] = byte(ops.TypeMacroDef)
data := m.ops.Data[m.pc.data : m.pc.data+opconst.TypeMacroDefLen]
data[0] = byte(opconst.TypeMacroDef)
bo := binary.LittleEndian
bo.PutUint32(data[1:], uint32(pc.data))
bo.PutUint32(data[5:], uint32(pc.refs))
m.version = m.ops.version
}
func (m *MacroOp) decode(data []byte, refs []interface{}) {
if ops.OpType(data[0]) != ops.TypeMacro {
panic("invalid op")
}
bo := binary.LittleEndian
dataIdx := int(int32(bo.Uint32(data[1:])))
refsIdx := int(int32(bo.Uint32(data[5:])))
version := int(int32(bo.Uint32(data[9:])))
*m = MacroOp{
ops: refs[0].(*Ops),
pc: pc{
data: dataIdx,
refs: refsIdx,
},
version: version,
}
m.version = m.ops.Version
}
func (m MacroOp) Add(o *Ops) {
@@ -235,88 +156,11 @@ func (m MacroOp) Add(o *Ops) {
if m.ops == nil {
return
}
data := make([]byte, ops.TypeMacroLen)
data[0] = byte(ops.TypeMacro)
data := make([]byte, opconst.TypeMacroLen)
data[0] = byte(opconst.TypeMacro)
bo := binary.LittleEndian
bo.PutUint32(data[1:], uint32(m.pc.data))
bo.PutUint32(data[5:], uint32(m.pc.refs))
bo.PutUint32(data[9:], uint32(m.version))
o.Write(data, m.ops)
}
// Reset start reading from the op list.
func (r *OpsReader) Reset(ops *Ops) {
r.stack = r.stack[:0]
r.pc = pc{}
r.ops = nil
if ops == nil {
return
}
r.ops = ops
}
func (r *OpsReader) Decode() (EncodedOp, bool) {
if r.ops == nil {
return EncodedOp{}, false
}
for {
if len(r.stack) > 0 {
b := r.stack[len(r.stack)-1]
if r.pc == b.endPC {
r.ops = b.ops
r.pc = b.retPC
r.stack = r.stack[:len(r.stack)-1]
continue
}
}
if r.pc.data == len(r.ops.data) {
return EncodedOp{}, false
}
key := OpKey{ops: r.ops, pc: r.pc.data, version: r.ops.version}
t := ops.OpType(r.ops.data[r.pc.data])
n := t.Size()
nrefs := t.NumRefs()
data := r.ops.data[r.pc.data : r.pc.data+n]
refs := r.ops.refs[r.pc.refs : r.pc.refs+nrefs]
switch t {
case ops.TypeAux:
var op opAux
op.decode(data)
n += op.len
data = r.ops.data[r.pc.data : r.pc.data+n]
case ops.TypeMacro:
var op MacroOp
op.decode(data, refs)
macroOps := op.ops
if ops.OpType(macroOps.data[op.pc.data]) != ops.TypeMacroDef {
panic("invalid macro reference")
}
if op.version != op.ops.version {
panic("invalid MacroOp reference to reset Ops")
}
var opDef opMacroDef
opDef.decode(macroOps.data[op.pc.data : op.pc.data+ops.TypeMacroDef.Size()])
retPC := r.pc
retPC.data += n
retPC.refs += nrefs
r.stack = append(r.stack, macro{
ops: r.ops,
retPC: retPC,
endPC: opDef.endpc,
})
r.ops = macroOps
r.pc = op.pc
r.pc.data += ops.TypeMacroDef.Size()
r.pc.refs += ops.TypeMacroDef.NumRefs()
continue
case ops.TypeMacroDef:
var op opMacroDef
op.decode(data)
r.pc = op.endpc
continue
}
r.pc.data += n
r.pc.refs += nrefs
return EncodedOp{Key: key, Data: data, Refs: refs}, true
}
}
+9 -9
View File
@@ -10,7 +10,7 @@ import (
"gioui.org/ui"
"gioui.org/ui/f32"
"gioui.org/ui/input"
"gioui.org/ui/internal/ops"
"gioui.org/ui/internal/opconst"
)
type Event struct {
@@ -95,8 +95,8 @@ func (op EllipseAreaOp) Add(ops *ui.Ops) {
}
func (op areaOp) add(o *ui.Ops) {
data := make([]byte, ops.TypeAreaLen)
data[0] = byte(ops.TypeArea)
data := make([]byte, opconst.TypeAreaLen)
data[0] = byte(opconst.TypeArea)
data[1] = byte(op.kind)
bo := binary.LittleEndian
bo.PutUint32(data[2:], uint32(op.rect.Min.X))
@@ -107,8 +107,8 @@ func (op areaOp) add(o *ui.Ops) {
}
func (h HandlerOp) Add(o *ui.Ops) {
data := make([]byte, ops.TypePointerHandlerLen)
data[0] = byte(ops.TypePointerHandler)
data := make([]byte, opconst.TypePointerHandlerLen)
data[0] = byte(opconst.TypePointerHandler)
if h.Grab {
data[1] = 1
}
@@ -116,7 +116,7 @@ func (h HandlerOp) Add(o *ui.Ops) {
}
func (h *HandlerOp) Decode(d []byte, refs []interface{}) {
if ops.OpType(d[0]) != ops.TypePointerHandler {
if opconst.OpType(d[0]) != opconst.TypePointerHandler {
panic("invalid op")
}
*h = HandlerOp{
@@ -126,8 +126,8 @@ func (h *HandlerOp) Decode(d []byte, refs []interface{}) {
}
func (op PassOp) Add(o *ui.Ops) {
data := make([]byte, ops.TypePassLen)
data[0] = byte(ops.TypePass)
data := make([]byte, opconst.TypePassLen)
data[0] = byte(opconst.TypePass)
if op.Pass {
data[1] = 1
}
@@ -135,7 +135,7 @@ func (op PassOp) Add(o *ui.Ops) {
}
func (op *PassOp) Decode(d []byte) {
if ops.OpType(d[0]) != ops.TypePass {
if opconst.OpType(d[0]) != opconst.TypePass {
panic("invalid op")
}
*op = PassOp{
+4 -4
View File
@@ -7,7 +7,7 @@ package system
import (
"gioui.org/ui"
"gioui.org/ui/input"
"gioui.org/ui/internal/ops"
"gioui.org/ui/internal/opconst"
)
// ProfileOp registers a handler for receiving
@@ -24,13 +24,13 @@ type ProfileEvent struct {
}
func (p ProfileOp) Add(o *ui.Ops) {
data := make([]byte, ops.TypeProfileLen)
data[0] = byte(ops.TypeProfile)
data := make([]byte, opconst.TypeProfileLen)
data[0] = byte(opconst.TypeProfile)
o.Write(data, p.Key)
}
func (p *ProfileOp) Decode(d []byte, refs []interface{}) {
if ops.OpType(d[0]) != ops.TypeProfile {
if opconst.OpType(d[0]) != opconst.TypeProfile {
panic("invalid op")
}
*p = ProfileOp{
+7 -7
View File
@@ -8,7 +8,7 @@ import (
"time"
"gioui.org/ui/f32"
"gioui.org/ui/internal/ops"
"gioui.org/ui/internal/opconst"
)
// Config represents the essential configuration for
@@ -33,8 +33,8 @@ type TransformOp struct {
}
func (r InvalidateOp) Add(o *Ops) {
data := make([]byte, ops.TypeRedrawLen)
data[0] = byte(ops.TypeInvalidate)
data := make([]byte, opconst.TypeRedrawLen)
data[0] = byte(opconst.TypeInvalidate)
bo := binary.LittleEndian
// UnixNano cannot represent the zero time.
if t := r.At; !t.IsZero() {
@@ -48,7 +48,7 @@ func (r InvalidateOp) Add(o *Ops) {
func (r *InvalidateOp) Decode(d []byte) {
bo := binary.LittleEndian
if ops.OpType(d[0]) != ops.TypeInvalidate {
if opconst.OpType(d[0]) != opconst.TypeInvalidate {
panic("invalid op")
}
if nanos := bo.Uint64(d[1:]); nanos > 0 {
@@ -79,8 +79,8 @@ func (t TransformOp) Multiply(t2 TransformOp) TransformOp {
}
func (t TransformOp) Add(o *Ops) {
data := make([]byte, ops.TypeTransformLen)
data[0] = byte(ops.TypeTransform)
data := make([]byte, opconst.TypeTransformLen)
data[0] = byte(opconst.TypeTransform)
bo := binary.LittleEndian
bo.PutUint32(data[1:], math.Float32bits(t.offset.X))
bo.PutUint32(data[5:], math.Float32bits(t.offset.Y))
@@ -89,7 +89,7 @@ func (t TransformOp) Add(o *Ops) {
func (t *TransformOp) Decode(d []byte) {
bo := binary.LittleEndian
if ops.OpType(d[0]) != ops.TypeTransform {
if opconst.OpType(d[0]) != opconst.TypeTransform {
panic("invalid op")
}
*t = TransformOp{f32.Point{