Files
ngzz-mc/internal/engine/loop.go

56 lines
1.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package engine 主循环:tick 固定 20Hz、render 吃满帧率、两者解耦(架构.md §3.2)。
package engine
import (
"context"
"time"
)
// Ticker 世界逻辑接口:每 tick 调用,dt 为固定 tick 间隔秒数。
type Ticker interface {
Tick(dt float64)
}
// Renderer 渲染接口:每帧调用;ShouldClose 返回 true 时退出循环。
type Renderer interface {
Render()
ShouldClose() bool
}
// NoopRenderer 无渲染占位(服务器),以约 60Hz 空转。
type NoopRenderer struct{}
// Render 空实现。
func (NoopRenderer) Render() { time.Sleep(time.Second / 60) }
// ShouldClose 永不主动关闭。
func (NoopRenderer) ShouldClose() bool { return false }
// Run 主循环:tick goroutine 固定 20Hz;主 goroutine 渲染;ctx 取消或窗口关闭时退出。
func Run(ctx context.Context, tick Ticker, render Renderer) {
const tickInterval = time.Second / 20
stop := make(chan struct{})
go func() {
t := time.NewTicker(tickInterval)
defer t.Stop()
for {
select {
case <-ctx.Done():
return
case <-stop:
return
case <-t.C:
tick.Tick(tickInterval.Seconds())
}
}
}()
defer close(stop)
for {
if ctx.Err() != nil || render.ShouldClose() {
return
}
render.Render()
}
}