~eliasnaur/gio-patches

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
3 3

[PATCH gio] widget: make Editor implement io.Seeker, io.Reader and io.WriterTo

~pierrec
Details
Message ID
<162141258454.4112.7544450371035883084-0@git.sr.ht>
DKIM signature
missing
Download raw message
Patch: +70 -0
From: pierre <pierre.curto@gmail.com>

Those methods help the case where the String method is called often and garbage wants to be reduced.

Signed-off-by: pierre <pierre.curto@gmail.com>
---
-

 widget/buffer.go      | 10 ++++++++++
 widget/editor.go      | 15 +++++++++++++++
 widget/editor_test.go | 45 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 70 insertions(+)

diff --git a/widget/buffer.go b/widget/buffer.go
index e658d56..fbde602 100644
--- a/widget/buffer.go
+++ b/widget/buffer.go
@@ -142,6 +142,16 @@ func (e *editBuffer) ReadRune() (rune, int, error) {
	return r, s, nil
}

// WriteTo implements io.WriteTo.
func (e *editBuffer) WriteTo(w io.Writer) (int64, error) {
	n1, err := w.Write(e.text[:e.gapstart])
	if err != nil {
		return int64(n1), err
	}
	n2, err := w.Write(e.text[e.gapend:])
	return int64(n1 + n2), err
}

