Made cache more generic.
This commit is contained in:
parent
280b4842e8
commit
5ecfd10754
38
ui/cache.go
Normal file
38
ui/cache.go
Normal file
@ -0,0 +1,38 @@
|
||||
package ui
|
||||
|
||||
type CacheHashFn func(interface{}) string
|
||||
type CacheHashContextFn func(Context) string
|
||||
|
||||
func (c CacheHashContextFn) Fn() CacheHashFn {
|
||||
return func(state interface{}) string { return c(state.(Context)) }
|
||||
}
|
||||
|
||||
type CacheUpdateFn func(interface{}) interface{}
|
||||
type CacheUpdateContextFn func(Context) interface{}
|
||||
|
||||
func (c CacheUpdateContextFn) Fn() CacheUpdateFn {
|
||||
return func(state interface{}) interface{} { return c(state.(Context)) }
|
||||
}
|
||||
|
||||
type Cache struct {
|
||||
value interface{}
|
||||
hash string
|
||||
|
||||
updateFn CacheUpdateFn
|
||||
hashFn CacheHashFn
|
||||
}
|
||||
|
||||
func NewCache(update CacheUpdateFn, hash CacheHashFn) *Cache {
|
||||
return &Cache{updateFn: update, hashFn: hash}
|
||||
}
|
||||
|
||||
func NewCacheContext(update CacheUpdateContextFn, hash CacheHashContextFn) *Cache {
|
||||
return NewCache(update.Fn(), hash.Fn())
|
||||
}
|
||||
|
||||
func (c *Cache) Get(state interface{}) interface{} {
|
||||
if c.hashFn(state) != c.hash {
|
||||
c.value = c.updateFn(state)
|
||||
}
|
||||
return c.value
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"github.com/minio/highwayhash"
|
||||
"opslag.de/schobers/geom"
|
||||
)
|
||||
|
||||
type desiredSizeCache struct {
|
||||
sum [32]byte
|
||||
size geom.PointF32
|
||||
}
|
||||
|
||||
func (c *desiredSizeCache) Update(ctx Context, data string, calcFn func(Context) geom.PointF32) geom.PointF32 {
|
||||
var key = [32]byte{}
|
||||
sum := highwayhash.Sum([]byte(data), key[:])
|
||||
if c.sum != sum {
|
||||
c.size = calcFn(ctx)
|
||||
c.sum = sum
|
||||
}
|
||||
return c.size
|
||||
}
|
42
ui/label.go
42
ui/label.go
@ -9,7 +9,8 @@ type Label struct {
|
||||
|
||||
Text string
|
||||
|
||||
size desiredSizeCache
|
||||
init bool
|
||||
size *Cache
|
||||
}
|
||||
|
||||
func BuildLabel(text string, fn func(*Label)) *Label {
|
||||
@ -20,23 +21,38 @@ func BuildLabel(text string, fn func(*Label)) *Label {
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *Label) DesiredSize(ctx Context) geom.PointF32 {
|
||||
var fontName = l.FontName(ctx)
|
||||
return l.size.Update(ctx, fontName+l.Text, func(ctx Context) geom.PointF32 {
|
||||
var font = ctx.Renderer().Font(fontName)
|
||||
var width = font.WidthOf(l.Text)
|
||||
var height = font.Height()
|
||||
var pad = ctx.Style().Dimensions.TextPadding
|
||||
func (l *Label) initialize() {
|
||||
if l.init {
|
||||
return
|
||||
}
|
||||
l.size = NewCacheContext(l.desiredSize, l.hashContent)
|
||||
l.init = true
|
||||
}
|
||||
|
||||
func (l *Label) hashContent(ctx Context) string {
|
||||
return l.FontName(ctx) + l.Text
|
||||
}
|
||||
|
||||
func (l *Label) desiredSize(ctx Context) interface{} {
|
||||
fontName := l.FontName(ctx)
|
||||
font := ctx.Renderer().Font(fontName)
|
||||
width := font.WidthOf(l.Text)
|
||||
height := font.Height()
|
||||
pad := ctx.Style().Dimensions.TextPadding
|
||||
return geom.PtF32(width+pad*2, height+pad*2)
|
||||
})
|
||||
}
|
||||
|
||||
func (l *Label) DesiredSize(ctx Context) geom.PointF32 {
|
||||
l.initialize()
|
||||
return l.size.Get(ctx).(geom.PointF32)
|
||||
}
|
||||
|
||||
func (l *Label) Render(ctx Context) {
|
||||
l.RenderBackground(ctx)
|
||||
var c = l.FontColor(ctx)
|
||||
var f = l.FontName(ctx)
|
||||
var pad = ctx.Style().Dimensions.TextPadding
|
||||
var bounds = l.bounds.Inset(pad)
|
||||
c := l.FontColor(ctx)
|
||||
f := l.FontName(ctx)
|
||||
pad := ctx.Style().Dimensions.TextPadding
|
||||
bounds := l.bounds.Inset(pad)
|
||||
switch l.TextAlignment {
|
||||
case AlignLeft:
|
||||
ctx.Renderer().TextAlign(bounds.Min, f, c, l.Text, l.TextAlignment)
|
||||
|
Loading…
Reference in New Issue
Block a user