Hi all! I’m trying to implement so kind of event b...
# flow
s
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
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
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