Even-driven communication between modules – draft

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

Add a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.