package Ġit . kr zem in ski . v ima al Ċ Ċ import Ġkotlin . reflect . K Class Ċ Ċ class ĠState Machine < State Type Ġ: ĠAny , ĠEventType , ĠSide Effect Type >( initialState : ĠState Type ) Ġ{ ĊĠĠĠ Ġvar Ġcurrent State Ġ= ĠinitialState ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĠĠĠ Ġprivate Ġval Ġstate To Transition Mapping : ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMutable Map < K Class < out ĠState Type >, Ġ( EventType ) Ġ-> ĠTransition < State Type , ĠSide Effect Type >> Ġ= Ġmutable Map Of () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠPerform Ġa Ġtransition Ġfrom Ġ[ currentState ], Ġtriggered Ġby Ġ[ event ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġtransition ( event : ĠEventType ): ĠSide Effect Type ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtransition Ġ= Ġstate To Transition Mapping [ currentState :: class ]?. invoke ( event ) ĊĠĠĠĠĠĠĠ Ġcurrent State Ġ= Ġtransition ?. state Ġ?: Ġcurrent State ĊĠĠĠĠĠĠĠ Ġreturn Ġtransition ?. side Effect ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠChecks Ġif Ġany Ġlogic Ġwas Ġset Ġto Ġgo Ġfrom Ġ[ state ] Ġto Ġany Ġother Ġstate . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġcontains Transition For ( state : ĠState Type ) Ġ= Ġstate To Transition Mapping [ state :: class ] Ġ!= Ġnull ĊĊĠĠĠ Ġdata Ġclass ĠTransition < State Type , ĠSide Effect Type >( val Ġstate : ĠState Type , Ġval Ġside Effect : ĠSide Effect Type ?) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠUsed Ġin ĠDSL Ġduring Ġbuilding Ġthe Ġstate Ġmachine , Ġto Ġdefine Ġa Ġstate Ġand Ġtransitions Ġfrom Ġit . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoperator Ġfun ĠState Type . invoke ( function : Ġ( EventType ) Ġ-> ĠTransition < State Type , ĠSide Effect Type >) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( state To Transition Mapping . containsKey ( this :: class )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" State Ġre definition Ġduring Ġbuilding : Ġ${ this }") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġstate To Transition Mapping [ this :: class ] Ġ= Ġfunction ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoperator Ġfun Ġ< T Ġ: ĠState Type > ĠK Class < T >. invoke ( function : Ġ( EventType , ĠT ) Ġ-> ĠTransition < State Type , ĠSide Effect Type >) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( state To Transition Mapping . containsKey ( this )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" State Ġre definition Ġduring Ġbuilding : Ġ${ this }") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ@ Suppress (" UN CHECK ED _ CAST ") Ġ// Ġcurrent State Ġis Ġof Ġtype ĠT Ġbecause Ġthis Ġmethod Ġdefines Ġtransitions Ġfrom Ġstate ĠT . ĊĠĠĠĠĠĠĠ Ġstate To Transition Mapping [ this ] Ġ= Ġ{ ĠeventType Ġ-> Ġfunction ( eventType , Ġcurrent State Ġas ĠT ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠUsed Ġin ĠDSL Ġduring Ġbuilding Ġthe Ġstate Ġmachine , Ġto Ġspecify Ġthe Ġtarget Ġstate Ġduring Ġtransition . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġin fix Ġfun Ġgo . to ( state : ĠState Type ): ĠTransition < State Type , ĠSide Effect Type > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTransition ( state Ġ= Ġstate , Ġside Effect Ġ= Ġnull ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠUsed Ġin ĠDSL Ġduring Ġbuilding Ġthe Ġstate Ġmachine , Ġto Ġspecify Ġthe Ġside Ġeffect Ġof Ġthe Ġtransition . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġin fix Ġfun ĠTransition < State Type , ĠSide Effect Type >. with ( side Effect : ĠSide Effect Type ): ĠTransition < State Type , ĠSide Effect Type > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . copy ( side Effect Ġ= Ġside Effect ) Ċ } Ċ Ċ fun Ġ< State Type Ġ: ĠAny , ĠEventType , ĠSide Effect Type > Ġstate Machine ( ĊĠĠĠĠĠĠĠ ĠinitialState : ĠState Type , ĊĠĠĠĠĠĠĠ Ġinitialize : ĠState Machine < State Type , ĠEventType , ĠSide Effect Type >. () Ġ-> ĠUnit ): ĠState Machine < State Type , ĠEventType , ĠSide Effect Type > Ġ{ ĊĠĠĠ Ġval Ġnew StateMachine Ġ= ĠState Machine < State Type , ĠEventType , ĠSide Effect Type >( initialState Ġ= ĠinitialState ) ĊĠĠĠ Ġnew StateMachine . initialize () ĊĊĠĠĠ Ġif Ġ(! new StateMachine . contains Transition For ( initialState )) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" No Ġtransitions Ġhave Ġbeen Ġdefined Ġfor Ġthe Ġinitial Ġstate : Ġ$ initialState ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġnew StateMachine Ċ } Ċ Ċ /** Ċ Ġ* ĠUsed Ġin ĠDSL Ġduring Ġbuilding . Ċ Ġ*/ Ċ object Ġgo Ċ