controllogic: debug value is Value (array-capable); lua get narrows to scalar
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -12,11 +12,11 @@ import (
|
||||
// only meaningful when HasValue is true (e.g. an action.write's written value or
|
||||
// a flow.if branch as 0/1); otherwise the event just marks the node as active.
|
||||
type DebugEvent struct {
|
||||
GraphID string `json:"graphId"`
|
||||
NodeID string `json:"nodeId"`
|
||||
Value float64 `json:"value"`
|
||||
HasValue bool `json:"hasValue"`
|
||||
TS int64 `json:"ts"` // unix millis
|
||||
GraphID string `json:"graphId"`
|
||||
NodeID string `json:"nodeId"`
|
||||
Value any `json:"value"`
|
||||
HasValue bool `json:"hasValue"`
|
||||
TS int64 `json:"ts"` // unix millis
|
||||
}
|
||||
|
||||
// DebugObserver receives node-execution events from running (and simulated)
|
||||
@@ -83,7 +83,7 @@ func (e *Engine) FireTrigger(graphID, triggerID string) bool {
|
||||
|
||||
// emitDebug reports a node execution to the observer when the graph is watched
|
||||
// (or the graph is a simulate sandbox, which is always its own subscriber).
|
||||
func (cg *compiledGraph) emitDebug(nodeID string, value float64, hasValue bool) {
|
||||
func (cg *compiledGraph) emitDebug(nodeID string, value Value, hasValue bool) {
|
||||
if !cg.alwaysDebug {
|
||||
w, _ := cg.engine.debugWatch.Load().(map[string]bool)
|
||||
if !w[cg.id] {
|
||||
|
||||
@@ -79,7 +79,7 @@ func TestDebugObserverCapturesNodeValues(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatal("no event for write node 'w'")
|
||||
}
|
||||
if !wEv.HasValue || wEv.Value != 42 {
|
||||
if !wEv.HasValue || wEv.Value != 42.0 {
|
||||
t.Errorf("write node event = %+v, want value 42 hasValue true", wEv)
|
||||
}
|
||||
if wEv.GraphID != "g1" {
|
||||
@@ -136,7 +136,7 @@ func TestFireTriggerForcesRun(t *testing.T) {
|
||||
}
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
if !wEv.HasValue || wEv.Value != 42 {
|
||||
if !wEv.HasValue || wEv.Value != 42.0 {
|
||||
t.Errorf("write node event = %+v, want value 42 hasValue true", wEv)
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ func TestSimulateSuppressesWrites(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatal("simulate produced no event for write node 'w'")
|
||||
}
|
||||
if !wEv.HasValue || wEv.Value != 42 {
|
||||
if !wEv.HasValue || wEv.Value != 42.0 {
|
||||
t.Errorf("simulate write event = %+v, want value 42 hasValue true", wEv)
|
||||
}
|
||||
if wEv.GraphID != "sim" {
|
||||
|
||||
@@ -1053,11 +1053,7 @@ func (cg *compiledGraph) run(nodeID string, ctx *runCtx) {
|
||||
|
||||
case "action.write":
|
||||
val := EvalValue(node.param("expr"), ctx.resolve)
|
||||
f, isNum := val.(float64)
|
||||
if !isNum {
|
||||
f = math.NaN()
|
||||
}
|
||||
cg.emitDebug(node.ID, f, true)
|
||||
cg.emitDebug(node.ID, val, true)
|
||||
cg.engine.write(cg, node.param("target"), val)
|
||||
cg.follow(node.ID, "out", ctx)
|
||||
|
||||
|
||||
@@ -110,3 +110,11 @@ func TestResolverReturnsLocalValue(t *testing.T) {
|
||||
t.Fatalf("sum(buf) = %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmitDebugAcceptsArray(t *testing.T) {
|
||||
g := Graph{ID: "g", Name: "n"}
|
||||
cg := compile(g)
|
||||
cg.engine = &Engine{} // no observer installed; emitDebug must not panic
|
||||
cg.emitDebug("x", []Value{1.0, 2.0}, true)
|
||||
cg.emitDebug("x", 3.0, true)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package controllogic
|
||||
|
||||
import (
|
||||
"math"
|
||||
"sync"
|
||||
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
@@ -60,9 +61,9 @@ func (lr *luaRuntime) ensure() error {
|
||||
L.SetGlobal("get", L.NewFunction(func(s *lua.LState) int {
|
||||
target := s.CheckString(1)
|
||||
ds, name, ok := parseRef(target)
|
||||
var v float64
|
||||
if ok && lr.curResolve != nil { // shim: Task 6 finalizes lua Value handling
|
||||
if f, fok := lr.curResolve(ds, name).(float64); fok {
|
||||
v := math.NaN()
|
||||
if ok && lr.curResolve != nil {
|
||||
if f, isNum := lr.curResolve(ds, name).(float64); isNum {
|
||||
v = f
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,12 +55,12 @@ func NewDebugHub(engine *controllogic.Engine, log *slog.Logger) *DebugHub {
|
||||
|
||||
// debugOut is the client-bound JSON form of a node-execution event.
|
||||
type debugOut struct {
|
||||
Type string `json:"type"` // always "debugNode"
|
||||
GraphID string `json:"graphId"`
|
||||
NodeID string `json:"nodeId"`
|
||||
Value float64 `json:"value"`
|
||||
HasValue bool `json:"hasValue"`
|
||||
TS int64 `json:"ts"`
|
||||
Type string `json:"type"` // always "debugNode"
|
||||
GraphID string `json:"graphId"`
|
||||
NodeID string `json:"nodeId"`
|
||||
Value any `json:"value"`
|
||||
HasValue bool `json:"hasValue"`
|
||||
TS int64 `json:"ts"`
|
||||
}
|
||||
|
||||
// Observe implements controllogic.DebugObserver: push the event to every client
|
||||
|
||||
Reference in New Issue
Block a user