@@ -11,12 +11,6 @@ import androidx.compose.foundation.layout.padding
11
11
import androidx.compose.material.Text
12
12
import androidx.compose.runtime.Composable
13
13
import androidx.compose.runtime.LaunchedEffect
14
- import androidx.compose.runtime.getValue
15
- import androidx.compose.runtime.mutableStateListOf
16
- import androidx.compose.runtime.mutableStateMapOf
17
- import androidx.compose.runtime.mutableStateOf
18
- import androidx.compose.runtime.remember
19
- import androidx.compose.runtime.setValue
20
14
import androidx.compose.ui.Alignment
21
15
import androidx.compose.ui.ExperimentalComposeUiApi
22
16
import androidx.compose.ui.Modifier
@@ -26,122 +20,7 @@ import androidx.compose.ui.input.pointer.isPrimaryPressed
26
20
import androidx.compose.ui.input.pointer.isSecondaryPressed
27
21
import androidx.compose.ui.input.pointer.onPointerEvent
28
22
import androidx.compose.ui.unit.dp
29
- import com.squareup.moshi.JsonAdapter
30
- import com.squareup.workflow1.traceviewer.TraceMode
31
23
import com.squareup.workflow1.traceviewer.model.Node
32
- import com.squareup.workflow1.traceviewer.util.ParseResult
33
- import com.squareup.workflow1.traceviewer.util.createMoshiAdapter
34
- import com.squareup.workflow1.traceviewer.util.parseFileTrace
35
- import com.squareup.workflow1.traceviewer.util.parseLiveTrace
36
- import kotlinx.coroutines.Dispatchers
37
- import kotlinx.coroutines.launch
38
- import kotlinx.coroutines.withContext
39
- import java.net.SocketException
40
-
41
- /* *
42
- * Access point for drawing the main content of the app. It will load the trace for given files and
43
- * tabs. This will also all errors related to errors parsing a given trace JSON file.
44
- *
45
- * This handles either File or Live trace modes, and will parse equally
46
- */
47
- @Composable
48
- internal fun RenderTrace (
49
- traceSource : TraceMode ,
50
- frameInd : Int ,
51
- onFileParse : (List <Node >) -> Unit ,
52
- onNodeSelect : (Node , Node ? ) -> Unit ,
53
- onNewFrame : () -> Unit ,
54
- modifier : Modifier = Modifier
55
- ) {
56
- var isLoading by remember(traceSource) { mutableStateOf(true ) }
57
- var error by remember(traceSource) { mutableStateOf<Throwable ?>(null ) }
58
- val frames = remember { mutableStateListOf<Node >() }
59
- val fullTree = remember { mutableStateListOf<Node >() }
60
- val affectedNodes = remember { mutableStateListOf<Set <Node >>() }
61
-
62
- // Updates current state with the new data from trace source.
63
- fun addToStates (frame : List <Node >, tree : List <Node >, affected : List <Set <Node >>) {
64
- frames.addAll(frame)
65
- fullTree.addAll(tree)
66
- affectedNodes.addAll(affected)
67
- isLoading = false
68
- onFileParse(frame)
69
- }
70
-
71
- // Handles the result of parsing a trace, either from file or live. Live mode includes callback
72
- // for when a new frame is received.
73
- fun handleParseResult (
74
- parseResult : ParseResult ,
75
- onNewFrame : (() -> Unit )? = null
76
- ) {
77
- when (parseResult) {
78
- is ParseResult .Failure -> {
79
- error = parseResult.error
80
- }
81
- is ParseResult .Success -> {
82
- addToStates(
83
- frame = parseResult.trace,
84
- tree = parseResult.trees,
85
- affected = parseResult.affectedNodes
86
- )
87
- onNewFrame?.invoke()
88
- }
89
- }
90
- }
91
-
92
- LaunchedEffect (traceSource) {
93
- when (traceSource) {
94
- is TraceMode .File -> {
95
- checkNotNull(traceSource.file){
96
- " TraceMode.File should have a non-null file to parse."
97
- }
98
- val parseResult = parseFileTrace(traceSource.file)
99
- handleParseResult(parseResult)
100
- }
101
-
102
- is TraceMode .Live -> {
103
- val socket = traceSource.socket
104
- launch {
105
- try {
106
- socket.pollSocket()
107
- } catch (e: SocketException ) {
108
- error = SocketException (" Socket has already been closed or is not available: ${e.message} " )
109
- return @launch
110
- }
111
- }
112
- if (error != null ) {
113
- return @LaunchedEffect
114
- }
115
- val adapter: JsonAdapter <List <Node >> = createMoshiAdapter<Node >()
116
-
117
- withContext(Dispatchers .Default ) {
118
- // Since channel implements ChannelIterator, we can for-loop through on the receiver end.
119
- for (renderPass in socket.renderPassChannel) {
120
- val currentTree = fullTree.lastOrNull()
121
- val parseResult = parseLiveTrace(renderPass, adapter, currentTree)
122
- handleParseResult(parseResult, onNewFrame)
123
- }
124
- }
125
- }
126
- }
127
- }
128
-
129
- if (error != null ) {
130
- Text (" Error parsing: ${error?.message} " )
131
- return
132
- }
133
-
134
- if (! isLoading) {
135
- val previousFrame = if (frameInd > 0 ) fullTree[frameInd - 1 ] else null
136
- DrawTree (
137
- node = fullTree[frameInd],
138
- previousNode = previousFrame,
139
- affectedNodes = affectedNodes[frameInd],
140
- expandedNodes = remember(frameInd) { mutableStateMapOf() },
141
- onNodeSelect = onNodeSelect,
142
- )
143
- }
144
- }
145
24
146
25
/* *
147
26
* Since the workflow nodes present a tree structure, we utilize a recursive function to draw the tree
@@ -151,7 +30,7 @@ internal fun RenderTrace(
151
30
* closed from user clicks.
152
31
*/
153
32
@Composable
154
- private fun DrawTree (
33
+ internal fun DrawTree (
155
34
node : Node ,
156
35
previousNode : Node ? ,
157
36
affectedNodes : Set <Node >,
0 commit comments