@@ -9,7 +9,8 @@ import io.github.vinceglb.filekit.PlatformFile
9
9
import io.github.vinceglb.filekit.readString
10
10
11
11
/* *
12
- * Parses a given file's JSON String into [Node] with Moshi adapters.
12
+ * Parses a given file's JSON String into a list of [Node]s with Moshi adapters. Each of these nodes
13
+ * count as the root of a tree which forms a Frame.
13
14
*
14
15
* @return A [ParseResult] representing result of parsing, either an error related to the
15
16
* format of the JSON, or a success and a parsed trace.
@@ -19,18 +20,58 @@ public suspend fun parseTrace(
19
20
): ParseResult {
20
21
return try {
21
22
val jsonString = file.readString()
22
- val moshi = Moshi .Builder ()
23
- .add(KotlinJsonAdapterFactory ())
24
- .build()
25
- val workflowList = Types .newParameterizedType(List ::class .java, Node ::class .java)
26
- val workflowAdapter: JsonAdapter <List <Node >> = moshi.adapter(workflowList)
27
- val trace = workflowAdapter.fromJson(jsonString)
28
- ParseResult .Success (trace)
23
+ val workflowAdapter = createMoshiAdapter()
24
+ val unParsedTrace = workflowAdapter.fromJson(jsonString)
25
+
26
+ val parsedTrace = mutableListOf<Node >()
27
+ unParsedTrace?.forEach { renderPass ->
28
+ val parsed = getFrameFromRenderPass(renderPass)
29
+ parsedTrace.add(parsed)
30
+ }
31
+
32
+ ParseResult .Success (parsedTrace)
29
33
} catch (e: Exception ) {
30
34
ParseResult .Failure (e)
31
35
}
32
36
}
33
37
38
+ /* *
39
+ * Creates a Moshi adapter for parsing the JSON trace file.
40
+ */
41
+ private fun createMoshiAdapter (): JsonAdapter <List <List <Node >>> {
42
+ val moshi = Moshi .Builder ()
43
+ .add(KotlinJsonAdapterFactory ())
44
+ .build()
45
+ val workflowList = Types .newParameterizedType(List ::class .java,
46
+ Types .newParameterizedType(List ::class .java, Node ::class .java))
47
+ val adapter: JsonAdapter <List <List <Node >>> = moshi.adapter(workflowList)
48
+ return adapter
49
+ }
50
+
51
+ /* *
52
+ * We take an unparsed render pass and build up a tree structure from it to form a Frame.
53
+ */
54
+ private fun getFrameFromRenderPass (renderPass : List <Node >): Node {
55
+ val childrenByParent = renderPass.groupBy { it.parent }
56
+ val root = childrenByParent[" root" ]?.single()
57
+ return buildTree(root!! , childrenByParent)
58
+ }
59
+
60
+ /* *
61
+ * Recursively builds a tree using each node's children.
62
+ */
63
+ private fun buildTree (node : Node , childrenByParent : Map <String , List <Node >>): Node {
64
+ val children = (childrenByParent[node.name] ? : emptyList())
65
+ return Node (
66
+ name = node.name,
67
+ parent = node.parent,
68
+ props = node.props,
69
+ state = node.state,
70
+ children = children.map { buildTree(it, childrenByParent) },
71
+ id = node.id
72
+ )
73
+ }
74
+
34
75
sealed interface ParseResult {
35
76
class Success (val trace : List <Node >? ) : ParseResult
36
77
class Failure (val error : Throwable ) : ParseResult
0 commit comments