Even-driven communication between modules – draft
Posted On February 12, 2022
interface FeatureModule { val observe: SharedFlow<ModuleEvent.Outgoing> suspend fun execute(action: ModuleEvent.Incoming) } sealed class ModuleEvent { sealed class Incoming : ModuleEvent() sealed class Outgoing : ModuleEvent() } object HostModule { private val _outgoingEvents = MutableSharedFlow<ModuleEvent.Incoming>() val outgoingEvents = _outgoingEvents.asSharedFlow() suspend fun initModules() { Feature1Module.observe.collect { when (it) { Feature1Module.Outgoing.OpenJobs -> JobsModule.execute(JobsModule.Incoming.OpenJobs) Feature1Module.Outgoing.GetJobs -> JobsModule.execute(JobsModule.Incoming.GetJobs) } } JobsModule.observe.collect { when (it) { JobsModule.Outgoing.StartFeature -> Feature1Module.execute(Feature1Module.Incoming.OpenFeature) } } } suspend fun execute(event: ModuleEvent) { when (event) { Feature1Module.Outgoing.OpenJobs -> JobsModule.execute(JobsModule.Incoming.OpenJobs) } } } object Feature1Module : FeatureModule { private val _incoming = MutableSharedFlow<ModuleEvent.Incoming>() val incoming: SharedFlow<ModuleEvent.Incoming> get() = _incoming private val _observe = MutableSharedFlow<ModuleEvent.Outgoing>() override val observe: SharedFlow<ModuleEvent.Outgoing> get() = _observe override suspend fun execute(action: ModuleEvent.Incoming) { handleIncomingAction(action) } private suspend fun handleIncomingAction(action: ModuleEvent.Incoming) { when (action) { Incoming.OpenFeature -> { // startActivity() } is Incoming.GetJobs -> { _incoming.emit(action) } } } internal suspend fun emit(action: ModuleEvent.Outgoing) { _observe.emit(action) } sealed class Incoming : ModuleEvent.Incoming() { object OpenFeature : Incoming() data class GetJobs(val job: Job) : ModuleEvent.Incoming() } sealed class Outgoing : ModuleEvent.Outgoing() { object OpenJobs : Outgoing() object GetJobs : ModuleEvent.Outgoing() } } class GetJobsFeature1Activity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) lifecycleScope.launchWhenCreated { HostModule.outgoingEvents.collect { when (it) { is Feature1Module.Incoming.GetJobs -> { // viewModel.showJobs(it.job) } } } HostModule.execute(Feature1Module.Outgoing.GetJobs) } } } object JobsModule : FeatureModule { private val _observe = MutableSharedFlow<ModuleEvent.Outgoing>() override val observe: SharedFlow<ModuleEvent.Outgoing> get() = _observe override suspend fun execute(action: ModuleEvent.Incoming) { handleIncomingAction(action) } private fun handleIncomingAction(action: ModuleEvent.Incoming) { when (action) { Incoming.OpenJobs -> { // startChatActivity() } Incoming.GetJobs -> { // getJobs() } } } internal suspend fun emit(action: ModuleEvent.Outgoing) { _observe.emit(action) } sealed class Incoming : ModuleEvent.Incoming() { object OpenJobs : Incoming() object GetJobs : Incoming() } sealed class Outgoing : ModuleEvent.Outgoing() { object StartFeature : Outgoing() data class JobData(val job: Job) : Outgoing() } }