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 CachedValue update CacheUpdateFn hash CacheHashFn } func NewCache(update CacheUpdateFn, hash CacheHashFn) *Cache { return &Cache{update: update, hash: hash} } func (c *Cache) Get(state interface{}) interface{} { return c.value.Get(state, c.update, c.hash) } type CacheContext struct { value CachedValue update CacheUpdateContextFn hash CacheHashContextFn } func NewCacheContext(update CacheUpdateContextFn, hash CacheHashContextFn) *CacheContext { return &CacheContext{update: update, hash: hash} } func (c *CacheContext) Get(ctx Context) interface{} { return c.value.GetContext(ctx, c.update, c.hash) } type CachedValue struct { value interface{} hash string } func (c *CachedValue) Get(state interface{}, update CacheUpdateFn, hash CacheHashFn) interface{} { if hash(state) != c.hash { c.value = update(state) } return c.value } func (c *CachedValue) GetContext(ctx Context, update CacheUpdateContextFn, hash CacheHashContextFn) interface{} { if hash(ctx) != c.hash { c.value = update(ctx) } return c.value }