package com.buginmyhead.chatter.fundamental.architecture /** * Trans-state is a coinage to indicate transition and state together in the state machine concept. * * Example for [GenericTransState], [GenericTransition], [GenericTransition.Disposal]: * ```kotlin * sealed interface Event * sealed interface TransState : GenericTransState * sealed interface State : TransState * * data class Transition( * override val state: State, * val sideEffect1: Any, * val sideEffect2: Any, * ) : TransState, GenericTransition { * * data object Disposal : Event, GenericTransition.Disposal * * } * ``` * * @param TS trans-state: the runtime type is either [GenericTransState] or [GenericTransition]. * @param S state * @param E event */ @Suppress("UNCHECKED_CAST") interface GenericTransState, S : TS, E> { fun transitByEvent(event: E): TS companion object { /** * @return * [GenericTransition.state] if the receiver is [GenericTransition], * or the receiver itself otherwise. */ @JvmStatic val , S : TS, E> TS.state: S get() = (if (this is GenericTransition<*, *, *>) state else this) as S } } /** * Transition in the state machine concept. * * Read the documentation of [GenericTransState] for an example. * * @param S state * @param E event */ interface GenericTransition, S : TS, E> : GenericTransState { val state: S /** * @return [state] for [Disposal] event, or `[transitByEvent]` of [state] for other events. */ override fun transitByEvent(event: E): TS = if (event is Disposal) state else state.transitByEvent(event) /** * Implement with the custom event interface. * The meaning of this event is to reset side effect state to default * by calling [transitByEvent]. * * Read the documentation of [GenericTransState] for an example. */ interface Disposal }