ui: basic map scroller
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
package world
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestWorldDeltaFixedToCanvasPx_RemainderAccumulatesPositive(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// zoom=1: px = (deltaWorldFp * 1000) / 1e6
|
||||
// For deltaWorldFp=1, each step contributes 0 px with remainder,
|
||||
// and after 1000 steps it must become 1 px total.
|
||||
zoomFp := SCALE
|
||||
var rem int64
|
||||
sum := 0
|
||||
|
||||
for i := 0; i < 1000; i++ {
|
||||
sum += worldDeltaFixedToCanvasPx(1, zoomFp, &rem)
|
||||
}
|
||||
|
||||
require.Equal(t, 1, sum)
|
||||
}
|
||||
|
||||
func TestWorldDeltaFixedToCanvasPx_RemainderAccumulatesNegative(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
zoomFp := SCALE
|
||||
var rem int64
|
||||
sum := 0
|
||||
|
||||
for i := 0; i < 1000; i++ {
|
||||
sum += worldDeltaFixedToCanvasPx(-1, zoomFp, &rem)
|
||||
}
|
||||
|
||||
require.Equal(t, -1, sum)
|
||||
}
|
||||
|
||||
func TestComputePanShiftPx_FirstCallRequiresFullRedraw(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
w := NewWorld(10, 10)
|
||||
|
||||
params := RenderParams{
|
||||
ViewportWidthPx: 100,
|
||||
ViewportHeightPx: 80,
|
||||
MarginXPx: 25,
|
||||
MarginYPx: 20,
|
||||
CameraXWorldFp: 5 * SCALE,
|
||||
CameraYWorldFp: 5 * SCALE,
|
||||
CameraZoom: 1.0,
|
||||
}
|
||||
|
||||
_, _, err := w.ComputePanShiftPx(params)
|
||||
require.ErrorIs(t, err, errIncrementalStateNotReady)
|
||||
}
|
||||
|
||||
func TestComputePanShiftPx_ZoomOrViewportChangeForcesFullRedraw(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
w := NewWorld(10, 10)
|
||||
|
||||
base := RenderParams{
|
||||
ViewportWidthPx: 100,
|
||||
ViewportHeightPx: 80,
|
||||
MarginXPx: 25,
|
||||
MarginYPx: 20,
|
||||
CameraXWorldFp: 5 * SCALE,
|
||||
CameraYWorldFp: 5 * SCALE,
|
||||
CameraZoom: 1.0,
|
||||
}
|
||||
require.NoError(t, w.CommitFullRedrawState(base))
|
||||
|
||||
changed := base
|
||||
changed.CameraZoom = 2.0
|
||||
|
||||
_, _, err := w.ComputePanShiftPx(changed)
|
||||
require.ErrorIs(t, err, errIncrementalZoomMismatch)
|
||||
|
||||
changed2 := base
|
||||
changed2.ViewportWidthPx = 101
|
||||
|
||||
_, _, err = w.ComputePanShiftPx(changed2)
|
||||
require.ErrorIs(t, err, errIncrementalZoomMismatch)
|
||||
}
|
||||
|
||||
func TestComputePanShiftPx_PanRightShiftsImageLeft(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
w := NewWorld(10, 10)
|
||||
|
||||
params := RenderParams{
|
||||
ViewportWidthPx: 100,
|
||||
ViewportHeightPx: 80,
|
||||
MarginXPx: 25,
|
||||
MarginYPx: 20,
|
||||
CameraXWorldFp: 5 * SCALE,
|
||||
CameraYWorldFp: 5 * SCALE,
|
||||
CameraZoom: 1.0,
|
||||
}
|
||||
require.NoError(t, w.CommitFullRedrawState(params))
|
||||
|
||||
// Move camera right by 1 world unit => world rect minX increases by 1 unit,
|
||||
// so content moves left by 1px at zoom=1 => image shift should be -1.
|
||||
params2 := params
|
||||
params2.CameraXWorldFp += 1 * SCALE
|
||||
|
||||
dx, dy, err := w.ComputePanShiftPx(params2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, -1, dx)
|
||||
require.Equal(t, 0, dy)
|
||||
}
|
||||
|
||||
func TestComputePanShiftPx_PanUpShiftsImageDown(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
w := NewWorld(10, 10)
|
||||
|
||||
params := RenderParams{
|
||||
ViewportWidthPx: 100,
|
||||
ViewportHeightPx: 80,
|
||||
MarginXPx: 25,
|
||||
MarginYPx: 20,
|
||||
CameraXWorldFp: 5 * SCALE,
|
||||
CameraYWorldFp: 5 * SCALE,
|
||||
CameraZoom: 1.0,
|
||||
}
|
||||
require.NoError(t, w.CommitFullRedrawState(params))
|
||||
|
||||
// Move camera up by 1 world unit => world rect minY decreases by 1 unit,
|
||||
// so content moves down by 1px => image shift should be +1 in dy.
|
||||
params2 := params
|
||||
params2.CameraYWorldFp -= 1 * SCALE
|
||||
|
||||
dx, dy, err := w.ComputePanShiftPx(params2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, dx)
|
||||
require.Equal(t, 1, dy)
|
||||
}
|
||||
|
||||
func TestComputePanShiftPx_SubPixelPanAccumulatesToOnePixel(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
w := NewWorld(10, 10)
|
||||
|
||||
params := RenderParams{
|
||||
ViewportWidthPx: 100,
|
||||
ViewportHeightPx: 80,
|
||||
MarginXPx: 25,
|
||||
MarginYPx: 20,
|
||||
CameraXWorldFp: 5 * SCALE,
|
||||
CameraYWorldFp: 5 * SCALE,
|
||||
CameraZoom: 1.0,
|
||||
}
|
||||
require.NoError(t, w.CommitFullRedrawState(params))
|
||||
|
||||
// Pan camera right by 0.001 world units (1 fixed-point) 1000 times.
|
||||
// At zoom=1 this should accumulate to a 1px content shift left, hence image shift -1.
|
||||
totalDx := 0
|
||||
p := params
|
||||
for i := 0; i < 1000; i++ {
|
||||
p.CameraXWorldFp += 1
|
||||
dx, dy, err := w.ComputePanShiftPx(p)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, dy)
|
||||
totalDx += dx
|
||||
}
|
||||
|
||||
require.Equal(t, -1, totalDx)
|
||||
}
|
||||
Reference in New Issue
Block a user