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()
}
}