~eliasnaur/gio

6e26c92c75530df7ee57cbb41b5191573aa40e2a — Elias Naur 8 months ago 4d66669
all: remove exported Decode methods on operations

Add decode functions to the packages that need them instead. For
TransformOp that is used in multiple packages, add the decode
function to the internal ops package.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
M ui/app/internal/gpu/gpu.go => ui/app/internal/gpu/gpu.go +60 -9
@@ 144,6 144,61 @@ func (op *clipOp) decode(data []byte) {
	}
}

func decodeImageOp(data []byte, refs []interface{}) gdraw.ImageOp {
	bo := binary.LittleEndian
	if opconst.OpType(data[0]) != opconst.TypeImage {
		panic("invalid op")
	}
	sr := image.Rectangle{
		Min: image.Point{
			X: int(int32(bo.Uint32(data[1:]))),
			Y: int(int32(bo.Uint32(data[5:]))),
		},
		Max: image.Point{
			X: int(int32(bo.Uint32(data[9:]))),
			Y: int(int32(bo.Uint32(data[13:]))),
		},
	}
	return gdraw.ImageOp{
		Src:  refs[0].(image.Image),
		Rect: sr,
	}
}

func decodeColorOp(data []byte, refs []interface{}) gdraw.ColorOp {
	if opconst.OpType(data[0]) != opconst.TypeColor {
		panic("invalid op")
	}
	return gdraw.ColorOp{
		Color: color.RGBA{
			R: data[1],
			G: data[2],
			B: data[3],
			A: data[4],
		},
	}
}

func decodeDrawOp(data []byte, refs []interface{}) gdraw.DrawOp {
	bo := binary.LittleEndian
	if opconst.OpType(data[0]) != opconst.TypeDraw {
		panic("invalid op")
	}
	r := f32.Rectangle{
		Min: f32.Point{
			X: math.Float32frombits(bo.Uint32(data[1:])),
			Y: math.Float32frombits(bo.Uint32(data[5:])),
		},
		Max: f32.Point{
			X: math.Float32frombits(bo.Uint32(data[9:])),
			Y: math.Float32frombits(bo.Uint32(data[13:])),
		},
	}
	return gdraw.DrawOp{
		Rect: r,
	}
}

type clipType uint8

