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