Files
origin/util/blueprint/exec.go
2025-10-28 11:11:36 +08:00

593 lines
12 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package blueprint
import "fmt"
type IBaseExecNode interface {
initInnerExecNode(innerNode *innerExecNode)
initExecNode(gr *Graph, en *execNode) error
GetPorts() ([]IPort, []IPort)
getExecNodeInfo() (*ExecContext, *execNode)
setExecNodeInfo(gr *ExecContext, en *execNode)
GetBlueprintModule() IBlueprintModule
}
type IInnerExecNode interface {
GetName() string
SetExec(exec IExecNode)
IsInPortExec(index int) bool
IsOutPortExec(index int) bool
GetInPortCount() int
GetOutPortCount() int
CloneInOutPort() ([]IPort, []IPort)
GetInPort(index int) IPort
GetOutPort(index int) IPort
GetOutPortParamStartIndex() int
}
type IExecNode interface {
GetName() string
DoNext(index int) error
Exec() (int, error) // 返回后续执行的Node的Index
GetNextExecLen() int
getInnerExecNode() IInnerExecNode
setVariableName(name string) bool
}
type innerExecNode struct {
Name string
Title string
Package string
Description string
inPort []IPort // 下标即为portId
outPort []IPort // 下标即为portId
outPortParamStartIndex int // 输出参数的起始索引,用于排除执行出口
IExecNode
}
type BaseExecNode struct {
*innerExecNode
// 执行时初始化的数据
*ExecContext
gr *Graph
execNode *execNode
}
type InputConfig struct {
Name string `json:"name"`
PortType string `json:"type"`
DataType string `json:"data_type"`
HasInput bool `json:"has_input"`
PinWidget string `json:"pin_widget"`
PortId int `json:"port_id"`
}
type OutputConfig struct {
Name string `json:"name"`
PortType string `json:"type"`
DataType string `json:"data_type"`
HasInput bool `json:"has_input"`
PortId int `json:"port_id"`
}
type BaseExecConfig struct {
Name string `json:"name"`
Title string `json:"title"`
Package string `json:"package"`
Description string `json:"description"`
IsPure bool `json:"is_pure"`
Inputs []InputConfig `json:"inputs"`
Outputs []OutputConfig `json:"outputs"`
}
func (bc *BaseExecConfig) GetMaxInPortId() int {
maxPortId := -1
for i := range bc.Inputs {
if bc.Inputs[i].PortId > maxPortId {
maxPortId = bc.Inputs[i].PortId
}
}
return maxPortId
}
func (bc *BaseExecConfig) GetMaxOutPortId() int {
maxPortId := -1
for i := range bc.Outputs {
if bc.Outputs[i].PortId > maxPortId {
maxPortId = bc.Outputs[i].PortId
}
}
return maxPortId
}
//func (em *innerExecNode) AppendInPort(port ...IPort) {
// 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.inPort = append(em.inPort, port[i])
// }
//}
func (em *innerExecNode) PrepareMaxInPortId(maxInPortId int) {
em.inPort = make([]IPort, 0, maxInPortId+1)
}
func (em *innerExecNode) PrepareMaxOutPortId(maxOutPortId int) {
em.outPort = make([]IPort, 0, maxOutPortId+1)
}
func (em *innerExecNode) SetInPortById(id int, port IPort) bool {
if id < 0 || id >= len(em.inPort) {
return false
}
em.inPort[id] = port
return true
}
func (em *innerExecNode) SetOutPortById(id int, port IPort) bool {
if id < 0 || id >= len(em.outPort) {
return false
}
em.outPort[id] = port
// 分析执行的
em.outPortParamStartIndex = -1
for i := range em.outPort {
if em.outPort[i] == nil {
continue
}
// 遇到非Exec结点即为输出参数开始位置
if !em.outPort[i].IsPortExec() {
em.outPortParamStartIndex = i
break
}
}
return true
}
func (em *innerExecNode) GetOutPortParamStartIndex() int {
return em.outPortParamStartIndex
}
func (em *innerExecNode) GetName() string {
return em.Name
}
func (em *innerExecNode) SetExec(exec IExecNode) {
em.IExecNode = exec
}
func (em *innerExecNode) CloneInOutPort() ([]IPort, []IPort) {
inPorts := make([]IPort, 0, 2)
for _, port := range em.inPort {
if port == nil {
inPorts = append(inPorts, nil)
}
if port.IsPortExec() {
// 执行入口, 不需要克隆,占位处理
inPorts = append(inPorts, nil)
continue
}
inPorts = append(inPorts, port.Clone())
}
outPorts := make([]IPort, 0, 2)
for _, port := range em.outPort {
if port == nil {
outPorts = append(outPorts, nil)
}
if port.IsPortExec() {
outPorts = append(outPorts, nil)
continue
}
outPorts = append(outPorts, port.Clone())
}
return inPorts, outPorts
}
func (em *innerExecNode) IsInPortExec(index int) bool {
if index >= len(em.inPort) || index < 0 {
return false
}
return em.inPort[index].IsPortExec()
}
func (em *innerExecNode) IsOutPortExec(index int) bool {
if index >= len(em.outPort) || index < 0 {
return false
}
return em.outPort[index].IsPortExec()
}
func (em *innerExecNode) GetInPortCount() int {
return len(em.inPort)
}
func (em *innerExecNode) GetOutPortCount() int {
return len(em.outPort)
}
func (em *innerExecNode) GetInPort(index int) IPort {
if index >= len(em.inPort) || index < 0 {
return nil
}
return em.inPort[index]
}
func (em *innerExecNode) GetOutPort(index int) IPort {
if index >= len(em.outPort) || index < 0 {
return nil
}
return em.outPort[index]
}
func (en *BaseExecNode) GetBluePrintModule() IBlueprintModule {
return en.gr.IBlueprintModule
}
func (en *BaseExecNode) initInnerExecNode(innerNode *innerExecNode) {
en.innerExecNode = innerNode
}
func (en *BaseExecNode) getExecNodeInfo() (*ExecContext, *execNode) {
return en.ExecContext, en.execNode
}
func (en *BaseExecNode) setExecNodeInfo(c *ExecContext, e *execNode) {
en.ExecContext = c
en.execNode = e
}
func (en *BaseExecNode) initExecNode(gr *Graph, node *execNode) error {
ctx, ok := gr.context[node.Id]
if !ok {
return fmt.Errorf("node %s not found", node.Id)
}
en.ExecContext = ctx
en.gr = gr
en.execNode = node
return nil
}
func (en *BaseExecNode) GetPorts() ([]IPort, []IPort) {
return en.InputPorts, en.OutputPorts
}
func (en *BaseExecNode) GetInPort(index int) IPort {
if en.InputPorts == nil {
return nil
}
if index >= len(en.InputPorts) || index < 0 {
return nil
}
return en.InputPorts[index]
}
func (en *BaseExecNode) GetOutPort(index int) IPort {
if en.OutputPorts == nil {
return nil
}
if index >= len(en.OutputPorts) || index < 0 {
return nil
}
return en.OutputPorts[index]
}
func (en *BaseExecNode) SetOutPort(index int, val IPort) bool {
if index >= len(en.OutputPorts) || index < 0 {
return false
}
en.OutputPorts[index].SetValue(val)
return true
}
func (en *BaseExecNode) GetInPortInt(index int) (Port_Int, bool) {
port := en.GetInPort(index)
if port == nil {
return 0, false
}
return port.GetInt()
}
func (en *BaseExecNode) GetInPortFloat(index int) (Port_Float, bool) {
port := en.GetInPort(index)
if port == nil {
return 0, false
}
return port.GetFloat()
}
func (en *BaseExecNode) GetInPortStr(index int) (Port_Str, bool) {
port := en.GetInPort(index)
if port == nil {
return "", false
}
return port.GetStr()
}
func (en *BaseExecNode) GetInPortArray(index int) (Port_Array, bool) {
port := en.GetInPort(index)
if port == nil {
return nil, false
}
return port.GetArray()
}
func (en *BaseExecNode) GetInPortArrayValInt(index int, idx int) (Port_Int, bool) {
port := en.GetInPort(index)
if port == nil {
return 0, false
}
return port.GetArrayValInt(idx)
}
func (en *BaseExecNode) GetInPortArrayValStr(idx int) (Port_Str, bool) {
port := en.GetInPort(idx)
if port == nil {
return "", false
}
return port.GetArrayValStr(idx)
}
func (en *BaseExecNode) GetInPortBool(index int) (Port_Bool, bool) {
port := en.GetInPort(index)
if port == nil {
return false, false
}
return port.GetBool()
}
func (en *BaseExecNode) GetOutPortInt(index int) (Port_Int, bool) {
port := en.GetOutPort(index)
if port == nil {
return 0, false
}
return port.GetInt()
}
func (en *BaseExecNode) GetOutPortFloat(index int) (Port_Float, bool) {
port := en.GetOutPort(index)
if port == nil {
return 0, false
}
return port.GetFloat()
}
func (en *BaseExecNode) GetOutPortStr(index int) (Port_Str, bool) {
port := en.GetOutPort(index)
if port == nil {
return "", false
}
return port.GetStr()
}
func (en *BaseExecNode) GetOutPortArrayValInt(index int, idx int) (Port_Int, bool) {
port := en.GetOutPort(index)
if port == nil {
return 0, false
}
return port.GetArrayValInt(idx)
}
func (en *BaseExecNode) GetOutPortArrayValStr(index int, idx int) (Port_Str, bool) {
port := en.GetOutPort(index)
if port == nil {
return "", false
}
return port.GetArrayValStr(idx)
}
func (en *BaseExecNode) GetOutPortBool(index int) (Port_Bool, bool) {
port := en.GetInPort(index)
if port == nil {
return false, false
}
return port.GetBool()
}
func (en *BaseExecNode) SetInPortInt(index int, val Port_Int) bool {
port := en.GetInPort(index)
if port == nil {
return false
}
return port.SetInt(val)
}
func (en *BaseExecNode) SetInPortFloat(index int, val Port_Float) bool {
port := en.GetInPort(index)
if port == nil {
return false
}
return port.SetFloat(val)
}
func (en *BaseExecNode) SetInPortStr(index int, val Port_Str) bool {
port := en.GetInPort(index)
if port == nil {
return false
}
return port.SetStr(val)
}
func (en *BaseExecNode) SetInBool(index int, val Port_Bool) bool {
port := en.GetInPort(index)
if port == nil {
return false
}
return port.SetBool(val)
}
func (en *BaseExecNode) SetInPortArrayValInt(index int, idx int, val Port_Int) bool {
port := en.GetInPort(index)
if port == nil {
return false
}
return port.SetArrayValInt(idx, val)
}
func (en *BaseExecNode) SetInPortArrayValStr(index int, idx int, val Port_Str) bool {
port := en.GetInPort(index)
if port == nil {
return false
}
return port.SetArrayValStr(idx, val)
}
func (en *BaseExecNode) AppendInPortArrayValInt(index int, val Port_Int) bool {
port := en.GetInPort(index)
if port == nil {
return false
}
return port.AppendArrayValInt(val)
}
func (en *BaseExecNode) AppendInPortArrayValStr(index int, val Port_Str) bool {
port := en.GetInPort(index)
if port == nil {
return false
}
return port.AppendArrayValStr(val)
}
func (en *BaseExecNode) GetInPortArrayLen(index int) Port_Int {
port := en.GetInPort(index)
if port == nil {
return 0
}
return port.GetArrayLen()
}
func (en *BaseExecNode) SetOutPortInt(index int, val Port_Int) bool {
port := en.GetOutPort(index)
if port == nil {
return false
}
return port.SetInt(val)
}
func (en *BaseExecNode) SetOutPortFloat(index int, val Port_Float) bool {
port := en.GetOutPort(index)
if port == nil {
return false
}
return port.SetFloat(val)
}
func (en *BaseExecNode) SetOutPortStr(index int, val Port_Str) bool {
port := en.GetOutPort(index)
if port == nil {
return false
}
return port.SetStr(val)
}
func (en *BaseExecNode) SetOutPortBool(index int, val Port_Bool) bool {
port := en.GetOutPort(index)
if port == nil {
return false
}
return port.SetBool(val)
}
func (en *BaseExecNode) SetOutPortArrayValInt(index int, idx int, val Port_Int) bool {
port := en.GetOutPort(index)
if port == nil {
return false
}
return port.SetArrayValInt(idx, val)
}
func (en *BaseExecNode) SetOutPortArrayValStr(index int, idx int, val Port_Str) bool {
port := en.GetOutPort(index)
if port == nil {
return false
}
return port.SetArrayValStr(idx, val)
}
func (en *BaseExecNode) AppendOutPortArrayValInt(index int, val Port_Int) bool {
port := en.GetOutPort(index)
if port == nil {
return false
}
return port.AppendArrayValInt(val)
}
func (en *BaseExecNode) AppendOutPortArrayValStr(index int, val Port_Str) bool {
port := en.GetOutPort(index)
if port == nil {
return false
}
return port.AppendArrayValStr(val)
}
func (en *BaseExecNode) GetOutPortArrayLen(index int) Port_Int {
port := en.GetOutPort(index)
if port == nil {
return 0
}
return port.GetArrayLen()
}
func (en *BaseExecNode) DoNext(index int) error {
// -1 表示中断运行
if index == -1 {
return nil
}
if index < 0 || index >= len(en.execNode.nextNode) {
return fmt.Errorf("next index %d not found", index)
}
if en.execNode.nextNode[index] == nil {
return nil
}
return en.execNode.nextNode[index].Do(en.gr)
}
func (en *BaseExecNode) GetNextExecLen() int {
return len(en.execNode.nextNode)
}
func (en *BaseExecNode) getInnerExecNode() IInnerExecNode {
return en.innerExecNode.IExecNode.(IInnerExecNode)
}
func (en *BaseExecNode) setVariableName(name string) bool {
return false
}
func (en *BaseExecNode) GetBlueprintModule() IBlueprintModule {
if en.gr == nil {
return nil
}
return en.gr.IBlueprintModule
}