type resource interface {


@@ 649,9 704,8 @@ loop:
	for encOp, ok := r.Decode(); ok; encOp, ok = r.Decode() {
		switch opconst.OpType(encOp.Data[0]) {
		case opconst.TypeTransform:
			var op ui.TransformOp
			op.Decode(encOp.Data)
			state.t = state.t.Multiply(op)
			op := ops.DecodeTransformOp(encOp.Data)
			state.t = state.t.Multiply(ui.TransformOp(op))
		case opconst.TypeAux:
			aux = encOp.Data[opconst.TypeAuxLen:]
			auxKey = encOp.Key


@@ 679,18 733,15 @@ loop:
			aux = nil
			auxKey = ops.Key{}
		case opconst.TypeColor:
			var op gdraw.ColorOp
			op.Decode(encOp.Data, encOp.Refs)
			op := decodeColorOp(encOp.Data, encOp.Refs)
			state.img = nil
			state.color = op.Color
		case opconst.TypeImage:
			var op gdraw.ImageOp
			op.Decode(encOp.Data, encOp.Refs)
			op := decodeImageOp(encOp.Data, encOp.Refs)
			state.img = op.Src
			state.imgRect = op.Rect
		case opconst.TypeDraw:
			var op gdraw.DrawOp
			op.Decode(encOp.Data, encOp.Refs)
			op := decodeDrawOp(encOp.Data, encOp.Refs)
			off := state.t.Transform(f32.Point{})
			clip := state.clip.Intersect(op.Rect.Add(off))
			if clip.Empty() {

M ui/app/internal/input/key.go => ui/app/internal/input/key.go +11 -2
@@ 97,8 97,7 @@ loop:
	for encOp, ok := q.reader.Decode(); ok; encOp, ok = q.reader.Decode() {
		switch opconst.OpType(encOp.Data[0]) {
		case opconst.TypeKeyHandler:
			var op key.HandlerOp
			op.Decode(encOp.Data, encOp.Refs)
			op := decodeKeyHandlerOp(encOp.Data, encOp.Refs)
			var newPri listenerPriority
			switch {
			case op.Focus:


@@ 139,3 138,13 @@ func (p listenerPriority) replaces(p2 listenerPriority) bool {
	// Favor earliest default focus or latest requested focus.
	return p > p2 || p == p2 && p == priNewFocus
}

func decodeKeyHandlerOp(d []byte, refs []interface{}) key.HandlerOp {
	if opconst.OpType(d[0]) != opconst.TypeKeyHandler {
		panic("invalid op")
	}
	return key.HandlerOp{
		Focus: d[1] != 0,
		Key:   refs[0].(input.Key),
	}
}

M ui/app/internal/input/pointer.go => ui/app/internal/input/pointer.go +23 -7
@@ 72,8 72,7 @@ func (q *pointerQueue) collectHandlers(r *ops.Reader, events *handlerEvents, t u
		case opconst.TypePop:
			return
		case opconst.TypePass:
			var op pointer.PassOp
			op.Decode(encOp.Data)
			op := decodePassOp(encOp.Data)
			pass = op.Pass
		case opconst.TypeArea:
			var op areaOp


@@ 87,12 86,10 @@ func (q *pointerQueue) collectHandlers(r *ops.Reader, events *handlerEvents, t u
			})
			node = len(q.hitTree) - 1
		case opconst.TypeTransform:
			var op ui.TransformOp
			op.Decode(encOp.Data)
			t = t.Multiply(op)
			op := ops.DecodeTransformOp(encOp.Data)
			t = t.Multiply(ui.TransformOp(op))
		case opconst.TypePointerHandler:
			var op pointer.HandlerOp
			op.Decode(encOp.Data, encOp.Refs)
			op := decodePointerHandlerOp(encOp.Data, encOp.Refs)
			q.hitTree = append(q.hitTree, hitNode{
				next: node,
				area: area,


@@ 316,3 313,22 @@ func (op *areaOp) Hit(pos f32.Point) bool {
		panic("invalid area kind")
	}
}

func decodePointerHandlerOp(d []byte, refs []interface{}) pointer.HandlerOp {
	if opconst.OpType(d[0]) != opconst.TypePointerHandler {
		panic("invalid op")
	}
	return pointer.HandlerOp{
		Grab: d[1] != 0,
		Key:  refs[0].(input.Key),
	}
}

func decodePassOp(d []byte) pointer.PassOp {
	if opconst.OpType(d[0]) != opconst.TypePass {
		panic("invalid op")
	}
	return pointer.PassOp{
		Pass: d[1] != 0,
	}
}

M ui/app/internal/input/router.go => ui/app/internal/input/router.go +24 -4
@@ 3,6 3,7 @@
package input

import (
	"encoding/binary"
	"time"

	"gioui.org/ui"


@@ 74,15 75,13 @@ func (q *Router) collect() {
	for encOp, ok := q.reader.Decode(); ok; encOp, ok = q.reader.Decode() {
		switch opconst.OpType(encOp.Data[0]) {
		case opconst.TypeInvalidate:
			var op ui.InvalidateOp
			op.Decode(encOp.Data)
			op := decodeInvalidateOp(encOp.Data)
			if !q.wakeup || op.At.Before(q.wakeupTime) {
				q.wakeup = true
				q.wakeupTime = op.At
			}
		case opconst.TypeProfile:
			var op system.ProfileOp
			op.Decode(encOp.Data, encOp.Refs)
			op := decodeProfileOp(encOp.Data, encOp.Refs)
			q.profHandlers = append(q.profHandlers, op.Key)
		}
	}


@@ 141,3 140,24 @@ func (h *handlerEvents) Clear() {
		delete(h.handlers, k)
	}
}

func decodeProfileOp(d []byte, refs []interface{}) system.ProfileOp {
	if opconst.OpType(d[0]) != opconst.TypeProfile {
		panic("invalid op")
	}
	return system.ProfileOp{
		Key: refs[0].(input.Key),
	}
}

func decodeInvalidateOp(d []byte) ui.InvalidateOp {
	bo := binary.LittleEndian
	if opconst.OpType(d[0]) != opconst.TypeInvalidate {
		panic("invalid op")
	}
	var o ui.InvalidateOp
	if nanos := bo.Uint64(d[1:]); nanos > 0 {
		o.At = time.Unix(0, int64(nanos))
	}
	return o
}

M ui/draw/draw.go => ui/draw/draw.go +0 -55
@@ 37,27 37,6 @@ func (i ImageOp) Add(o *ui.Ops) {
	o.Write(data, i.Src)
}

func (i *ImageOp) Decode(data []byte, refs []interface{}) {
	bo := binary.LittleEndian
	if opconst.OpType(data[0]) != opconst.TypeImage {
		panic("invalid op")
	}
	sr := image.Rectangle{
		Min: image.Point{
			X: int(int32(bo.Uint32(data[1:]))),
			Y: int(int32(bo.Uint32(data[5:]))),
		},
		Max: image.Point{
			X: int(int32(bo.Uint32(data[9:]))),
			Y: int(int32(bo.Uint32(data[13:]))),
		},
	}
	*i = ImageOp{
		Src:  refs[0].(image.Image),
		Rect: sr,
	}
}

func (c ColorOp) Add(o *ui.Ops) {
	data := make([]byte, opconst.TypeColorLen)
	data[0] = byte(opconst.TypeColor)


@@ 68,20 47,6 @@ func (c ColorOp) Add(o *ui.Ops) {
	o.Write(data)
}

func (c *ColorOp) Decode(data []byte, refs []interface{}) {
	if opconst.OpType(data[0]) != opconst.TypeColor {
		panic("invalid op")
	}
	*c = ColorOp{
		Color: color.RGBA{
			R: data[1],
			G: data[2],
			B: data[3],
			A: data[4],
		},
	}
}

func (d DrawOp) Add(o *ui.Ops) {
	data := make([]byte, opconst.TypeDrawLen)
	data[0] = byte(opconst.TypeDraw)


@@ 93,26 58,6 @@ func (d DrawOp) Add(o *ui.Ops) {
	o.Write(data)
}

func (d *DrawOp) Decode(data []byte, refs []interface{}) {
	bo := binary.LittleEndian
	if opconst.OpType(data[0]) != opconst.TypeDraw {
		panic("invalid op")
	}
	r := f32.Rectangle{
		Min: f32.Point{
			X: math.Float32frombits(bo.Uint32(data[1:])),
			Y: math.Float32frombits(bo.Uint32(data[5:])),
		},
		Max: f32.Point{
			X: math.Float32frombits(bo.Uint32(data[9:])),
			Y: math.Float32frombits(bo.Uint32(data[13:])),
		},
	}
	*d = DrawOp{
		Rect: r,
	}
}

// RectClip returns a ClipOp op corresponding to
// a pixel aligned rectangular area.
func RectClip(r image.Rectangle) ClipOp {

A ui/internal/ops/ops.go => ui/internal/ops/ops.go +23 -0
@@ 0,0 1,23 @@
// SPDX-License-Identifier: Unlicense OR MIT

package ops

import (
	"encoding/binary"
	"math"

	"gioui.org/ui"
	"gioui.org/ui/f32"
	"gioui.org/ui/internal/opconst"
)

func DecodeTransformOp(d []byte) ui.TransformOp {
	bo := binary.LittleEndian
	if opconst.OpType(d[0]) != opconst.TypeTransform {
		panic("invalid op")
	}
	return ui.TransformOp{}.Offset(f32.Point{
		X: math.Float32frombits(bo.Uint32(d[1:])),
		Y: math.Float32frombits(bo.Uint32(d[5:])),
	})
}

M ui/key/key.go => ui/key/key.go +0 -10
@@ 64,16 64,6 @@ func (h HandlerOp) Add(o *ui.Ops) {
	o.Write(data, h.Key)
}

func (h *HandlerOp) Decode(d []byte, refs []interface{}) {
	if opconst.OpType(d[0]) != opconst.TypeKeyHandler {
		panic("invalid op")
	}
	*h = HandlerOp{
		Focus: d[1] != 0,
		Key:   refs[0].(input.Key),
	}
}

func (h HideInputOp) Add(o *ui.Ops) {
	data := make([]byte, opconst.TypeHideInputLen)
	data[0] = byte(opconst.TypeHideInput)

M ui/pointer/pointer.go => ui/pointer/pointer.go +0 -19
@@ 115,16 115,6 @@ func (h HandlerOp) Add(o *ui.Ops) {
	o.Write(data, h.Key)
}

func (h *HandlerOp) Decode(d []byte, refs []interface{}) {
	if opconst.OpType(d[0]) != opconst.TypePointerHandler {
		panic("invalid op")
	}
	*h = HandlerOp{
		Grab: d[1] != 0,
		Key:  refs[0].(input.Key),
	}
}

func (op PassOp) Add(o *ui.Ops) {
	data := make([]byte, opconst.TypePassLen)
	data[0] = byte(opconst.TypePass)


@@ 134,15 124,6 @@ func (op PassOp) Add(o *ui.Ops) {
	o.Write(data)
}

func (op *PassOp) Decode(d []byte) {
	if opconst.OpType(d[0]) != opconst.TypePass {
		panic("invalid op")
	}
	*op = PassOp{
		Pass: d[1] != 0,
	}
}

func (t Type) String() string {
	switch t {
	case Press:

M ui/system/system.go => ui/system/system.go +0 -9
@@ 29,13 29,4 @@ func (p ProfileOp) Add(o *ui.Ops) {
	o.Write(data, p.Key)
}

func (p *ProfileOp) Decode(d []byte, refs []interface{}) {
	if opconst.OpType(d[0]) != opconst.TypeProfile {
		panic("invalid op")
	}
	*p = ProfileOp{
		Key: refs[0].(input.Key),
	}
}

func (p ProfileEvent) ImplementsEvent() {}

M ui/ui.go => ui/ui.go +0 -21
@@ 46,16 46,6 @@ func (r InvalidateOp) Add(o *Ops) {
	o.Write(data)
}

func (r *InvalidateOp) Decode(d []byte) {
	bo := binary.LittleEndian
	if opconst.OpType(d[0]) != opconst.TypeInvalidate {
		panic("invalid op")
	}
	if nanos := bo.Uint64(d[1:]); nanos > 0 {
		r.At = time.Unix(0, int64(nanos))
	}
}

// Offset the transformation.
func (t TransformOp) Offset(o f32.Point) TransformOp {
	return t.Multiply(TransformOp{o})


@@ 86,14 76,3 @@ func (t TransformOp) Add(o *Ops) {
	bo.PutUint32(data[5:], math.Float32bits(t.offset.Y))
	o.Write(data)
}

func (t *TransformOp) Decode(d []byte) {
	bo := binary.LittleEndian
	if opconst.OpType(d[0]) != opconst.TypeTransform {
		panic("invalid op")
	}
	*t = TransformOp{f32.Point{
		X: math.Float32frombits(bo.Uint32(d[1:])),
		Y: math.Float32frombits(bo.Uint32(d[5:])),
	}}
}