From 5e0d8a36df4ecd4fc9784728e94abe871dd9248d Mon Sep 17 00:00:00 2001 From: Jacek Olszak Date: Wed, 1 Apr 2026 18:58:12 +0200 Subject: [PATCH] Add piloop.Stop() function This function can be used to stop the game loop. --- _examples/stop/main.go | 16 ++++++++++++++++ piebiten/internal/ebitengame.go | 15 +++++++++++++-- piloop/event.go | 1 + piloop/piloop.go | 4 ++++ 4 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 _examples/stop/main.go diff --git a/_examples/stop/main.go b/_examples/stop/main.go new file mode 100644 index 00000000..f6167f1d --- /dev/null +++ b/_examples/stop/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "github.com/elgopher/pi/piebiten" + "github.com/elgopher/pi/pikey" + "github.com/elgopher/pi/piloop" +) + +func main() { + // stops the game loop when user pressed Escape key + pikey.RegisterShortcut(piloop.Stop, pikey.Esc) + + piebiten.Run() // this function ends without panic once game loop is stopped + + // Code in here is executed after loop is stopped +} diff --git a/piebiten/internal/ebitengame.go b/piebiten/internal/ebitengame.go index d77b3dc3..5a7bcedc 100644 --- a/piebiten/internal/ebitengame.go +++ b/piebiten/internal/ebitengame.go @@ -4,12 +4,13 @@ package internal import ( + "math" + "time" + "github.com/elgopher/pi/piaudio" "github.com/elgopher/pi/piebiten/internal/audio" "github.com/elgopher/pi/piebiten/internal/input" ebitenaudio "github.com/hajimehoshi/ebiten/v2/audio" - "math" - "time" "github.com/hajimehoshi/ebiten/v2" @@ -40,6 +41,7 @@ func RunEbitenGame() *EbitenGame { } pidebug.Target().SubscribeAll(game.onPidebugEvent) + piloop.Target().Subscribe(piloop.EventStop, game.onPiloopStopEvent) return game } @@ -87,9 +89,14 @@ type EbitenGame struct { inputBackend *input.Backend ebitenFrame int // frame incremented on each Ebiten tick + + stopped bool } func (g *EbitenGame) Update() error { + if g.stopped { + return ebiten.Termination + } if ebiten.IsWindowBeingClosed() { piloop.Target().Publish(piloop.EventWindowClose) return ebiten.Termination @@ -217,3 +224,7 @@ func (g *EbitenGame) onPidebugEvent(event pidebug.Event, _ pievent.Handler) { g.paused = false } } + +func (g *EbitenGame) onPiloopStopEvent(piloop.Event, pievent.Handler) { + g.stopped = true +} diff --git a/piloop/event.go b/piloop/event.go index ab6187f4..98ef3bc5 100644 --- a/piloop/event.go +++ b/piloop/event.go @@ -13,4 +13,5 @@ const ( EventDraw Event = "draw" // after pi.Draw EventLateDraw Event = "late_draw" // after EventDraw EventWindowClose Event = "window_close" // when a user closes the window (desktop only) + EventStop Event = "stop" // when game loop is stopped by calling piloop.Stop() ) diff --git a/piloop/piloop.go b/piloop/piloop.go index ae746e63..8e37df49 100644 --- a/piloop/piloop.go +++ b/piloop/piloop.go @@ -17,6 +17,10 @@ func DebugTarget() pievent.Target[Event] { return debugTarget } +func Stop() { + Target().Publish(EventStop) +} + var ( target = pievent.NewTarget[Event]() debugTarget = pievent.NewTarget[Event]()