@@ -2,6 +2,7 @@ package dev.silenium.libs.flows.impl
2
2
3
3
import dev.silenium.libs.flows.api.*
4
4
import kotlinx.coroutines.*
5
+ import kotlinx.coroutines.flow.map
5
6
import kotlin.coroutines.CoroutineContext
6
7
import kotlin.reflect.KClass
7
8
@@ -98,25 +99,38 @@ internal class FlowGraphImpl(private val coroutineScope: CoroutineScope) :
98
99
99
100
internal class FlowGraphConfigScopeImpl (private val flowGraph : FlowGraph ) : FlowGraphConfigScope,
100
101
FlowGraph by flowGraph {
101
- private val connectionStarted = mutableSetOf<Job >()
102
-
103
- override fun <T , P > Source <T , P >.connectTo (sink : Sink <T , P >): Result <Job > {
104
- outputMetadata.forEach { (pad, metadata) ->
105
- sink.configure(pad, metadata).onFailure {
106
- return Result .failure(IllegalStateException (" Unable to configure input pad $pad of sink $sink " , it))
102
+ private val configurationJobs = mutableSetOf<Job >()
103
+
104
+ override fun <T , P > connect (
105
+ pair : Pair <Source <T , P >, Sink <T , P >>,
106
+ padSelector : (sourceSinkMap: Map <UInt , UInt >, sourcePads: Map <UInt , P >, sourcePad: UInt , metadata: P ) -> UInt? ,
107
+ ): Job {
108
+ val (source, sink) = pair
109
+ val padMap = mutableMapOf<UInt , UInt >()
110
+ for ((sourcePad, metadata) in source.outputMetadata) {
111
+ val sinkPad = padSelector(padMap, source.outputMetadata, sourcePad, metadata) ? : continue
112
+ padMap[sourcePad] = sinkPad
113
+ }
114
+ padMap.forEach { (sourcePad, sinkPad) ->
115
+ val metadata = source.outputMetadata.getValue(sourcePad)
116
+ sink.configure(sinkPad, metadata).onFailure {
117
+ throw IllegalStateException (" Unable to configure $sink :$sinkPad from $source :$sourcePad " , it)
107
118
}
108
119
}
109
120
val started = CompletableDeferred <Unit >()
110
121
return launch {
111
122
started.complete(Unit )
112
- flow.collect(sink)
123
+ source.flow
124
+ .map { it.copy(pad = padMap.getValue(it.pad)) }
125
+ .collect(sink)
113
126
}.also {
114
- connectionStarted .add(started)
115
- }. let { Result .success(it) }
127
+ configurationJobs .add(started)
128
+ }
116
129
}
117
130
118
- override suspend fun configure (): Result <Unit > = runCatching {
119
- connectionStarted.joinAll()
131
+ override suspend fun configure (): Result <FlowGraph > = runCatching {
132
+ configurationJobs.joinAll()
133
+ flowGraph
120
134
}
121
135
}
122
136
@@ -136,7 +150,7 @@ internal fun FlowGraph.builder() = FlowGraphConfigScopeImpl(this)
136
150
suspend fun FlowGraph (
137
151
coroutineContext : CoroutineContext = Dispatchers .Default ,
138
152
block : FlowGraphConfigScope .() -> Unit ,
139
- ): FlowGraph = FlowGraphImpl (coroutineContext).builder().apply (block).apply { configure() }
153
+ ): FlowGraph = FlowGraphImpl (coroutineContext).builder().apply (block).configure().getOrThrow()
140
154
141
155
/* *
142
156
* Creates a new [FlowGraph] with the given [coroutineScope] and [block] configuration.
@@ -152,4 +166,4 @@ suspend fun FlowGraph(
152
166
suspend fun FlowGraph (
153
167
coroutineScope : CoroutineScope ,
154
168
block : FlowGraphConfigScope .() -> Unit ,
155
- ): FlowGraph = FlowGraphImpl (coroutineScope).builder().apply (block).apply { configure() }
169
+ ): FlowGraph = FlowGraphImpl (coroutineScope).builder().apply (block).configure().getOrThrow()
0 commit comments