mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +00:00
all: replace InvalidateOp with InvalidateCmd command
Curiously, InvalidateCmd is probably the only command that is appropriate to call during layout. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+2
-2
@@ -339,8 +339,8 @@ func (w *Window) processFrame(d driver) {
|
||||
// If the window is inactive, the event is sent when the window becomes active.
|
||||
//
|
||||
// Note that Invalidate is intended for externally triggered updates, such as a
|
||||
// response from a network request. InvalidateOp is more efficient for animation
|
||||
// and similar internal updates.
|
||||
// response from a network request. The [op.InvalidateCmd] command is more efficient
|
||||
// for animation.
|
||||
//
|
||||
// Invalidate is safe for concurrent use.
|
||||
func (w *Window) Invalidate() {
|
||||
|
||||
+3
-3
@@ -252,9 +252,6 @@ func (ClickEvent) ImplementsEvent() {}
|
||||
// as defined in io/pointer.InputOp.
|
||||
func (s *Scroll) Add(ops *op.Ops) {
|
||||
event.InputOp(ops, s)
|
||||
if s.flinger.Active() {
|
||||
op.InvalidateOp{}.Add(ops)
|
||||
}
|
||||
}
|
||||
|
||||
// Stop any remaining fling movement.
|
||||
@@ -336,6 +333,9 @@ func (s *Scroll) Update(cfg unit.Metric, q input.Source, t time.Time, axis Axis,
|
||||
}
|
||||
}
|
||||
total += s.flinger.Tick(t)
|
||||
if s.flinger.Active() {
|
||||
q.Execute(op.InvalidateCmd{})
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,6 @@ const (
|
||||
TypePopTransform
|
||||
TypePushOpacity
|
||||
TypePopOpacity
|
||||
TypeInvalidate
|
||||
TypeImage
|
||||
TypePaint
|
||||
TypeColor
|
||||
@@ -405,7 +404,6 @@ var opProps = [0x100]opProp{
|
||||
TypePopTransform: {Size: TypePopTransformLen, NumRefs: 0},
|
||||
TypePushOpacity: {Size: TypePushOpacityLen, NumRefs: 0},
|
||||
TypePopOpacity: {Size: TypePopOpacityLen, NumRefs: 0},
|
||||
TypeInvalidate: {Size: TypeRedrawLen, NumRefs: 0},
|
||||
TypeImage: {Size: TypeImageLen, NumRefs: 2},
|
||||
TypePaint: {Size: TypePaintLen, NumRefs: 0},
|
||||
TypeColor: {Size: TypeColorLen, NumRefs: 0},
|
||||
@@ -459,8 +457,6 @@ func (t OpType) String() string {
|
||||
return "PushOpacity"
|
||||
case TypePopOpacity:
|
||||
return "PopOpacity"
|
||||
case TypeInvalidate:
|
||||
return "Invalidate"
|
||||
case TypeImage:
|
||||
return "Image"
|
||||
case TypePaint:
|
||||
|
||||
+9
-22
@@ -3,7 +3,6 @@
|
||||
package input
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"image"
|
||||
"io"
|
||||
"strings"
|
||||
@@ -44,7 +43,7 @@ type Router struct {
|
||||
|
||||
reader ops.Reader
|
||||
|
||||
// InvalidateOp summary.
|
||||
// InvalidateCmd summary.
|
||||
wakeup bool
|
||||
wakeupTime time.Time
|
||||
|
||||
@@ -261,7 +260,6 @@ func (q *Router) Frame(frame *op.Ops) {
|
||||
}
|
||||
}
|
||||
q.transfers = nil
|
||||
q.wakeup = false
|
||||
q.deferring = false
|
||||
for _, h := range q.handlers {
|
||||
h.filter, h.nextFilter = h.nextFilter, h.filter
|
||||
@@ -470,6 +468,11 @@ func (q *Router) executeCommand(c Command) (event.Tag, stateChange) {
|
||||
case pointer.GrabCmd:
|
||||
tag = req.Tag
|
||||
state.pointerState, evts = q.pointer.queue.grab(state.pointerState, req)
|
||||
case op.InvalidateCmd:
|
||||
if !q.wakeup || req.At.Before(q.wakeupTime) {
|
||||
q.wakeup = true
|
||||
q.wakeupTime = req.At
|
||||
}
|
||||
}
|
||||
return tag, stateChange{state: state, events: evts}
|
||||
}
|
||||
@@ -727,12 +730,6 @@ func (q *Router) collect() {
|
||||
var t f32.Affine2D
|
||||
for encOp, ok := q.reader.Decode(); ok; encOp, ok = q.reader.Decode() {
|
||||
switch ops.OpType(encOp.Data[0]) {
|
||||
case ops.TypeInvalidate:
|
||||
op := decodeInvalidateOp(encOp.Data)
|
||||
if !q.wakeup || op.At.Before(q.wakeupTime) {
|
||||
q.wakeup = true
|
||||
q.wakeupTime = op.At
|
||||
}
|
||||
case ops.TypeSave:
|
||||
id := ops.DecodeSave(encOp.Data)
|
||||
if extra := id - len(q.savedTrans) + 1; extra > 0 {
|
||||
@@ -822,19 +819,9 @@ func (q *Router) collect() {
|
||||
// WakeupTime returns the most recent time for doing another frame,
|
||||
// as determined from the last call to Frame.
|
||||
func (q *Router) WakeupTime() (time.Time, bool) {
|
||||
return q.wakeupTime, q.wakeup
|
||||
}
|
||||
|
||||
func decodeInvalidateOp(d []byte) op.InvalidateOp {
|
||||
bo := binary.LittleEndian
|
||||
if ops.OpType(d[0]) != ops.TypeInvalidate {
|
||||
panic("invalid op")
|
||||
}
|
||||
var o op.InvalidateOp
|
||||
if nanos := bo.Uint64(d[1:]); nanos > 0 {
|
||||
o.At = time.Unix(0, int64(nanos))
|
||||
}
|
||||
return o
|
||||
w := q.wakeup
|
||||
q.wakeup = false
|
||||
return q.wakeupTime, w
|
||||
}
|
||||
|
||||
func (s SemanticGestures) String() string {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"gioui.org/io/pointer"
|
||||
"gioui.org/op"
|
||||
)
|
||||
|
||||
func TestNoFilterAllocs(t *testing.T) {
|
||||
@@ -22,3 +23,12 @@ func TestNoFilterAllocs(t *testing.T) {
|
||||
t.Fatalf("expected 0 AllocsPerOp, got %d", allocs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouterWakeup(t *testing.T) {
|
||||
r := new(Router)
|
||||
r.Source().Execute(op.InvalidateCmd{})
|
||||
r.Frame(new(op.Ops))
|
||||
if _, wake := r.WakeupTime(); !wake {
|
||||
t.Errorf("InvalidateCmd did not trigger a redraw")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,6 @@ The MacroOp records a list of operations to be executed later:
|
||||
ops := new(op.Ops)
|
||||
macro := op.Record(ops)
|
||||
// Record operations by adding them.
|
||||
op.InvalidateOp{}.Add(ops)
|
||||
...
|
||||
// End recording.
|
||||
call := macro.Stop()
|
||||
@@ -96,9 +95,9 @@ type CallOp struct {
|
||||
end ops.PC
|
||||
}
|
||||
|
||||
// InvalidateOp requests a redraw at the given time. Use
|
||||
// InvalidateCmd requests a redraw at the given time. Use
|
||||
// the zero value to request an immediate redraw.
|
||||
type InvalidateOp struct {
|
||||
type InvalidateCmd struct {
|
||||
At time.Time
|
||||
}
|
||||
|
||||
@@ -181,19 +180,6 @@ func (c CallOp) Add(o *Ops) {
|
||||
ops.AddCall(&o.Internal, c.ops, c.start, c.end)
|
||||
}
|
||||
|
||||
func (r InvalidateOp) Add(o *Ops) {
|
||||
data := ops.Write(&o.Internal, ops.TypeRedrawLen)
|
||||
data[0] = byte(ops.TypeInvalidate)
|
||||
bo := binary.LittleEndian
|
||||
// UnixNano cannot represent the zero time.
|
||||
if t := r.At; !t.IsZero() {
|
||||
nanos := t.UnixNano()
|
||||
if nanos > 0 {
|
||||
bo.PutUint64(data[1:], uint64(nanos))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Offset converts an offset to a TransformOp.
|
||||
func Offset(off image.Point) TransformOp {
|
||||
offf := f32.Pt(float32(off.X), float32(off.Y))
|
||||
@@ -240,3 +226,5 @@ func (t TransformStack) Pop() {
|
||||
data := ops.Write(t.ops, ops.TypePopTransformLen)
|
||||
data[0] = byte(ops.TypePopTransform)
|
||||
}
|
||||
|
||||
func (InvalidateCmd) ImplementsCommand() {}
|
||||
|
||||
+1
-2
@@ -692,8 +692,7 @@ func (e *Editor) layout(gtx layout.Context, textMaterial, selectMaterial op.Call
|
||||
const timePerBlink = time.Second / blinksPerSecond
|
||||
nextBlink := now.Add(timePerBlink/2 - dt%(timePerBlink/2))
|
||||
if blinking {
|
||||
redraw := op.InvalidateOp{At: nextBlink}
|
||||
redraw.Add(gtx.Ops)
|
||||
gtx.Execute(op.InvalidateCmd{At: nextBlink})
|
||||
}
|
||||
e.showCaret = e.focused && (!blinking || dt%timePerBlink < timePerBlink/2)
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ func drawInk(gtx layout.Context, c widget.Press) {
|
||||
|
||||
// Animate only ended presses, and presses that are fading in.
|
||||
if !c.End.IsZero() || sizet <= 1.0 {
|
||||
op.InvalidateOp{}.Add(gtx.Ops)
|
||||
gtx.Execute(op.InvalidateCmd{})
|
||||
}
|
||||
|
||||
if sizet > 1.0 {
|
||||
|
||||
@@ -47,7 +47,7 @@ func (l LoaderStyle) Layout(gtx layout.Context) layout.Dimensions {
|
||||
}.Add(gtx.Ops)
|
||||
defer op.Offset(image.Pt(-radius, -radius)).Push(gtx.Ops).Pop()
|
||||
paint.PaintOp{}.Add(gtx.Ops)
|
||||
op.InvalidateOp{}.Add(gtx.Ops)
|
||||
gtx.Execute(op.InvalidateCmd{})
|
||||
return layout.Dimensions{
|
||||
Size: sz,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user