go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/projects/nodes/pkg/incrutil/always.go (about) 1 /* 2 3 Copyright (c) 2023 - Present. Will Charczuk. All rights reserved. 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository. 5 6 */ 7 8 package incrutil 9 10 import ( 11 "fmt" 12 13 "github.com/wcharczuk/go-incr" 14 ) 15 16 // Always yields an incremental that is always stale. 17 // 18 // The way to use this effectively is to place this node above a tree of 19 // nodes that should always be recomputed, but specifically you'll likely 20 // want to pair this with a cutoff _below_ the immediate child of the always node 21 // such that you don't just always recompute an entire subgraph. 22 func Always[A any](scope incr.Scope) AlwaysIncr[A] { 23 return incr.WithinScope(scope, &alwaysIncr[A]{ 24 n: incr.NewNode("always"), 25 }) 26 } 27 28 // AlwaysIncr is an incremental that implements the always interface. 29 type AlwaysIncr[A any] interface { 30 incr.AlwaysIncr[A] 31 ISetInput 32 IRemoveInput 33 IInputs 34 } 35 36 type alwaysIncr[A any] struct { 37 n *incr.Node 38 input incr.Incr[A] 39 } 40 41 func (a *alwaysIncr[A]) Parents() []incr.INode { 42 if a.input != nil { 43 return []incr.INode{a.input} 44 } 45 return nil 46 } 47 48 func (a *alwaysIncr[A]) SetInput(name string, i incr.INode, _ bool) error { 49 typed, ok := i.(incr.Incr[A]) 50 if !ok || typed == nil { 51 return fmt.Errorf("invalid untyped input for map node %T", i) 52 } 53 a.input = typed 54 LinkNodes(a, i) 55 return nil 56 } 57 58 func (a *alwaysIncr[A]) RemoveInput(name string) error { 59 if a.input != nil { 60 UnlinkNodes(a, a.input) 61 a.input = nil 62 return nil 63 } 64 return fmt.Errorf("remove input; input is unset") 65 } 66 67 func (a *alwaysIncr[A]) Inputs() map[string]incr.INode { 68 if a.input != nil { 69 return map[string]incr.INode{ 70 "input": a.input, 71 } 72 } 73 return nil 74 } 75 76 func (a *alwaysIncr[A]) Always() {} 77 78 func (a *alwaysIncr[A]) Value() A { 79 return a.input.Value() 80 } 81 82 func (a *alwaysIncr[A]) Node() *incr.Node { return a.n } 83 84 func (a *alwaysIncr[A]) String() string { 85 return a.n.String() 86 }