All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.MobiusLoopController.kt Maven / Gradle / Ivy

package kt.mobius

import kt.mobius.functions.Consumer
import kt.mobius.runners.Runnable
import kt.mobius.runners.WorkRunner

class MobiusLoopController(
    private val loopFactory: MobiusLoop.Factory,
    private val defaultModel: M,
    private val mainThreadRunner: WorkRunner
) : MobiusLoop.Controller, ControllerActions {
    private object LOCK

    private var currentState: ControllerStateBase? = null

    override val isRunning: Boolean
        get() = mpp.synchronized(LOCK) {
            currentState!!.isRunning
        }

    override val model: M
        get() = mpp.synchronized(LOCK) {
            currentState!!.onGetModel()
        }

    init {
        goToStateInit(defaultModel)
    }

    private fun dispatchEvent(event: E) {
        currentState!!.onDispatchEvent(event)
    }

    private fun updateView(model: M) {
        currentState!!.onUpdateView(model)
    }

    override fun connect(view: Connectable): Unit = mpp.synchronized(LOCK) {
        currentState!!.onConnect(view)
    }

    override fun disconnect(): Unit = mpp.synchronized(LOCK) {
        currentState!!.onDisconnect()
    }

    override fun start(): Unit = mpp.synchronized(LOCK) {
        currentState!!.onStart()
    }

    override fun stop(): Unit = mpp.synchronized(LOCK) {
        currentState!!.onStop()
    }

    override fun replaceModel(model: M): Unit = mpp.synchronized(LOCK) {
        currentState!!.onReplaceModel(model)
    }

    override fun postUpdateView(model: M) {
        mainThreadRunner.post(
            object : Runnable {
                override fun run() {
                    updateView(model)
                }
            })
    }

    override fun goToStateInit(nextModelToStartFrom: M): Unit = mpp.synchronized(LOCK) {
        currentState = ControllerStateInit(this, nextModelToStartFrom)
    }

    override fun goToStateCreated(renderer: Connection, nextModelToStartFrom: M?): Unit =
        mpp.synchronized(LOCK) {
            val nextModel = nextModelToStartFrom ?: defaultModel
            currentState = ControllerStateCreated(this, renderer, nextModel)
        }

    override fun goToStateCreated(view: Connectable, nextModelToStartFrom: M) {

        val safeModelHandler = SafeConnectable(view)

        val modelConnection = safeModelHandler.connect { event -> dispatchEvent(event) }

        goToStateCreated(modelConnection, nextModelToStartFrom)
    }

    override fun goToStateRunning(renderer: Connection, nextModelToStartFrom: M): Unit =
        mpp.synchronized(LOCK) {
            val stateRunning = ControllerStateRunning(this, renderer, loopFactory, nextModelToStartFrom)

            currentState = stateRunning

            stateRunning.start()
        }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy