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  }