ichigo/engine/debug.go

119 lines
2.3 KiB
Go

package engine
import (
"compress/gzip"
"encoding/gob"
"errors"
"fmt"
"math"
"os"
"time"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
)
var (
_ Drawer = PerfDisplay{}
_ DrawOrderer = PerfDisplay{}
_ Hider = &PerfDisplay{}
_ Disabler = &GobDumper{}
_ Prepper = &GobDumper{}
_ Updater = &GobDumper{}
)
func init() {
gob.Register(&GobDumper{})
gob.Register(&PerfDisplay{})
}
// DebugToast debugprints a string for a while, then disappears.
type DebugToast struct {
ID
Hidden
Timer int // ticks
Text string
}
func (d *DebugToast) Draw(screen *ebiten.Image, _ ebiten.DrawImageOptions) {
if d.Hidden {
return
}
ebitenutil.DebugPrintAt(screen, d.Text, 0, 20)
}
func (d *DebugToast) DrawOrder() float64 {
return math.MaxFloat64
}
func (d *DebugToast) Toast(text string) {
d.Text = text
d.Timer = 120
d.Hidden = false
}
func (d *DebugToast) Update() error {
if d.Hidden = d.Timer <= 0; !d.Hidden {
d.Timer--
}
return nil
}
// PerfDisplay debugprints CurrentTPS and CurrentFPS in the top left.
type PerfDisplay struct {
Hidden
}
func (p PerfDisplay) Draw(screen *ebiten.Image, _ ebiten.DrawImageOptions) {
if p.Hidden {
return
}
ebitenutil.DebugPrint(screen, fmt.Sprintf("TPS: %0.2f FPS: %0.2f", ebiten.CurrentTPS(), ebiten.CurrentFPS()))
}
func (PerfDisplay) DrawOrder() float64 {
// Always draw on top
return math.MaxFloat64
}
// GobDumper waits for a given key combo, then dumps the game into a gob file
// in the current directory.
type GobDumper struct {
Disabled
KeyCombo []ebiten.Key
game *Game
}
// Prepare simply stores the reference to the Game.
func (d *GobDumper) Prepare(g *Game) { d.game = g }
// Update waits for the key combo, then dumps the game state into a gzipped gob.
func (d *GobDumper) Update() error {
if d.Disabled {
return nil
}
for _, key := range d.KeyCombo {
if !ebiten.IsKeyPressed(key) {
return nil
}
}
if d.game == nil {
return errors.New("nil d.game in GobDumper.Update")
}
f, err := os.Create(time.Now().Format("20060102030405.gob.gz"))
if err != nil {
return err
}
defer f.Close()
gz := gzip.NewWriter(f)
defer gz.Close()
if err := gob.NewEncoder(gz).Encode(d.game); err != nil {
return err
}
if err := gz.Close(); err != nil {
return err
}
return f.Close()
}