github.com/15mga/kiwi@v0.0.2-0.20240324021231-b95d5c3ac751/graph/point.go (about) 1 package graph 2 3 import ( 4 "github.com/15mga/kiwi" 5 "github.com/15mga/kiwi/ds" 6 "github.com/15mga/kiwi/util" 7 ) 8 9 type IPoint interface { 10 IGraphElem 11 Type() TPoint 12 Node() INode 13 AddLink(lnk ILink) 14 GetLink(name string) (ILink, *util.Err) 15 AddFilter(func(IMsg) *util.Err) 16 } 17 18 type TPoint string 19 20 const ( 21 TpNone = "none" 22 ) 23 24 type IOut interface { 25 IPoint 26 Send(msg IMsg) *util.Err 27 } 28 29 type IIn interface { 30 IPoint 31 Receive(msg IMsg) *util.Err 32 } 33 34 func newPoint(n INode, t TPoint, name string) *point { 35 return &point{ 36 IGraphElem: newGraphElem(n.Graph(), name), 37 node: n, 38 typ: t, 39 links: make([]ILink, 0, 1), 40 nameToLink: make(map[string]ILink, 1), 41 } 42 } 43 44 type point struct { 45 IGraphElem 46 node INode 47 typ TPoint 48 links []ILink 49 nameToLink map[string]ILink 50 filter *ds.FnErrLink1[IMsg] 51 } 52 53 func (p *point) Type() TPoint { 54 return p.typ 55 } 56 57 func (p *point) AddLink(lnk ILink) { 58 p.nameToLink[lnk.Name()] = lnk 59 p.links = append(p.links, lnk) 60 } 61 62 func (p *point) GetLink(name string) (ILink, *util.Err) { 63 lnk, ok := p.nameToLink[name] 64 if !ok { 65 return nil, util.NewErr(util.EcNotExist, util.M{ 66 "name": name, 67 "point": p.Name(), 68 "node": p.node.Name(), 69 //"graph": p. 70 }) 71 } 72 return lnk, nil 73 } 74 75 func (p *point) Node() INode { 76 return p.node 77 } 78 79 func (p *point) AddFilter(fn func(IMsg) *util.Err) { 80 if p.filter == nil { 81 p.filter = ds.NewFnErrLink1[IMsg]() 82 } 83 p.filter.Push(fn) 84 } 85 86 func newPIn(n INode, t TPoint, name string) IIn { 87 return &in{ 88 point: newPoint(n, t, name), 89 } 90 } 91 92 type in struct { 93 *point 94 } 95 96 func (i *in) Receive(msg IMsg) *util.Err { 97 if msg.Type() != i.Type() { 98 return util.NewErr(util.EcType, util.M{ 99 "msg type": msg.Type(), 100 "in": i.Name(), 101 "node": i.node.Name(), 102 }) 103 } 104 if !i.Enabled() { 105 return nil 106 } 107 msg.SetInPoint(i.Name()) 108 if i.filter != nil { 109 err := i.filter.Invoke(msg) 110 if err != nil { 111 err.AddParam("in", i.Path()) 112 return err 113 } 114 } 115 err := i.node.ProcessData(msg) 116 if err != nil { 117 err.AddParam("in", i.Path()) 118 return err 119 } 120 return nil 121 } 122 123 func newOut(n INode, t TPoint, name string) IOut { 124 return &out{ 125 point: newPoint(n, t, name), 126 } 127 } 128 129 type out struct { 130 *point 131 } 132 133 func (o *out) Send(msg IMsg) *util.Err { 134 if msg.Type() != o.Type() { 135 return util.NewErr(util.EcType, util.M{ 136 "msg type": msg.Type(), 137 "in type": o.Path(), 138 }) 139 } 140 if !o.Enabled() { 141 return nil 142 } 143 if o.filter != nil { 144 err := o.filter.Invoke(msg) 145 if err != nil { 146 return err 147 } 148 } 149 for _, lnk := range o.links { 150 err := lnk.Transfer(msg) 151 if err != nil { 152 kiwi.Error(err) 153 } 154 } 155 return nil 156 }