ui: basic map scroller
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
// Pseudo-code / toolkit-agnostic example.
|
||||
// Goal: never render more than one frame concurrently, and always render the latest params.
|
||||
//
|
||||
// Это не “асинхронная работа в фоне”, а чистый паттерн управления вызовами Render.
|
||||
// Он работает в любом UI, где у тебя есть loop и возможность запускать отрисовку
|
||||
// (например, через requestAnimationFrame-аналог или таски).
|
||||
//
|
||||
// Как это сочетается с CoalesceUpdates
|
||||
// - Если params.Options.Incremental.CoalesceUpdates == true, UI использует этот scheduler.
|
||||
// - Если false, UI может пытаться рендерить каждое событие (но это обычно хуже).
|
||||
//
|
||||
// # Важный момент
|
||||
//
|
||||
// Это не делает рендер асинхронным в смысле “рендерить в фоне” — в реальном UI ты должен
|
||||
// выполнять w.Render строго в UI thread. Я показал go только как “планировщик”
|
||||
// (в твоём GUI заменишь на invokeOnMainThread/PostTask/RunOnUI).
|
||||
package world
|
||||
|
||||
import "sync"
|
||||
|
||||
type RenderScheduler struct {
|
||||
w *World
|
||||
drawer PrimitiveDrawer
|
||||
|
||||
// Protects fields below.
|
||||
mu sync.Mutex
|
||||
|
||||
inFlight bool
|
||||
pending bool
|
||||
latest RenderParams
|
||||
}
|
||||
|
||||
// RequestRender stores the latest params and schedules rendering.
|
||||
// If a render is already in progress, it coalesces (drops intermediate requests).
|
||||
func (s *RenderScheduler) RequestRender(params RenderParams) {
|
||||
s.mu.Lock()
|
||||
s.latest = params
|
||||
if s.inFlight {
|
||||
s.pending = true
|
||||
s.mu.Unlock()
|
||||
return
|
||||
}
|
||||
s.inFlight = true
|
||||
s.mu.Unlock()
|
||||
|
||||
// Schedule on the UI thread/event loop. Replace this with your toolkit method.
|
||||
go s.runOnUIThread()
|
||||
}
|
||||
|
||||
// runOnUIThread should execute on the UI thread.
|
||||
// Replace the body with actual UI scheduling primitives.
|
||||
func (s *RenderScheduler) runOnUIThread() {
|
||||
for {
|
||||
s.mu.Lock()
|
||||
params := s.latest
|
||||
s.mu.Unlock()
|
||||
|
||||
_ = s.w.Render(s.drawer, params) // handle error in real code
|
||||
|
||||
s.mu.Lock()
|
||||
if !s.pending {
|
||||
s.inFlight = false
|
||||
s.mu.Unlock()
|
||||
return
|
||||
}
|
||||
// There was a newer request while we were rendering. Loop and render latest.
|
||||
s.pending = false
|
||||
s.mu.Unlock()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user