Skip to content

Commit

Permalink
Merge pull request #2580 from toaster/feature/geometry_add
Browse files Browse the repository at this point in the history
geometry addition helpers
  • Loading branch information
toaster authored Oct 30, 2021
2 parents 728757e + 2a32ffb commit 8514602
Show file tree
Hide file tree
Showing 3 changed files with 220 additions and 34 deletions.
20 changes: 20 additions & 0 deletions geometry.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ func (p Position) Add(v Vector2) Position {
return Position{p.X + x, p.Y + y}
}

// AddXY returns a new Position by adding x and y to the current one.
func (p Position) AddXY(x, y float32) Position {
return Position{p.X + x, p.Y + y}
}

// Components returns the X and Y elements of this Position
func (p Position) Components() (float32, float32) {
return p.X, p.Y
Expand All @@ -66,6 +71,11 @@ func (p Position) Subtract(v Vector2) Position {
return Position{p.X - x, p.Y - y}
}

// SubtractXY returns a new Position by subtracting x and y from the current one.
func (p Position) SubtractXY(x, y float32) Position {
return Position{p.X - x, p.Y - y}
}

// Size describes something with width and height.
type Size struct {
Width float32 // The number of units along the X axis.
Expand All @@ -84,6 +94,11 @@ func (s Size) Add(v Vector2) Size {
return Size{s.Width + w, s.Height + h}
}

// AddWidthHeight returns a new Size by adding width and height to the current one.
func (s Size) AddWidthHeight(width, height float32) Size {
return Size{s.Width + width, s.Height + height}
}

// IsZero returns whether the Size has zero width and zero height.
func (s Size) IsZero() bool {
return s.Width == 0.0 && s.Height == 0.0
Expand Down Expand Up @@ -120,3 +135,8 @@ func (s Size) Subtract(v Vector2) Size {
w, h := v.Components()
return Size{s.Width - w, s.Height - h}
}

// SubtractWidthHeight returns a new Size by subtracting width and height from the current one.
func (s Size) SubtractWidthHeight(width, height float32) Size {
return Size{s.Width - width, s.Height - height}
}
129 changes: 129 additions & 0 deletions geometry_benchmark_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// +build !ci

package fyne_test

import (
"testing"

"github.com/stretchr/testify/assert"

"fyne.io/fyne/v2"
)

func BenchmarkPosition_Add(b *testing.B) {
b.Run("Add()", benchmarkPositionAdd)
b.Run("AddXY()", benchmarkPositionAddXY)
}

func BenchmarkPosition_Subtract(b *testing.B) {
b.Run("Subtract()", benchmarkPositionSubtract)
b.Run("SubtractXY()", benchmarkPositionSubtractXY)
}

func BenchmarkSize_Add(b *testing.B) {
b.Run("Add()", benchmarkSizeAdd)
b.Run("AddWidthHeight()", benchmarkSizeAddWidthHeight)
}

func BenchmarkSize_Subtract(b *testing.B) {
b.Run("Subtract()", benchmarkSizeSubtract)
b.Run("SubtractWidthHeight()", benchmarkSizeSubtractWidthHeight)
}

// This test prevents Position.Add to be simplified to `return p.AddXY(v.Components())`
// because this slows down the speed by factor 10.
func TestPosition_Add_Speed(t *testing.T) {
add := testing.Benchmark(benchmarkPositionAdd)
addXY := testing.Benchmark(benchmarkPositionAddXY)
assert.Less(t, add.NsPerOp()/addXY.NsPerOp(), int64(5))
}

// This test prevents Position.Subtract to be simplified to `return p.SubtractXY(v.Components())`
// because this slows down the speed by factor 10.
func TestPosition_Subtract_Speed(t *testing.T) {
subtract := testing.Benchmark(benchmarkPositionSubtract)
subtractXY := testing.Benchmark(benchmarkPositionSubtractXY)
assert.Less(t, subtract.NsPerOp()/subtractXY.NsPerOp(), int64(5))
}

// This test prevents Size.Add to be simplified to `return s.AddWidthHeight(v.Components())`
// because this slows down the speed by factor 10.
func TestSize_Add_Speed(t *testing.T) {
add := testing.Benchmark(benchmarkSizeAdd)
addWidthHeight := testing.Benchmark(benchmarkSizeAddWidthHeight)
assert.Less(t, add.NsPerOp()/addWidthHeight.NsPerOp(), int64(5))
}

// This test prevents Size.Subtract to be simplified to `return s.SubtractWidthHeight(v.Components())`
// because this slows down the speed by factor 10.
func TestSize_Subtract_Speed(t *testing.T) {
subtract := testing.Benchmark(benchmarkSizeSubtract)
subtractWidthHeight := testing.Benchmark(benchmarkSizeSubtractWidthHeight)
assert.Less(t, subtract.NsPerOp()/subtractWidthHeight.NsPerOp(), int64(5))
}

var benchmarkResult interface{}

func benchmarkPositionAdd(b *testing.B) {
pos := fyne.NewPos(10, 10)
for n := 0; n < b.N; n++ {
pos = pos.Add(fyne.NewPos(float32(n), float32(n)))
}
benchmarkResult = pos
}

func benchmarkPositionAddXY(b *testing.B) {
pos := fyne.NewPos(10, 10)
for n := 0; n < b.N; n++ {
pos = pos.AddXY(float32(n), float32(n))
}
benchmarkResult = pos
}

func benchmarkPositionSubtract(b *testing.B) {
pos := fyne.NewPos(10, 10)
for n := 0; n < b.N; n++ {
pos = pos.Subtract(fyne.NewPos(float32(n), float32(n)))
}
benchmarkResult = pos
}

func benchmarkPositionSubtractXY(b *testing.B) {
pos := fyne.NewPos(10, 10)
for n := 0; n < b.N; n++ {
pos = pos.SubtractXY(float32(n), float32(n))
}
benchmarkResult = pos
}

func benchmarkSizeAdd(b *testing.B) {
size := fyne.NewSize(10, 10)
for n := 0; n < b.N; n++ {
size = size.Add(fyne.NewPos(float32(n), float32(n)))
}
benchmarkResult = size
}

func benchmarkSizeAddWidthHeight(b *testing.B) {
size := fyne.NewSize(10, 10)
for n := 0; n < b.N; n++ {
size = size.AddWidthHeight(float32(n), float32(n))
}
benchmarkResult = size
}

func benchmarkSizeSubtract(b *testing.B) {
size := fyne.NewSize(10, 10)
for n := 0; n < b.N; n++ {
size = size.Subtract(fyne.NewSize(float32(n), float32(n)))
}
benchmarkResult = size
}

func benchmarkSizeSubtractWidthHeight(b *testing.B) {
size := fyne.NewSize(10, 10)
for n := 0; n < b.N; n++ {
size = size.SubtractWidthHeight(float32(n), float32(n))
}
benchmarkResult = size
}
105 changes: 71 additions & 34 deletions geometry_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package fyne
package fyne_test

import (
"testing"

"fyne.io/fyne/v2"
"github.com/stretchr/testify/assert"
)

func TestPosition_Add(t *testing.T) {
pos1 := NewPos(10, 10)
pos2 := NewPos(25, 25)
pos1 := fyne.NewPos(10, 10)
pos2 := fyne.NewPos(25, 25)

pos3 := pos1.Add(pos2)

Expand All @@ -17,8 +18,8 @@ func TestPosition_Add(t *testing.T) {
}

func TestPosition_Add_Size(t *testing.T) {
pos1 := NewPos(10, 10)
s := NewSize(25, 25)
pos1 := fyne.NewPos(10, 10)
s := fyne.NewSize(25, 25)

pos2 := pos1.Add(s)

Expand All @@ -27,25 +28,34 @@ func TestPosition_Add_Size(t *testing.T) {
}

func TestPosition_Add_Vector(t *testing.T) {
pos1 := NewPos(10, 10)
v := NewDelta(25, 25)
pos1 := fyne.NewPos(10, 10)
v := fyne.NewDelta(25, 25)

pos2 := pos1.Add(v)

assert.Equal(t, float32(35), pos2.X)
assert.Equal(t, float32(35), pos2.Y)
}

func TestPosition_AddXY(t *testing.T) {
pos1 := fyne.NewPos(10, 10)

pos2 := pos1.AddXY(25, 25)

assert.Equal(t, float32(35), pos2.X)
assert.Equal(t, float32(35), pos2.Y)
}

func TestPosition_IsZero(t *testing.T) {
for name, tt := range map[string]struct {
p Position
p fyne.Position
want bool
}{
"zero value": {Position{}, true},
"0,0": {NewPos(0, 0), true},
"zero X": {NewPos(0, 42), false},
"zero Y": {NewPos(17, 0), false},
"non-zero X and Y": {NewPos(6, 9), false},
"zero value": {fyne.Position{}, true},
"0,0": {fyne.NewPos(0, 0), true},
"zero X": {fyne.NewPos(0, 42), false},
"zero Y": {fyne.NewPos(17, 0), false},
"non-zero X and Y": {fyne.NewPos(6, 9), false},
} {
t.Run(name, func(t *testing.T) {
assert.Equal(t, tt.want, tt.p.IsZero())
Expand All @@ -54,18 +64,27 @@ func TestPosition_IsZero(t *testing.T) {
}

func TestPosition_Subtract(t *testing.T) {
pos1 := NewPos(25, 25)
pos2 := NewPos(10, 10)
pos1 := fyne.NewPos(25, 25)
pos2 := fyne.NewPos(10, 10)

pos3 := pos1.Subtract(pos2)

assert.Equal(t, float32(15), pos3.X)
assert.Equal(t, float32(15), pos3.Y)
}

func TestPosition_SubtractXY(t *testing.T) {
pos1 := fyne.NewPos(25, 25)

pos2 := pos1.SubtractXY(10, 10)

assert.Equal(t, float32(15), pos2.X)
assert.Equal(t, float32(15), pos2.Y)
}

func TestSize_Add(t *testing.T) {
size1 := NewSize(10, 10)
size2 := NewSize(25, 25)
size1 := fyne.NewSize(10, 10)
size2 := fyne.NewSize(25, 25)

size3 := size1.Add(size2)

Expand All @@ -74,8 +93,8 @@ func TestSize_Add(t *testing.T) {
}

func TestSize_Add_Position(t *testing.T) {
size1 := NewSize(10, 10)
p := NewSize(25, 25)
size1 := fyne.NewSize(10, 10)
p := fyne.NewSize(25, 25)

size2 := size1.Add(p)

Expand All @@ -84,25 +103,34 @@ func TestSize_Add_Position(t *testing.T) {
}

func TestSize_Add_Vector(t *testing.T) {
size1 := NewSize(10, 10)
v := NewDelta(25, 25)
size1 := fyne.NewSize(10, 10)
v := fyne.NewDelta(25, 25)

size2 := size1.Add(v)

assert.Equal(t, float32(35), size2.Width)
assert.Equal(t, float32(35), size2.Height)
}

func TestSize_AddWidthHeight(t *testing.T) {
size1 := fyne.NewSize(10, 10)

size2 := size1.AddWidthHeight(25, 25)

assert.Equal(t, float32(35), size2.Width)
assert.Equal(t, float32(35), size2.Height)
}

func TestSize_IsZero(t *testing.T) {
for name, tt := range map[string]struct {
s Size
s fyne.Size
want bool
}{
"zero value": {Size{}, true},
"0x0": {NewSize(0, 0), true},
"zero width": {NewSize(0, 42), false},
"zero height": {NewSize(17, 0), false},
"non-zero area": {NewSize(6, 9), false},
"zero value": {fyne.Size{}, true},
"0x0": {fyne.NewSize(0, 0), true},
"zero width": {fyne.NewSize(0, 42), false},
"zero height": {fyne.NewSize(17, 0), false},
"non-zero area": {fyne.NewSize(6, 9), false},
} {
t.Run(name, func(t *testing.T) {
assert.Equal(t, tt.want, tt.s.IsZero())
Expand All @@ -111,8 +139,8 @@ func TestSize_IsZero(t *testing.T) {
}

func TestSize_Max(t *testing.T) {
size1 := NewSize(10, 100)
size2 := NewSize(100, 10)
size1 := fyne.NewSize(10, 100)
size2 := fyne.NewSize(100, 10)

size3 := size1.Max(size2)

Expand All @@ -121,8 +149,8 @@ func TestSize_Max(t *testing.T) {
}

func TestSize_Min(t *testing.T) {
size1 := NewSize(10, 100)
size2 := NewSize(100, 10)
size1 := fyne.NewSize(10, 100)
size2 := fyne.NewSize(100, 10)

size3 := size1.Min(size2)

Expand All @@ -131,17 +159,26 @@ func TestSize_Min(t *testing.T) {
}

func TestSize_Subtract(t *testing.T) {
size1 := NewSize(25, 25)
size2 := NewSize(10, 10)
size1 := fyne.NewSize(25, 25)
size2 := fyne.NewSize(10, 10)

size3 := size1.Subtract(size2)

assert.Equal(t, float32(15), size3.Width)
assert.Equal(t, float32(15), size3.Height)
}

func TestSize_SubtractWidthHeight(t *testing.T) {
size1 := fyne.NewSize(25, 25)

size2 := size1.SubtractWidthHeight(10, 10)

assert.Equal(t, float32(15), size2.Width)
assert.Equal(t, float32(15), size2.Height)
}

func TestVector_IsZero(t *testing.T) {
v := NewDelta(0, 0)
v := fyne.NewDelta(0, 0)

assert.True(t, v.IsZero())

Expand Down

0 comments on commit 8514602

Please sign in to comment.