Skip to content

Commit 7070d83

Browse files
committed
Build one main workflow runtime tree
Currently this builds one tree which is an amalgamation of all the frames. It uses a recursive algorithm to fill in missing children nodes after each renderpass has been parsed
1 parent 7285e68 commit 7070d83

File tree

4 files changed

+41
-7
lines changed

4 files changed

+41
-7
lines changed

workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/App.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public fun App(
7272
selectedTraceFile = it
7373
selectedNode = null
7474
frameIndex = 0
75+
workflowFrames = emptyList()
7576
},
7677
modifier = Modifier.align(Alignment.BottomStart)
7778
)

workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/model/Node.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@ public class Node(
1717
val renderings: Any? = null,
1818
val children: List<Node>,
1919
) {
20+
2021
override fun toString(): String {
21-
return "Node(name='$name', parent='$parent', children=${children.size})"
22+
return "Node(name='$name', parent='$parent', children=${children})"
2223
}
2324

2425
override fun equals(other: Any?): Boolean {
2526
if (this === other) return true
2627
if (other !is Node) return false
2728
return this.id == other.id
2829
}
30+
2931
override fun hashCode(): Int {
3032
return id.hashCode()
3133
}

workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/ui/WorkflowTree.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public fun RenderDiagram(
3939
var frames by remember { mutableStateOf<List<Node>>(emptyList()) }
4040
var isLoading by remember(traceFile) { mutableStateOf(true) }
4141
var error by remember(traceFile) { mutableStateOf<Throwable?>(null) }
42+
var mainTree by remember { mutableStateOf<Node?>(null) }
4243

4344
LaunchedEffect(traceFile) {
4445
val parseResult = parseTrace(traceFile)
@@ -50,6 +51,7 @@ public fun RenderDiagram(
5051
is ParseResult.Success -> {
5152
val parsedFrames = parseResult.trace ?: emptyList()
5253
frames = parsedFrames
54+
mainTree = parseResult.mainTree
5355
onFileParse(parsedFrames)
5456
isLoading = false
5557
}
@@ -62,7 +64,8 @@ public fun RenderDiagram(
6264
}
6365

6466
if (!isLoading) {
65-
DrawTree(frames[frameInd], onNodeSelect)
67+
// DrawTree(frames[frameInd], onNodeSelect)
68+
DrawTree(mainTree!!, onNodeSelect)
6669
}
6770
}
6871

workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/util/JsonParser.kt

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,23 @@ public suspend fun parseTrace(
2929
val workflowAdapter = createMoshiAdapter()
3030
val parsedRenderPasses = workflowAdapter.fromJson(jsonString)
3131

32-
val parsedFrames = mutableListOf<Node>()
32+
var mainWorkflowTree: Node? = null
33+
val parsedFrame = mutableListOf<Node>()
3334
parsedRenderPasses?.forEach { renderPass ->
3435
val parsed = getFrameFromRenderPass(renderPass)
35-
parsedFrames.add(parsed)
36+
if (mainWorkflowTree == null) {
37+
mainWorkflowTree = parsed
38+
} else {
39+
mergeFrameIntoMainTree(parsed, mainWorkflowTree!!)
40+
}
41+
parsedFrame.add(parsed)
3642
}
37-
38-
ParseResult.Success(parsedFrames)
43+
/*
44+
this parsing method can never be called without a provided file, so we can assume that there
45+
will always be at least one render pass in the trace. If not, then Moshi would catch any
46+
malformed JSON and throw an error beforehand.
47+
*/
48+
ParseResult.Success(parsedFrame, mainWorkflowTree!!)
3949
} catch (e: Exception) {
4050
ParseResult.Failure(e)
4151
}
@@ -83,7 +93,25 @@ private fun buildTree(node: Node, childrenByParent: Map<String, List<Node>>): No
8393
)
8494
}
8595

96+
/**
97+
* Every new frame starts with the same roots as the main tree, so we can do a simple traversal to
98+
* add any missing child nodes from the frame.
99+
*/
100+
private fun mergeFrameIntoMainTree(
101+
frame: Node,
102+
main: Node
103+
) {
104+
val children = frame.children
105+
children.forEach { child ->
106+
if (child in main.children) {
107+
mergeFrameIntoMainTree(child, main.children.find { it.id == child.id }!!)
108+
} else {
109+
main.children.add(child)
110+
}
111+
}
112+
}
113+
86114
sealed interface ParseResult {
87-
class Success(val trace: List<Node>?) : ParseResult
115+
class Success(val trace: List<Node>?, val mainTree: Node) : ParseResult
88116
class Failure(val error: Throwable) : ParseResult
89117
}

0 commit comments

Comments
 (0)