Improved all axpect of tracing / forcing arrays
Improved ui and tree export
This commit is contained in:
@@ -347,9 +347,11 @@ func (m *MarteClient) handleJSONResponse(tag, data string) {
|
||||
return
|
||||
|
||||
case "TREE":
|
||||
// Parse server-side and stream pre-digested flat-node batches to the
|
||||
// browser so it never has to JSON.parse a multi-MB string.
|
||||
go m.sendTreeBatches(data)
|
||||
// Per-node response — forward to browser as-is.
|
||||
broadcast(m.hub, map[string]any{
|
||||
"type": "tree_node",
|
||||
"data": data,
|
||||
})
|
||||
return
|
||||
}
|
||||
broadcast(m.hub, map[string]any{
|
||||
@@ -359,90 +361,6 @@ func (m *MarteClient) handleJSONResponse(tag, data string) {
|
||||
})
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// TREE streaming
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// TreeNode mirrors the DebugService TREE JSON structure.
|
||||
type TreeNode struct {
|
||||
Name string `json:"Name"`
|
||||
Class string `json:"Class"`
|
||||
IsTraceable bool `json:"IsTraceable"`
|
||||
IsForcable bool `json:"IsForcable"`
|
||||
Elements uint32 `json:"Elements"`
|
||||
Children []*TreeNode `json:"Children"`
|
||||
}
|
||||
|
||||
// FlatNode is a pre-digested, compact representation sent to the browser.
|
||||
type FlatNode struct {
|
||||
Path string `json:"p"`
|
||||
Name string `json:"n"`
|
||||
Class string `json:"c"`
|
||||
Parent string `json:"par"`
|
||||
Tr bool `json:"tr,omitempty"`
|
||||
Fo bool `json:"fo,omitempty"`
|
||||
El uint32 `json:"el,omitempty"`
|
||||
HasCh bool `json:"ch,omitempty"`
|
||||
}
|
||||
|
||||
func flattenTree(node *TreeNode, parentPath string, out *[]FlatNode) {
|
||||
path := node.Name
|
||||
if parentPath != "" {
|
||||
path = parentPath + "." + node.Name
|
||||
}
|
||||
hasCh := len(node.Children) > 0
|
||||
*out = append(*out, FlatNode{
|
||||
Path: path,
|
||||
Name: node.Name,
|
||||
Class: node.Class,
|
||||
Parent: parentPath,
|
||||
Tr: node.IsTraceable,
|
||||
Fo: node.IsForcable,
|
||||
El: node.Elements,
|
||||
HasCh: hasCh,
|
||||
})
|
||||
for _, c := range node.Children {
|
||||
flattenTree(c, path, out)
|
||||
}
|
||||
}
|
||||
|
||||
// sendTreeBatches parses the raw TREE JSON and streams compact FlatNode
|
||||
// batches to all browsers. Each browser processes one batch per animation
|
||||
// frame, keeping the UI responsive during large tree loads.
|
||||
func (m *MarteClient) sendTreeBatches(raw string) {
|
||||
var root TreeNode
|
||||
if err := json.Unmarshal([]byte(raw), &root); err != nil {
|
||||
log.Printf("[TREE] parse error: %v — falling back to raw JSON", err)
|
||||
broadcast(m.hub, map[string]any{"type": "response", "tag": "TREE", "data": raw})
|
||||
return
|
||||
}
|
||||
|
||||
var nodes []FlatNode
|
||||
if root.Name == "Root" && len(root.Children) > 0 {
|
||||
for _, c := range root.Children {
|
||||
flattenTree(c, "", &nodes)
|
||||
}
|
||||
} else {
|
||||
flattenTree(&root, "", &nodes)
|
||||
}
|
||||
|
||||
total := len(nodes)
|
||||
log.Printf("[TREE] streaming %d flat nodes to browser", total)
|
||||
broadcast(m.hub, map[string]any{"type": "tree_clear", "total": total})
|
||||
|
||||
const batchSize = 50
|
||||
for i := 0; i < total; i += batchSize {
|
||||
end := i + batchSize
|
||||
if end > total {
|
||||
end = total
|
||||
}
|
||||
broadcast(m.hub, map[string]any{
|
||||
"type": "tree_batch",
|
||||
"nodes": nodes[i:end],
|
||||
"done": end == total,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MarteClient) handleTextLine(line string) {
|
||||
if strings.HasPrefix(line, "OK SERVICE_INFO") {
|
||||
|
||||
Reference in New Issue
Block a user