func (e *editBuffer) String() string {
	var b strings.Builder
	b.Grow(e.len())
diff --git a/widget/editor.go b/widget/editor.go
index 19aef46..f69c420 100644
--- a/widget/editor.go
+++ b/widget/editor.go
@@ -1250,6 +1250,21 @@ func (e *Editor) ClearSelection() {
	e.caret.end = e.caret.start
}

// WriteTo implements io.WriteTo.
func (e *Editor) WriteTo(w io.Writer) (int64, error) {
	return e.rr.WriteTo(w)
}

// Seek implements io.Seeker.
func (e *Editor) Seek(offset int64, whence int) (int64, error) {
	return e.rr.Seek(0, io.SeekStart)
}

// Read implements io.Reader.
func (e *Editor) Read(p []byte) (int, error) {
	return e.rr.Read(p)
}

func max(a, b int) int {
	if a > b {
		return a
diff --git a/widget/editor_test.go b/widget/editor_test.go
index 2babdbf..d5dfd51 100644
--- a/widget/editor_test.go
+++ b/widget/editor_test.go
@@ -3,8 +3,10 @@
package widget

import (
	"bytes"
	"fmt"
	"image"
	"io"
	"math/rand"
	"reflect"
	"strings"
@@ -476,6 +478,49 @@ func TestSelectMove(t *testing.T) {
	testKey(key.NameDownArrow)
}

func TestEditor_Read(t *testing.T) {
	s := "hello world"
	testIO(t, s, func(e *Editor) (int, error) {
		buf := make([]byte, len(s))
		_, err := e.Seek(0, io.SeekStart)
		if err != nil {
			t.Error(err)
		}
		return io.ReadFull(e, buf)
	})
}

func TestEditor_WriteTo(t *testing.T) {
	s := "hello world"
	testIO(t, s, func(e *Editor) (int, error) {
		var buf bytes.Buffer
		n, err := io.Copy(&buf, e)
		return int(n), err
	})
}

func testIO(t *testing.T, s string, run func(e *Editor) (int, error)) {
	t.Helper()
	e := new(Editor)
	e.SetText(s)

	gtx := layout.Context{Ops: new(op.Ops)}
	cache := text.NewCache(gofont.Collection())
	font := text.Font{}
	fontSize := unit.Px(10)

	gtx.Queue = newQueue(key.FocusEvent{Focus: true})
	e.Layout(gtx, cache, font, fontSize)

	n, err := run(e)
	if got, want := n, len(s); got != want {
		t.Errorf("got %d; want %d", got, want)
	}
	if err != nil {
		t.Error(err)
	}
}

func textWidth(e *Editor, lineNum, colStart, colEnd int) float32 {
	var w fixed.Int26_6
	advances := e.lines[lineNum].Layout.Advances
-- 
2.30.2

[gio/patches] build failed

builds.sr.ht
Details
Message ID
<CBH3A83VHOW6.1KQ1VN13PWSBK@cirno2>
In-Reply-To
<162141258454.4112.7544450371035883084-0@git.sr.ht> (view parent)
DKIM signature
missing
Download raw message
gio/patches: FAILED in 23m6s

[widget: make Editor implement io.Seeker, io.Reader and io.WriterTo][0] from [~pierrec][1]

[0]: https://lists.sr.ht/~eliasnaur/gio-patches/patches/22811
[1]: mailto:pierre.curto@gmail.com

✗ #509385 FAILED  gio/patches/linux.yml   https://builds.sr.ht/~eliasnaur/job/509385
✓ #509383 SUCCESS gio/patches/apple.yml   https://builds.sr.ht/~eliasnaur/job/509383
✓ #509386 SUCCESS gio/patches/openbsd.yml https://builds.sr.ht/~eliasnaur/job/509386
✓ #509384 SUCCESS gio/patches/freebsd.yml https://builds.sr.ht/~eliasnaur/job/509384
Details
Message ID
<CBH3QVLOSWXR.21CB7R678FSVI@zoidberg>
In-Reply-To
<162141258454.4112.7544450371035883084-0@git.sr.ht> (view parent)
DKIM signature
pass
Download raw message
On Wed May 19, 2021 at 10:21 CET, ~pierrec wrote:
> From: pierre <pierre.curto@gmail.com>
>
> Those methods help the case where the String method is called often and
> garbage wants to be reduced.
>
> Signed-off-by: pierre <pierre.curto@gmail.com>
> ---
> -
>
> widget/buffer.go | 10 ++++++++++
> widget/editor.go | 15 +++++++++++++++
> widget/editor_test.go | 45 +++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 70 insertions(+)
>
> diff --git a/widget/buffer.go b/widget/buffer.go
> index e658d56..fbde602 100644
> --- a/widget/buffer.go
> +++ b/widget/buffer.go
> @@ -142,6 +142,16 @@ func (e *editBuffer) ReadRune() (rune, int, error)
> {
> return r, s, nil
> }
>  
> +// WriteTo implements io.WriteTo.
s/io.WriteTo/io.WriterTo/
(because I am pedantic :P)

> +func (e *editBuffer) WriteTo(w io.Writer) (int64, error) {
> + n1, err := w.Write(e.text[:e.gapstart])
> + if err != nil {
> + return int64(n1), err
> + }
> + n2, err := w.Write(e.text[e.gapend:])
> + return int64(n1 + n2), err
> +}
> +
> func (e *editBuffer) String() string {
> var b strings.Builder
> b.Grow(e.len())
> diff --git a/widget/editor.go b/widget/editor.go
> index 19aef46..f69c420 100644
> --- a/widget/editor.go
> +++ b/widget/editor.go
> @@ -1250,6 +1250,21 @@ func (e *Editor) ClearSelection() {
> e.caret.end = e.caret.start
> }
>  
> +// WriteTo implements io.WriteTo.
s/io.WriteTo/io.WriterTo/
(because I am pedantic :P)

> +func (e *Editor) WriteTo(w io.Writer) (int64, error) {
> + return e.rr.WriteTo(w)
> +}
> +
> +// Seek implements io.Seeker.
> +func (e *Editor) Seek(offset int64, whence int) (int64, error) {
> + return e.rr.Seek(0, io.SeekStart)
> +}
> +
> +// Read implements io.Reader.
> +func (e *Editor) Read(p []byte) (int, error) {
> + return e.rr.Read(p)
> +}
> +
> func max(a, b int) int {
> if a > b {
> return a
> diff --git a/widget/editor_test.go b/widget/editor_test.go
> index 2babdbf..d5dfd51 100644
> --- a/widget/editor_test.go
> +++ b/widget/editor_test.go
> @@ -3,8 +3,10 @@
> package widget
>  
> import (
> + "bytes"
> "fmt"
> "image"
> + "io"
> "math/rand"
> "reflect"
> "strings"
> @@ -476,6 +478,49 @@ func TestSelectMove(t *testing.T) {
> testKey(key.NameDownArrow)
> }
>  
> +func TestEditor_Read(t *testing.T) {
> + s := "hello world"
> + testIO(t, s, func(e *Editor) (int, error) {
> + buf := make([]byte, len(s))
> + _, err := e.Seek(0, io.SeekStart)
> + if err != nil {
> + t.Error(err)
> + }
> + return io.ReadFull(e, buf)
> + })
> +}
> +
> +func TestEditor_WriteTo(t *testing.T) {
> + s := "hello world"
> + testIO(t, s, func(e *Editor) (int, error) {
> + var buf bytes.Buffer
> + n, err := io.Copy(&buf, e)
> + return int(n), err
> + })
> +}
> +
> +func testIO(t *testing.T, s string, run func(e *Editor) (int, error)) {
> + t.Helper()
> + e := new(Editor)
> + e.SetText(s)
> +
> + gtx := layout.Context{Ops: new(op.Ops)}
> + cache := text.NewCache(gofont.Collection())
> + font := text.Font{}
> + fontSize := unit.Px(10)
> +
> + gtx.Queue = newQueue(key.FocusEvent{Focus: true})
> + e.Layout(gtx, cache, font, fontSize)
> +
> + n, err := run(e)
> + if got, want := n, len(s); got != want {
> + t.Errorf("got %d; want %d", got, want)
> + }
> + if err != nil {
> + t.Error(err)
> + }
> +}
> +
> func textWidth(e *Editor, lineNum, colStart, colEnd int) float32 {
> var w fixed.Int26_6
> advances := e.lines[lineNum].Layout.Advances
> --
> 2.30.2
Details
Message ID
<CBH4MLCRZ3LS.ZVL9V2QWW1H2@themachine>
In-Reply-To
<162141258454.4112.7544450371035883084-0@git.sr.ht> (view parent)
DKIM signature
fail
Download raw message
DKIM signature: fail
On Wed May 19, 2021 at 10:21, ~pierrec wrote:
> From: pierre <pierre.curto@gmail.com>
>
> Those methods help the case where the String method is called often and garbage wants to be reduced.
>

I suggest just:

The WriteTo, Seek, Read methods implement a more efficient access to
the Editor content than Text.

(the method name is Text, not String).

> diff --git a/widget/editor_test.go b/widget/editor_test.go
> index 2babdbf..d5dfd51 100644
> --- a/widget/editor_test.go
> +++ b/widget/editor_test.go
> @@ -476,6 +478,49 @@ func TestSelectMove(t *testing.T) {
>  	testKey(key.NameDownArrow)
>  }
>  
> +func TestEditor_Read(t *testing.T) {
> +	s := "hello world"
> +	testIO(t, s, func(e *Editor) (int, error) {
> +		buf := make([]byte, len(s))
> +		_, err := e.Seek(0, io.SeekStart)
> +		if err != nil {
> +			t.Error(err)
> +		}
> +		return io.ReadFull(e, buf)
> +	})
> +}
> +
> +func TestEditor_WriteTo(t *testing.T) {
> +	s := "hello world"
> +	testIO(t, s, func(e *Editor) (int, error) {
> +		var buf bytes.Buffer
> +		n, err := io.Copy(&buf, e)
> +		return int(n), err
> +	})
> +}
> +
> +func testIO(t *testing.T, s string, run func(e *Editor) (int, error)) {
> +	t.Helper()
> +	e := new(Editor)
> +	e.SetText(s)
> +
> +	gtx := layout.Context{Ops: new(op.Ops)}
> +	cache := text.NewCache(gofont.Collection())
> +	font := text.Font{}
> +	fontSize := unit.Px(10)
> +
> +	gtx.Queue = newQueue(key.FocusEvent{Focus: true})
> +	e.Layout(gtx, cache, font, fontSize)

Why is Layout necessary? Is it because Editor should makeValid in the
new I/O methods? Perhaps Editor.Text should as well?

> +
> +	n, err := run(e)
> +	if got, want := n, len(s); got != want {
> +		t.Errorf("got %d; want %d", got, want)
> +	}
> +	if err != nil {
> +		t.Error(err)
> +	}
> +}
> +
>  func textWidth(e *Editor, lineNum, colStart, colEnd int) float32 {
>  	var w fixed.Int26_6
>  	advances := e.lines[lineNum].Layout.Advances
> -- 
> 2.30.2
Reply to thread Export thread (mbox)