https://kotlinlang.org logo
#flow
Title
# flow
s

Semyon Zadorozhnyi

08/26/2021, 12:44 PM
Hi all! I’m trying to implement so kind of event bus repository using SharedFlow Long story short: System can send events to TriggerRepository via sendEvent method Any component in the system should have an ability to observe trigger. Trigger should fire when there is sequence of events in specific order emmited. I’m struggling with transformation step where I should somehow collect sequence of events and call the trigger. Code snippet and example in thread. Any form of help is appreciated 🙂
Copy code
class TriggerRepositoryImpl: TriggerRepository {

    private val _events = MutableSharedFlow<Event>()

    override fun observeTrigger(): Flow<Unit> = flow {
        // Observe _events and match latest against validTriggerPatterns
        // If there is a match - call emit(Unit)
    }

    override suspend fun addEvent(event: Event) {
        _events.emit(event)
    }

}

val validTriggerPatterns = listOf(
        listOf(Event.ScreenOpen(Screen.Main), Event.ScreenOpen(Screen.Details)),
        listOf(Event.CardCreated, Event.ScreenOpen(Screen.Main))
)
example: addEvent(Event.ScreenOpen(Screen.Details)) addEvent(Event.ScreenOpen(Screen.Main)) addEvent(Event.ScreenOpen(Screen.Details)) <- previous and this events are in pattern — emit(Unit) addEvent(Event.CardCreated) addEvent(Event.CardCreated) addEvent(Event.ScreenOpen(Screen.Details)) addEvent(Event.CardCreated) addEvent(Event.ScreenOpen(Screen.Main)) <- previous and this events are in pattern — emit(Unit)
There also might be more then two events in pattern but all patterns are unique
i

Ivan Pavlov

08/26/2021, 3:08 PM
I don't have a particular solution, but it looks like your problem is similar to what
runningReduce
or
runningFold
solves. You can take a look at sources and adapt it to your use case
n

Nick Allen

08/26/2021, 5:55 PM
I think you essentially want something like:
Copy code
flow {
    val history = ArrayDeque<Event>()
    _events.collect {
        history.addLast(it)
        if (history.size > MAX_PATTERN_SIZE) {
            history.removeFirst()
        }
        if (validTriggerPatterns.any { pattern -> isMatch(history. pattern) } {
            emit(Unit)
        }
    }
}
👍 1
2 Views