新增变量与全局变量

This commit is contained in:
boyce
2025-09-24 10:26:19 +08:00
parent 2a12d40f7a
commit be0078015f
7 changed files with 122 additions and 27 deletions

View File

@@ -53,12 +53,18 @@ func TestExecMgr(t *testing.T) {
t.Fatalf("init failed,err:%v", err) t.Fatalf("init failed,err:%v", err)
} }
graph := bp.Create("test1") graphTest2 := bp.Create("test2")
err = graph.Do(EntranceID_IntParam, 1, 2, 3) err = graphTest2.Do(EntranceID_IntParam, 1, 2, 3)
if err != nil { if err != nil {
t.Fatalf("do failed,err:%v", err) t.Fatalf("Do EntranceID_IntParam failed,err:%v", err)
} }
graph.Release() //graph := bp.Create("test1")
//err = graph.Do(EntranceID_IntParam, 1, 2, 3)
//if err != nil {
// t.Fatalf("do failed,err:%v", err)
//}
//graph.Release()
} }

View File

@@ -29,6 +29,8 @@ type IExecNode interface {
Exec() (int, error) // 返回后续执行的Node的Index Exec() (int, error) // 返回后续执行的Node的Index
GetNextExecLen() int GetNextExecLen() int
getInnerExecNode() IInnerExecNode getInnerExecNode() IInnerExecNode
setVariableName(name string) bool
} }
type innerExecNode struct { type innerExecNode struct {
@@ -223,7 +225,7 @@ func (en *BaseExecNode) SetOutPort(index int, val IPort) bool {
if index >= len(en.OutputPorts) || index < 0 { if index >= len(en.OutputPorts) || index < 0 {
return false return false
} }
en.OutputPorts[index] = val en.OutputPorts[index].SetValue(val)
return true return true
} }
@@ -488,3 +490,7 @@ func (en *BaseExecNode) GetNextExecLen() int {
func (en *BaseExecNode) getInnerExecNode() IInnerExecNode { func (en *BaseExecNode) getInnerExecNode() IInnerExecNode {
return en.innerExecNode.IExecNode.(IInnerExecNode) return en.innerExecNode.IExecNode.(IInnerExecNode)
} }
func (en *BaseExecNode) setVariableName(name string) bool {
return false
}

View File

@@ -248,6 +248,9 @@ func (em *ExecPool) loadSysExec() error {
return err return err
} }
if err = em.regSetVariables(Config_DataType_Int); err != nil {
return err
}
if err = em.regSetVariables(Config_DataType_Integer); err != nil { if err = em.regSetVariables(Config_DataType_Integer); err != nil {
return err return err
} }
@@ -304,11 +307,13 @@ func (em *ExecPool) regSetVariables(typ string) error {
var baseExec innerExecNode var baseExec innerExecNode
baseExec.Name = genSetVariablesNodeName(typ) baseExec.Name = genSetVariablesNodeName(typ)
inExecPort := NewPortByType(Config_PortType_Exec)
inPort := NewPortByType(typ) inPort := NewPortByType(typ)
outExecPort := NewPortByType(Config_PortType_Exec)
outPort := NewPortByType(typ) outPort := NewPortByType(typ)
baseExec.AppendInPort(inPort) baseExec.AppendInPort(inExecPort, inPort)
baseExec.AppendOutPort(outPort) baseExec.AppendOutPort(outExecPort, outPort)
baseExec.IExecNode = &SetVariablesNode{nodeName: baseExec.GetName()} baseExec.IExecNode = &SetVariablesNode{nodeName: baseExec.GetName()}
if !em.loadBaseExec(&baseExec) { if !em.loadBaseExec(&baseExec) {

View File

@@ -1,6 +1,9 @@
package blueprint package blueprint
import "fmt" import (
"fmt"
"github.com/goccy/go-json"
)
type IGraph interface { type IGraph interface {
Do(entranceID int64, args ...any) error Do(entranceID int64, args ...any) error
@@ -38,10 +41,48 @@ type edgeConfig struct {
DesPortIndex int `json:"des_port_index"` DesPortIndex int `json:"des_port_index"`
} }
type MultiTypeValue struct {
Value interface{}
}
// 实现json.Unmarshaler接口自定义解码逻辑
func (v *MultiTypeValue) UnmarshalJSON(data []byte) error {
// 尝试将数据解析为字符串
var strVal string
if err := json.Unmarshal(data, &strVal); err == nil {
v.Value = strVal
return nil
}
// 如果不是字符串,尝试解析为数字
var intVal int
if err := json.Unmarshal(data, &intVal); err == nil {
v.Value = intVal
return nil
}
// 如果不是字符串,尝试解析为数字
var boolVal bool
if err := json.Unmarshal(data, &boolVal); err == nil {
v.Value = boolVal
return nil
}
// 如果不是字符串,尝试解析为数字
var float64Val float64
if err := json.Unmarshal(data, &float64Val); err == nil {
v.Value = float64Val
return nil
}
// 如果都失败,返回错误
return fmt.Errorf("cannot unmarshal JSON value: %s", string(data))
}
type variablesConfig struct { type variablesConfig struct {
Name string `json:"name"` Name string `json:"name"`
Type string `json:"type"` Type string `json:"type"`
Value string `json:"value"` Value MultiTypeValue `json:"value"`
} }
type graphConfig struct { type graphConfig struct {

View File

@@ -54,7 +54,7 @@ func (gp *GraphPool) Create(graphName string) IGraph {
if !ok { if !ok {
return nil return nil
} }
var graph Graph var graph Graph
graph.baseGraph = gr graph.baseGraph = gr
graph.context = make(map[string]*ExecContext, 4) graph.context = make(map[string]*ExecContext, 4)
@@ -105,26 +105,26 @@ func (gp *GraphPool) prepareGraph(graphName string, graphConfig *graphConfig) er
return nil return nil
} }
func (gp *GraphPool) getVarExec(nodeCfg *nodeConfig, graphConfig *graphConfig) (IInnerExecNode, string) { func (gp *GraphPool) genVarExec(nodeCfg *nodeConfig, graphConfig *graphConfig) (IInnerExecNode, string) {
// 是否为Get_或Set_开头 // 是否为Get_或Set_开头
if strings.HasPrefix(nodeCfg.Class, "Get_") || strings.HasPrefix(nodeCfg.Class, "Set_") { if !strings.HasPrefix(nodeCfg.Class, "Get_") && !strings.HasPrefix(nodeCfg.Class, "Set_") {
return gp.execPool.GetExec(nodeCfg.Class), "" return gp.execPool.GetExec(nodeCfg.Class), ""
} }
// 获取Get_或Set_结尾字符串 // 获取Get_或Set_结尾字符串
var nodeName string var nodeName string
var varName string var varName string
if strings.HasSuffix(nodeCfg.Class, "Get_") { if strings.HasPrefix(nodeCfg.Class, "Get_") {
var typ string var typ string
varName = strings.TrimSuffix(nodeCfg.Class, "Get_") varName = strings.TrimPrefix(nodeCfg.Class, "Get_")
varCfg := graphConfig.GetVariablesByName(varName) varCfg := graphConfig.GetVariablesByName(varName)
if varCfg != nil { if varCfg != nil {
typ = varCfg.Type typ = varCfg.Type
} }
nodeName = genGetVariablesNodeName(typ) nodeName = genGetVariablesNodeName(typ)
} else if strings.HasSuffix(nodeCfg.Class, "Set_") { } else if strings.HasPrefix(nodeCfg.Class, "Set_") {
var typ string var typ string
varName = strings.TrimSuffix(nodeCfg.Class, "Set_") varName = strings.TrimPrefix(nodeCfg.Class, "Set_")
varCfg := graphConfig.GetVariablesByName(varName) varCfg := graphConfig.GetVariablesByName(varName)
if varCfg != nil { if varCfg != nil {
typ = varCfg.Type typ = varCfg.Type
@@ -132,7 +132,10 @@ func (gp *GraphPool) getVarExec(nodeCfg *nodeConfig, graphConfig *graphConfig) (
nodeName = genSetVariablesNodeName(typ) nodeName = genSetVariablesNodeName(typ)
} }
return gp.execPool.GetExec(nodeName), varName e := gp.execPool.GetExec(nodeName)
e.(IExecNode).setVariableName(varName)
return e, varName
} }
func (gp *GraphPool) genAllNode(graphConfig *graphConfig) (map[string]*execNode, error) { func (gp *GraphPool) genAllNode(graphConfig *graphConfig) (map[string]*execNode, error) {
@@ -147,7 +150,7 @@ func (gp *GraphPool) genAllNode(graphConfig *graphConfig) (map[string]*execNode,
// 获取不到node则获取变量node // 获取不到node则获取变量node
exec := gp.execPool.GetExec(className) exec := gp.execPool.GetExec(className)
if exec == nil { if exec == nil {
exec, varName = gp.getVarExec(&node, graphConfig) exec, varName = gp.genVarExec(&node, graphConfig)
if exec == nil { if exec == nil {
return nil, fmt.Errorf("%s node has not been registered", node.Class) return nil, fmt.Errorf("%s node has not been registered", node.Class)
} }

View File

@@ -67,6 +67,14 @@ func (en *execNode) doSetInPort(gr *Graph, index int, inPort IPort) error {
return nil return nil
} }
if _, ok := gr.context[preNode.node.Id]; !ok {
// 如果前一个结点没有执行过,则递归执行前一个结点
err := preNode.node.Do(gr, nil)
if err != nil {
return err
}
}
// 判断上一个结点是否已经执行过 // 判断上一个结点是否已经执行过
if _, ok := gr.context[preNode.node.Id]; ok { if _, ok := gr.context[preNode.node.Id]; ok {
outPort := gr.GetNodeOutPortValue(preNode.node.Id, preNode.outPortIndex) outPort := gr.GetNodeOutPortValue(preNode.node.Id, preNode.outPortIndex)
@@ -78,8 +86,7 @@ func (en *execNode) doSetInPort(gr *Graph, index int, inPort IPort) error {
return nil return nil
} }
// 如果前一个结点没有执行过,则递归执行前一个结点 return fmt.Errorf("pre node %s not exec", preNode.node.Id)
return preNode.node.Do(gr, nil)
} }
func (en *execNode) Do(gr *Graph, outPortArgs ...any) error { func (en *execNode) Do(gr *Graph, outPortArgs ...any) error {

View File

@@ -1,9 +1,13 @@
package blueprint package blueprint
import "fmt" import (
"fmt"
"strings"
)
const GetVariables = "GetVar" const GetVariables = "GetVar"
const SetVariables = "SetVar" const SetVariables = "SetVar"
const globalVariablesPrefix = "g_"
type GetVariablesNode struct { type GetVariablesNode struct {
BaseExecNode BaseExecNode
@@ -22,7 +26,13 @@ func (g *GetVariablesNode) GetName() string {
} }
func (g *GetVariablesNode) Exec() (int, error) { func (g *GetVariablesNode) Exec() (int, error) {
port := g.gr.variables[g.varName] var port IPort
if strings.HasPrefix(g.varName, globalVariablesPrefix) {
port = g.gr.globalVariables[g.varName]
} else {
port = g.gr.variables[g.varName]
}
if port == nil { if port == nil {
return -1, fmt.Errorf("variable %s not found,node name %s", g.varName, g.nodeName) return -1, fmt.Errorf("variable %s not found,node name %s", g.varName, g.nodeName)
} }
@@ -34,20 +44,37 @@ func (g *GetVariablesNode) Exec() (int, error) {
return 0, nil return 0, nil
} }
func (g *GetVariablesNode) setVariableName(name string) bool {
g.varName = name
return true
}
func (g *SetVariablesNode) GetName() string { func (g *SetVariablesNode) GetName() string {
return g.nodeName return g.nodeName
} }
func (g *SetVariablesNode) Exec() (int, error) { func (g *SetVariablesNode) Exec() (int, error) {
port := g.GetInPort(0) port := g.GetInPort(1)
if port == nil { if port == nil {
return -1, fmt.Errorf("get in port failed,node name %s", g.nodeName) return -1, fmt.Errorf("get in port failed,node name %s", g.nodeName)
} }
g.gr.variables[g.varName] = port varPort := port.Clone()
if !g.SetOutPort(0, port) { varPort.SetValue(port)
if strings.HasPrefix(g.varName, globalVariablesPrefix) {
g.gr.globalVariables[g.varName] = varPort
} else {
g.gr.variables[g.varName] = varPort
}
if !g.SetOutPort(1, varPort) {
return -1, fmt.Errorf("set out port failed,node name %s", g.nodeName) return -1, fmt.Errorf("set out port failed,node name %s", g.nodeName)
} }
return 0, nil return 0, nil
} }
func (g *SetVariablesNode) setVariableName(name string) bool {
g.varName = name
return true
}