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
|
Text string
|
||||||
|
|
||||||
size desiredSizeCache
|
init bool
|
||||||
|
size *Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildLabel(text string, fn func(*Label)) *Label {
|
func BuildLabel(text string, fn func(*Label)) *Label {
|
||||||
@ -20,23 +21,38 @@ func BuildLabel(text string, fn func(*Label)) *Label {
|
|||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Label) DesiredSize(ctx Context) geom.PointF32 {
|
func (l *Label) initialize() {
|
||||||
var fontName = l.FontName(ctx)
|
if l.init {
|
||||||
return l.size.Update(ctx, fontName+l.Text, func(ctx Context) geom.PointF32 {
|
return
|
||||||
var font = ctx.Renderer().Font(fontName)
|
}
|
||||||
var width = font.WidthOf(l.Text)
|
l.size = NewCacheContext(l.desiredSize, l.hashContent)
|
||||||
var height = font.Height()
|
l.init = true
|
||||||
var pad = ctx.Style().Dimensions.TextPadding
|
}
|
||||||
|
|
||||||
|
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)
|
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) {
|
func (l *Label) Render(ctx Context) {
|
||||||
l.RenderBackground(ctx)
|
l.RenderBackground(ctx)
|
||||||
var c = l.FontColor(ctx)
|
c := l.FontColor(ctx)
|
||||||
var f = l.FontName(ctx)
|
f := l.FontName(ctx)
|
||||||
var pad = ctx.Style().Dimensions.TextPadding
|
pad := ctx.Style().Dimensions.TextPadding
|
||||||
var bounds = l.bounds.Inset(pad)
|
bounds := l.bounds.Inset(pad)
|
||||||
switch l.TextAlignment {
|
switch l.TextAlignment {
|
||||||
case AlignLeft:
|
case AlignLeft:
|
||||||
ctx.Renderer().TextAlign(bounds.Min, f, c, l.Text, l.TextAlignment)
|
ctx.Renderer().TextAlign(bounds.Min, f, c, l.Text, l.TextAlignment)
|
||||||
|
Loading…
Reference in New Issue
Block a user