新增变量与全局变量

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)
}
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 {
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
GetNextExecLen() int
getInnerExecNode() IInnerExecNode
setVariableName(name string) bool
}
type innerExecNode struct {
@@ -223,7 +225,7 @@ func (en *BaseExecNode) SetOutPort(index int, val IPort) bool {
if index >= len(en.OutputPorts) || index < 0 {
return false
}
en.OutputPorts[index] = val
en.OutputPorts[index].SetValue(val)
return true
}
@@ -488,3 +490,7 @@ func (en *BaseExecNode) GetNextExecLen() int {
func (en *BaseExecNode) getInnerExecNode() 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
}
if err = em.regSetVariables(Config_DataType_Int); err != nil {
return err
}
if err = em.regSetVariables(Config_DataType_Integer); err != nil {
return err
}
@@ -304,11 +307,13 @@ func (em *ExecPool) regSetVariables(typ string) error {
var baseExec innerExecNode
baseExec.Name = genSetVariablesNodeName(typ)
inExecPort := NewPortByType(Config_PortType_Exec)
inPort := NewPortByType(typ)
outExecPort := NewPortByType(Config_PortType_Exec)
outPort := NewPortByType(typ)
baseExec.AppendInPort(inPort)
baseExec.AppendOutPort(outPort)
baseExec.AppendInPort(inExecPort, inPort)
baseExec.AppendOutPort(outExecPort, outPort)
baseExec.IExecNode = &SetVariablesNode{nodeName: baseExec.GetName()}
if !em.loadBaseExec(&baseExec) {

View File

@@ -1,6 +1,9 @@
package blueprint
import "fmt"
import (
"fmt"
"github.com/goccy/go-json"
)
type IGraph interface {
Do(entranceID int64, args ...any) error
@@ -38,10 +41,48 @@ type edgeConfig struct {
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 {
Name string `json:"name"`
Type string `json:"type"`
Value string `json:"value"`
Name string `json:"name"`
Type string `json:"type"`
Value MultiTypeValue `json:"value"`
}
type graphConfig struct {

View File

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

View File

@@ -1,9 +1,13 @@
package blueprint
import "fmt"
import (
"fmt"
"strings"
)
const GetVariables = "GetVar"
const SetVariables = "SetVar"
const globalVariablesPrefix = "g_"
type GetVariablesNode struct {
BaseExecNode
@@ -22,7 +26,13 @@ func (g *GetVariablesNode) GetName() string {
}
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 {
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
}
func (g *GetVariablesNode) setVariableName(name string) bool {
g.varName = name
return true
}
func (g *SetVariablesNode) GetName() string {
return g.nodeName
}
func (g *SetVariablesNode) Exec() (int, error) {
port := g.GetInPort(0)
port := g.GetInPort(1)
if port == nil {
return -1, fmt.Errorf("get in port failed,node name %s", g.nodeName)
}
g.gr.variables[g.varName] = port
if !g.SetOutPort(0, port) {
varPort := port.Clone()
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 0, nil
}
func (g *SetVariablesNode) setVariableName(name string) bool {
g.varName = name
return true
}