@@ -2,6 +2,7 @@ package dev.silenium.libs.flows.impl
22
33import dev.silenium.libs.flows.api.*
44import kotlinx.coroutines.*
5+ import kotlinx.coroutines.flow.map
56import kotlin.coroutines.CoroutineContext
67import kotlin.reflect.KClass
78
@@ -98,25 +99,38 @@ internal class FlowGraphImpl(private val coroutineScope: CoroutineScope) :
9899
99100internal class FlowGraphConfigScopeImpl (private val flowGraph : FlowGraph ) : FlowGraphConfigScope,
100101 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)
107118 }
108119 }
109120 val started = CompletableDeferred <Unit >()
110121 return launch {
111122 started.complete(Unit )
112- flow.collect(sink)
123+ source.flow
124+ .map { it.copy(pad = padMap.getValue(it.pad)) }
125+ .collect(sink)
113126 }.also {
114- connectionStarted .add(started)
115- }. let { Result .success(it) }
127+ configurationJobs .add(started)
128+ }
116129 }
117130
118- override suspend fun configure (): Result <Unit > = runCatching {
119- connectionStarted.joinAll()
131+ override suspend fun configure (): Result <FlowGraph > = runCatching {
132+ configurationJobs.joinAll()
133+ flowGraph
120134 }
121135}
122136
@@ -136,7 +150,7 @@ internal fun FlowGraph.builder() = FlowGraphConfigScopeImpl(this)
136150suspend fun FlowGraph (
137151 coroutineContext : CoroutineContext = Dispatchers .Default ,
138152 block : FlowGraphConfigScope .() -> Unit ,
139- ): FlowGraph = FlowGraphImpl (coroutineContext).builder().apply (block).apply { configure() }
153+ ): FlowGraph = FlowGraphImpl (coroutineContext).builder().apply (block).configure().getOrThrow()
140154
141155/* *
142156 * Creates a new [FlowGraph] with the given [coroutineScope] and [block] configuration.
@@ -152,4 +166,4 @@ suspend fun FlowGraph(
152166suspend fun FlowGraph (
153167 coroutineScope : CoroutineScope ,
154168 block : FlowGraphConfigScope .() -> Unit ,
155- ): FlowGraph = FlowGraphImpl (coroutineScope).builder().apply (block).apply { configure() }
169+ ): FlowGraph = FlowGraphImpl (coroutineScope).builder().apply (block).configure().getOrThrow()
0 commit comments