From be0078015f871f23fdb4f958c7e699684b924e63 Mon Sep 17 00:00:00 2001 From: boyce <6549168@qq.com> Date: Wed, 24 Sep 2025 10:26:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8F=98=E9=87=8F=E4=B8=8E?= =?UTF-8?q?=E5=85=A8=E5=B1=80=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- util/blueprint/blueprint_test.go | 14 ++++++--- util/blueprint/exec.go | 8 +++++- util/blueprint/execpool.go | 9 ++++-- util/blueprint/graph.go | 49 +++++++++++++++++++++++++++++--- util/blueprint/graphpool.go | 21 ++++++++------ util/blueprint/node.go | 11 +++++-- util/blueprint/variables.go | 37 ++++++++++++++++++++---- 7 files changed, 122 insertions(+), 27 deletions(-) diff --git a/util/blueprint/blueprint_test.go b/util/blueprint/blueprint_test.go index 88c87bc..4447675 100644 --- a/util/blueprint/blueprint_test.go +++ b/util/blueprint/blueprint_test.go @@ -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() } diff --git a/util/blueprint/exec.go b/util/blueprint/exec.go index 2637fca..761a1a8 100644 --- a/util/blueprint/exec.go +++ b/util/blueprint/exec.go @@ -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 +} diff --git a/util/blueprint/execpool.go b/util/blueprint/execpool.go index 8466f22..6ba063f 100644 --- a/util/blueprint/execpool.go +++ b/util/blueprint/execpool.go @@ -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) { diff --git a/util/blueprint/graph.go b/util/blueprint/graph.go index 5333193..83b58aa 100644 --- a/util/blueprint/graph.go +++ b/util/blueprint/graph.go @@ -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 { diff --git a/util/blueprint/graphpool.go b/util/blueprint/graphpool.go index 8d4124d..fbe2178 100644 --- a/util/blueprint/graphpool.go +++ b/util/blueprint/graphpool.go @@ -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) } diff --git a/util/blueprint/node.go b/util/blueprint/node.go index 9d08a79..72f6800 100644 --- a/util/blueprint/node.go +++ b/util/blueprint/node.go @@ -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 { diff --git a/util/blueprint/variables.go b/util/blueprint/variables.go index dd7915b..0df672a 100644 --- a/util/blueprint/variables.go +++ b/util/blueprint/variables.go @@ -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 +}