mirror of
https://github.com/duanhf2012/origin.git
synced 2026-02-03 22:45:13 +08:00
优化代码
This commit is contained in:
@@ -1,19 +1,24 @@
|
||||
package blueprint
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Blueprint struct {
|
||||
execPool ExecPool
|
||||
graphPool GraphPool
|
||||
}
|
||||
|
||||
func (bm *Blueprint) Init(execDefFilePath string, graphFilePath string, onRegister func(execPool *ExecPool) error) error {
|
||||
func (bm *Blueprint) Init(execDefFilePath string, graphFilePath string) error {
|
||||
err := bm.execPool.Load(execDefFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = onRegister(&bm.execPool)
|
||||
if err != nil {
|
||||
return err
|
||||
for _, e := range execNodes {
|
||||
if !bm.execPool.Register(e) {
|
||||
return fmt.Errorf("register exec failed,exec:%s", e.GetName())
|
||||
}
|
||||
}
|
||||
|
||||
err = bm.graphPool.Load(&bm.execPool, graphFilePath)
|
||||
|
||||
@@ -1,65 +1,36 @@
|
||||
package blueprint
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type Entrance_IntParam struct {
|
||||
BaseExecNode
|
||||
}
|
||||
|
||||
func (em *Entrance_IntParam) GetName() string {
|
||||
return "Entrance_IntParam"
|
||||
}
|
||||
|
||||
func (em *Entrance_IntParam) Exec() (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
type Output struct {
|
||||
BaseExecNode
|
||||
}
|
||||
|
||||
func (em *Output) GetName() string {
|
||||
return "Output"
|
||||
}
|
||||
|
||||
func (em *Output) Exec() (int, error) {
|
||||
val, ok := em.GetInPortInt(1)
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("Output Exec inParam not found")
|
||||
}
|
||||
|
||||
fmt.Printf("Output Exec inParam %d", val)
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func OnRegister(bm *ExecPool) error {
|
||||
bm.Register(&Entrance_IntParam{})
|
||||
bm.Register(&Output{})
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
EntranceID_IntParam = 3
|
||||
)
|
||||
|
||||
func TestExecMgr(t *testing.T) {
|
||||
//
|
||||
|
||||
var bp Blueprint
|
||||
err := bp.Init("./json/", "./vgf/", OnRegister)
|
||||
err := bp.Init("D:\\Develop\\OriginNodeEditor\\json", "D:\\Develop\\OriginNodeEditor\\vgf")
|
||||
if err != nil {
|
||||
t.Fatalf("init failed,err:%v", err)
|
||||
}
|
||||
|
||||
graphTest2 := bp.Create("test2")
|
||||
|
||||
err = graphTest2.Do(EntranceID_IntParam, 1, 2, 3)
|
||||
graphTest1 := bp.Create("testArray")
|
||||
err = graphTest1.Do(EntranceID_ArrayParam, 1, []int64{10, 11, 12})
|
||||
if err != nil {
|
||||
t.Fatalf("Do EntranceID_IntParam failed,err:%v", err)
|
||||
}
|
||||
|
||||
//graphTest2 := bp.Create("testForeach")
|
||||
//err = graphTest2.Do(EntranceID_IntParam, 1, 2, 3)
|
||||
//if err != nil {
|
||||
// t.Fatalf("Do EntranceID_IntParam failed,err:%v", err)
|
||||
//}
|
||||
|
||||
//graphTest2 := bp.Create("test2")
|
||||
//
|
||||
//err = graphTest2.Do(EntranceID_IntParam, 1, 2, 3)
|
||||
//if err != nil {
|
||||
// t.Fatalf("Do EntranceID_IntParam failed,err:%v", err)
|
||||
//}
|
||||
|
||||
//graph := bp.Create("test1")
|
||||
//err = graph.Do(EntranceID_IntParam, 1, 2, 3)
|
||||
//if err != nil {
|
||||
|
||||
@@ -39,11 +39,12 @@ type innerExecNode struct {
|
||||
Package string
|
||||
Description string
|
||||
|
||||
InPort []IPort
|
||||
OutPort []IPort
|
||||
inPort []IPort
|
||||
outPort []IPort
|
||||
|
||||
inPortParamStartIndex int // 输入参数的起始索引,用于排除执行入口
|
||||
outPortParamStartIndex int // 输出参数的起始索引,用于排除执行出口
|
||||
|
||||
IExecNode
|
||||
}
|
||||
|
||||
@@ -82,28 +83,28 @@ type BaseExecConfig struct {
|
||||
}
|
||||
|
||||
func (em *innerExecNode) AppendInPort(port ...IPort) {
|
||||
if len(em.InPort) == 0 {
|
||||
if len(em.inPort) == 0 {
|
||||
em.inPortParamStartIndex = -1
|
||||
}
|
||||
|
||||
for i := 0; i < len(port); i++ {
|
||||
if !port[i].IsPortExec() && em.inPortParamStartIndex < 0 {
|
||||
em.inPortParamStartIndex = len(em.InPort)
|
||||
em.inPortParamStartIndex = len(em.inPort)
|
||||
}
|
||||
|
||||
em.InPort = append(em.InPort, port[i])
|
||||
em.inPort = append(em.inPort, port[i])
|
||||
}
|
||||
}
|
||||
|
||||
func (em *innerExecNode) AppendOutPort(port ...IPort) {
|
||||
if len(em.OutPort) == 0 {
|
||||
if len(em.outPort) == 0 {
|
||||
em.outPortParamStartIndex = -1
|
||||
}
|
||||
for i := 0; i < len(port); i++ {
|
||||
if !port[i].IsPortExec() && em.outPortParamStartIndex < 0 {
|
||||
em.outPortParamStartIndex = len(em.OutPort)
|
||||
em.outPortParamStartIndex = len(em.outPort)
|
||||
}
|
||||
em.OutPort = append(em.OutPort, port[i])
|
||||
em.outPort = append(em.outPort, port[i])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +118,7 @@ func (em *innerExecNode) SetExec(exec IExecNode) {
|
||||
|
||||
func (em *innerExecNode) CloneInOutPort() ([]IPort, []IPort) {
|
||||
inPorts := make([]IPort, 0, 2)
|
||||
for _, port := range em.InPort {
|
||||
for _, port := range em.inPort {
|
||||
if port.IsPortExec() {
|
||||
// 执行入口, 不需要克隆,占位处理
|
||||
inPorts = append(inPorts, nil)
|
||||
@@ -128,7 +129,7 @@ func (em *innerExecNode) CloneInOutPort() ([]IPort, []IPort) {
|
||||
}
|
||||
outPorts := make([]IPort, 0, 2)
|
||||
|
||||
for _, port := range em.OutPort {
|
||||
for _, port := range em.outPort {
|
||||
if port.IsPortExec() {
|
||||
outPorts = append(outPorts, nil)
|
||||
continue
|
||||
@@ -140,40 +141,40 @@ func (em *innerExecNode) CloneInOutPort() ([]IPort, []IPort) {
|
||||
}
|
||||
|
||||
func (em *innerExecNode) IsInPortExec(index int) bool {
|
||||
if index >= len(em.InPort) || index < 0 {
|
||||
if index >= len(em.inPort) || index < 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return em.InPort[index].IsPortExec()
|
||||
return em.inPort[index].IsPortExec()
|
||||
}
|
||||
func (em *innerExecNode) IsOutPortExec(index int) bool {
|
||||
if index >= len(em.OutPort) || index < 0 {
|
||||
if index >= len(em.outPort) || index < 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return em.OutPort[index].IsPortExec()
|
||||
return em.outPort[index].IsPortExec()
|
||||
}
|
||||
|
||||
func (em *innerExecNode) GetInPortCount() int {
|
||||
return len(em.InPort)
|
||||
return len(em.inPort)
|
||||
}
|
||||
|
||||
func (em *innerExecNode) GetOutPortCount() int {
|
||||
return len(em.OutPort)
|
||||
return len(em.outPort)
|
||||
}
|
||||
|
||||
func (em *innerExecNode) GetInPort(index int) IPort {
|
||||
if index >= len(em.InPort) || index < 0 {
|
||||
if index >= len(em.inPort) || index < 0 {
|
||||
return nil
|
||||
}
|
||||
return em.InPort[index]
|
||||
return em.inPort[index]
|
||||
}
|
||||
|
||||
func (em *innerExecNode) GetOutPort(index int) IPort {
|
||||
if index >= len(em.OutPort) || index < 0 {
|
||||
if index >= len(em.outPort) || index < 0 {
|
||||
return nil
|
||||
}
|
||||
return em.OutPort[index]
|
||||
return em.outPort[index]
|
||||
}
|
||||
|
||||
func (em *innerExecNode) GetInPortParamStartIndex() int {
|
||||
@@ -390,7 +391,7 @@ func (en *BaseExecNode) AppendInPortArrayValStr(index int, val Port_Str) bool {
|
||||
return port.AppendArrayValStr(val)
|
||||
}
|
||||
|
||||
func (en *BaseExecNode) GetInPortArrayLen(index int) int {
|
||||
func (en *BaseExecNode) GetInPortArrayLen(index int) Port_Int {
|
||||
port := en.GetInPort(index)
|
||||
if port == nil {
|
||||
return 0
|
||||
@@ -462,7 +463,7 @@ func (en *BaseExecNode) AppendOutPortArrayValStr(index int, val Port_Str) bool {
|
||||
return port.AppendArrayValStr(val)
|
||||
}
|
||||
|
||||
func (en *BaseExecNode) GetOutPortArrayLen(index int) int {
|
||||
func (en *BaseExecNode) GetOutPortArrayLen(index int) Port_Int {
|
||||
port := en.GetOutPort(index)
|
||||
if port == nil {
|
||||
return 0
|
||||
|
||||
@@ -182,6 +182,7 @@ func (gp *GraphPool) prepareOneNode(mapNodeExec map[string]*execNode, nodeExec *
|
||||
if nextExecNode == nil {
|
||||
continue
|
||||
}
|
||||
nextExecNode.beConnect = true
|
||||
nodeExec.nextNode = append(nodeExec.nextNode, nextExecNode)
|
||||
}
|
||||
|
||||
@@ -222,13 +223,14 @@ func (gp *GraphPool) prepareOneEntrance(graphName string, entranceID int64, node
|
||||
return fmt.Errorf("entrance node %s not found", nodeCfg.Id)
|
||||
}
|
||||
|
||||
nodeExec.isEntrance = true
|
||||
err = gp.prepareOneNode(mapNodes, nodeExec, graphConfig, new(int))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 处理inPort前置结点
|
||||
err = gp.prepareInPort(mapNodes, nodeExec, graphConfig)
|
||||
err = gp.prepareInPort(mapNodes, graphConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -283,19 +285,10 @@ func (gp *GraphPool) preparePreInPortNode(mapNodes map[string]*execNode, nodeExe
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gp *GraphPool) prepareInPort(mapNodeExec map[string]*execNode, nodeExec *execNode, graphConfig *graphConfig) error {
|
||||
for _, nextNode := range nodeExec.nextNode {
|
||||
if nextNode == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对nextNode结点的入口进行预处理
|
||||
err := gp.preparePreInPortNode(mapNodeExec, nextNode, graphConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = gp.prepareInPort(mapNodeExec, nextNode, graphConfig)
|
||||
func (gp *GraphPool) prepareInPort(mapNodeExec map[string]*execNode, graphConfig *graphConfig) error {
|
||||
for _, e := range mapNodeExec {
|
||||
// 对当前结点的入口进行预处理
|
||||
err := gp.preparePreInPortNode(mapNodeExec, e, graphConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package blueprint
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type prePortNode struct {
|
||||
node *execNode // 上个结点
|
||||
@@ -18,6 +20,23 @@ type execNode struct {
|
||||
inPortDefaultValue map[string]any
|
||||
|
||||
variableName string // 如果是变量,则有变量名
|
||||
beConnect bool // 是否有被连线
|
||||
isEntrance bool // 是否是入口结点
|
||||
}
|
||||
|
||||
// HasBeConnectLine 是否有被连线
|
||||
func (en *execNode) HasBeConnectLine() bool {
|
||||
return en.beConnect
|
||||
}
|
||||
|
||||
// HasInPortExec 有前置执行入口
|
||||
func (en *execNode) HasInPortExec() bool {
|
||||
return en.execNode.IsInPortExec(0)
|
||||
}
|
||||
|
||||
// HasOutPortExec 有前置执行入口
|
||||
func (en *execNode) HasOutPortExec() bool {
|
||||
return en.execNode.IsOutPortExec(0)
|
||||
}
|
||||
|
||||
func (en *execNode) GetInPortDefaultValue(index int) any {
|
||||
@@ -52,6 +71,7 @@ func (en *execNode) exec(gr *Graph) (int, error) {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
//log.Debug("exec node %s", en.execNode.GetName())
|
||||
return e.Exec()
|
||||
}
|
||||
|
||||
@@ -67,9 +87,10 @@ func (en *execNode) doSetInPort(gr *Graph, index int, inPort IPort) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, ok := gr.context[preNode.node.Id]; !ok {
|
||||
if _, ok := gr.context[preNode.node.Id]; !ok ||
|
||||
(!preNode.node.HasBeConnectLine() && !preNode.node.isEntrance) {
|
||||
// 如果前一个结点没有执行过,则递归执行前一个结点
|
||||
err := preNode.node.Do(gr, nil)
|
||||
err := preNode.node.Do(gr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -80,6 +80,13 @@ func (em *Port[T]) GetBool() (Port_Bool, bool) {
|
||||
return false, false
|
||||
}
|
||||
|
||||
func (em *Port[T]) GetArray() (Port_Array, bool) {
|
||||
if t, ok := any(em.PortVal).(Port_Array); ok {
|
||||
return t, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (em *Port[T]) SetInt(val Port_Int) bool {
|
||||
if t, ok := any(&em.PortVal).(*Port_Int); ok {
|
||||
*t = val
|
||||
@@ -148,9 +155,9 @@ func (em *Port[T]) AppendArrayValStr(val Port_Str) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (em *Port[T]) GetArrayLen() int {
|
||||
func (em *Port[T]) GetArrayLen() Port_Int {
|
||||
if t, ok := any(&em.PortVal).(*Port_Array); ok {
|
||||
return len(*t)
|
||||
return Port_Int(len(*t))
|
||||
}
|
||||
|
||||
return 0
|
||||
@@ -262,6 +269,51 @@ func (em *Port[T]) setAnyVale(v any) error {
|
||||
default:
|
||||
return fmt.Errorf("port type is %T, but value is %v", em.PortVal, v)
|
||||
}
|
||||
case []int64:
|
||||
arr := v.([]int64)
|
||||
for _, val := range arr {
|
||||
em.AppendArrayValInt(val)
|
||||
}
|
||||
case []int32:
|
||||
arr := v.([]int32)
|
||||
for _, val := range arr {
|
||||
em.AppendArrayValInt(Port_Int(val))
|
||||
}
|
||||
case []int16:
|
||||
arr := v.([]int16)
|
||||
for _, val := range arr {
|
||||
em.AppendArrayValInt(Port_Int(val))
|
||||
}
|
||||
case []int8:
|
||||
arr := v.([]int8)
|
||||
for _, val := range arr {
|
||||
em.AppendArrayValInt(Port_Int(val))
|
||||
}
|
||||
case []uint64:
|
||||
arr := v.([]uint64)
|
||||
for _, val := range arr {
|
||||
em.AppendArrayValInt(Port_Int(val))
|
||||
}
|
||||
case []uint32:
|
||||
arr := v.([]uint32)
|
||||
for _, val := range arr {
|
||||
em.AppendArrayValInt(Port_Int(val))
|
||||
}
|
||||
case []uint16:
|
||||
arr := v.([]uint16)
|
||||
for _, val := range arr {
|
||||
em.AppendArrayValInt(Port_Int(val))
|
||||
}
|
||||
case []uint8:
|
||||
arr := v.([]uint8)
|
||||
for _, val := range arr {
|
||||
em.AppendArrayValInt(Port_Int(val))
|
||||
}
|
||||
case []string:
|
||||
arr := v.([]string)
|
||||
for _, val := range arr {
|
||||
em.AppendArrayValStr(val)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -283,6 +335,7 @@ type IPort interface {
|
||||
GetArrayValInt(idx int) (Port_Int, bool)
|
||||
GetArrayValStr(idx int) (Port_Str, bool)
|
||||
GetBool() (Port_Bool, bool)
|
||||
GetArray() (Port_Array, bool)
|
||||
|
||||
SetInt(val Port_Int) bool
|
||||
SetFloat(val Port_Float) bool
|
||||
@@ -292,7 +345,7 @@ type IPort interface {
|
||||
SetArrayValStr(idx int, val Port_Str) bool
|
||||
AppendArrayValInt(val Port_Int) bool
|
||||
AppendArrayValStr(val Port_Str) bool
|
||||
GetArrayLen() int
|
||||
GetArrayLen() Port_Int
|
||||
Clone() IPort
|
||||
Reset()
|
||||
|
||||
|
||||
7
util/blueprint/register.go
Normal file
7
util/blueprint/register.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package blueprint
|
||||
|
||||
var execNodes []IExecNode
|
||||
|
||||
func RegExecNode(exec IExecNode) {
|
||||
execNodes = append(execNodes, exec)
|
||||
}
|
||||
226
util/blueprint/sysnodes.go
Normal file
226
util/blueprint/sysnodes.go
Normal file
@@ -0,0 +1,226 @@
|
||||
package blueprint
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duanhf2012/origin/v2/log"
|
||||
)
|
||||
|
||||
// 系统入口ID定义,1000以内
|
||||
const (
|
||||
EntranceID_ArrayParam = 2
|
||||
EntranceID_IntParam = 3
|
||||
)
|
||||
|
||||
func init() {
|
||||
RegExecNode(&Entrance_ArrayParam{})
|
||||
RegExecNode(&Entrance_IntParam{})
|
||||
RegExecNode(&Output{})
|
||||
RegExecNode(&Sequence{})
|
||||
RegExecNode(&Foreach{})
|
||||
RegExecNode(&GetArrayInt{})
|
||||
RegExecNode(&GetArrayString{})
|
||||
RegExecNode(&GetArrayLen{})
|
||||
}
|
||||
|
||||
type Entrance_ArrayParam struct {
|
||||
BaseExecNode
|
||||
}
|
||||
|
||||
func (em *Entrance_ArrayParam) GetName() string {
|
||||
return "Entrance_ArrayParam"
|
||||
}
|
||||
|
||||
func (em *Entrance_ArrayParam) Exec() (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
type Entrance_IntParam struct {
|
||||
BaseExecNode
|
||||
}
|
||||
|
||||
func (em *Entrance_IntParam) GetName() string {
|
||||
return "Entrance_IntParam"
|
||||
}
|
||||
|
||||
func (em *Entrance_IntParam) Exec() (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
type Output struct {
|
||||
BaseExecNode
|
||||
}
|
||||
|
||||
func (em *Output) GetName() string {
|
||||
return "Output"
|
||||
}
|
||||
|
||||
func (em *Output) Exec() (int, error) {
|
||||
val, ok := em.GetInPortInt(1)
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("Output Exec inParam not found")
|
||||
}
|
||||
|
||||
fmt.Printf("Output Exec inParam %d", val)
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
type Sequence struct {
|
||||
BaseExecNode
|
||||
}
|
||||
|
||||
func (em *Sequence) GetName() string {
|
||||
return "Sequence"
|
||||
}
|
||||
|
||||
func (em *Sequence) Exec() (int, error) {
|
||||
for i := range em.outPort {
|
||||
if !em.outPort[i].IsPortExec() {
|
||||
break
|
||||
}
|
||||
|
||||
err := em.DoNext(i)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
}
|
||||
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
type Foreach struct {
|
||||
BaseExecNode
|
||||
}
|
||||
|
||||
func (em *Foreach) GetName() string {
|
||||
return "Foreach"
|
||||
}
|
||||
|
||||
func (em *Foreach) Exec() (int, error) {
|
||||
startIndex, ok := em.ExecContext.InputPorts[1].GetInt()
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("foreach Exec inParam not found")
|
||||
}
|
||||
endIndex, ok := em.ExecContext.InputPorts[2].GetInt()
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("foreach Exec inParam not found")
|
||||
}
|
||||
|
||||
for i := startIndex; i < endIndex; i++ {
|
||||
em.ExecContext.OutputPorts[2].SetInt(i)
|
||||
err := em.DoNext(0)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
}
|
||||
|
||||
err := em.DoNext(1)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
type GetArrayInt struct {
|
||||
BaseExecNode
|
||||
}
|
||||
|
||||
func (em *GetArrayInt) GetName() string {
|
||||
return "GetArrayInt"
|
||||
}
|
||||
|
||||
func (em *GetArrayInt) Exec() (int, error) {
|
||||
inPort := em.GetInPort(0)
|
||||
if inPort == nil {
|
||||
return -1, fmt.Errorf("GetArrayInt inParam not found")
|
||||
}
|
||||
outPort := em.GetOutPort(0)
|
||||
if outPort == nil {
|
||||
return -1, fmt.Errorf("GetArrayInt outParam not found")
|
||||
}
|
||||
|
||||
arrIndexPort := em.GetInPort(1)
|
||||
if arrIndexPort == nil {
|
||||
return -1, fmt.Errorf("GetArrayInt arrIndexParam not found")
|
||||
}
|
||||
arrIndex, ok := arrIndexPort.GetInt()
|
||||
if !ok {
|
||||
return -1, fmt.Errorf("GetArrayInt arrIndexParam not found")
|
||||
}
|
||||
|
||||
if arrIndex < 0 || arrIndex >= inPort.GetArrayLen() {
|
||||
return -1, fmt.Errorf("GetArrayInt arrIndexParam out of range,index %d", arrIndex)
|
||||
}
|
||||
|
||||
val, ok := inPort.GetArrayValInt(int(arrIndex))
|
||||
if !ok {
|
||||
log.Errorf("GetArrayValInt failed, idx:%d", arrIndex)
|
||||
return -1, fmt.Errorf("GetArrayInt inParam not found")
|
||||
}
|
||||
|
||||
outPort.SetInt(val)
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
type GetArrayString struct {
|
||||
BaseExecNode
|
||||
}
|
||||
|
||||
func (em *GetArrayString) GetName() string {
|
||||
return "GetArrayString"
|
||||
}
|
||||
|
||||
func (em *GetArrayString) Exec() (int, error) {
|
||||
inPort := em.GetInPort(0)
|
||||
if inPort == nil {
|
||||
return -1, fmt.Errorf("GetArrayInt inParam not found")
|
||||
}
|
||||
outPort := em.GetOutPort(0)
|
||||
if outPort == nil {
|
||||
return -1, fmt.Errorf("GetArrayInt outParam not found")
|
||||
}
|
||||
|
||||
arrIndexPort := em.GetInPort(1)
|
||||
if arrIndexPort == nil {
|
||||
return -1, fmt.Errorf("GetArrayInt arrIndexParam not found")
|
||||
}
|
||||
arrIndex, ok := arrIndexPort.GetInt()
|
||||
if !ok {
|
||||
return -1, fmt.Errorf("GetArrayInt arrIndexParam not found")
|
||||
}
|
||||
|
||||
if arrIndex < 0 || arrIndex >= inPort.GetArrayLen() {
|
||||
return -1, fmt.Errorf("GetArrayInt arrIndexParam out of range,index %d", arrIndex)
|
||||
}
|
||||
|
||||
val, ok := inPort.GetArrayValStr(int(arrIndex))
|
||||
if !ok {
|
||||
log.Errorf("GetArrayValStr failed, idx:%d", arrIndex)
|
||||
return -1, fmt.Errorf("GetArrayInt inParam not found")
|
||||
}
|
||||
|
||||
outPort.SetStr(val)
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
type GetArrayLen struct {
|
||||
BaseExecNode
|
||||
}
|
||||
|
||||
func (em *GetArrayLen) GetName() string {
|
||||
return "GetArrayLen"
|
||||
}
|
||||
|
||||
func (em *GetArrayLen) Exec() (int, error) {
|
||||
inPort := em.GetInPort(0)
|
||||
if inPort == nil {
|
||||
return -1, fmt.Errorf("GetArrayInt inParam not found")
|
||||
}
|
||||
outPort := em.GetOutPort(0)
|
||||
if outPort == nil {
|
||||
return -1, fmt.Errorf("GetArrayInt outParam not found")
|
||||
}
|
||||
|
||||
outPort.SetInt(inPort.GetArrayLen())
|
||||
return -1, nil
|
||||
}
|
||||
41
util/stack/stack.go
Normal file
41
util/stack/stack.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package stack
|
||||
|
||||
// Stack 是一个通用类型的栈结构
|
||||
type Stack[T any] struct {
|
||||
items []*T
|
||||
}
|
||||
|
||||
// Push 将元素压入栈顶
|
||||
func (s *Stack[T]) Push(item *T) {
|
||||
s.items = append(s.items, item)
|
||||
}
|
||||
|
||||
// Pop 弹出并返回栈顶元素,如果栈为空则返回错误
|
||||
func (s *Stack[T]) Pop() *T {
|
||||
if len(s.items) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
index := len(s.items) - 1
|
||||
item := s.items[index]
|
||||
s.items = s.items[:index]
|
||||
return item
|
||||
}
|
||||
|
||||
// Peek 返回栈顶元素但不移除,如果栈为空则返回错误
|
||||
func (s *Stack[T]) Peek() *T {
|
||||
if len(s.items) == 0 {
|
||||
return nil
|
||||
}
|
||||
return s.items[len(s.items)-1]
|
||||
}
|
||||
|
||||
// IsEmpty 检查栈是否为空
|
||||
func (s *Stack[T]) IsEmpty() bool {
|
||||
return len(s.items) == 0
|
||||
}
|
||||
|
||||
// Size 返回栈中元素的数量
|
||||
func (s *Stack[T]) Size() int {
|
||||
return len(s.items)
|
||||
}
|
||||
Reference in New Issue
Block a user