package Ġcom . mb oud ra a . flow ĊĊ Ċ type alias ĠOn State ChangeListener Ġ= Ġ( state : ĠState < *, Ġ* >, Ġflow : ĠFlow ) Ġ-> ĠUnit ĊĊ Ċ abstract Ġclass ĠFlow ( body : ĠFlow Builder . () Ġ-> ĠUnit ) Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġdata Store Ġ= ĠData Store () ĊĠĠĠ Ġprivate Ġval Ġstate Change Listeners Ġ= Ġarray ListOf < On State ChangeListener >() ĊĠĠĠ Ġprivate Ġval Ġtransition Listeners Ġ= Ġarray ListOf < On Transition Listener >() ĊĠĠĠ Ġprivate Ġval Ġtransitions Holder : ĠState Transitions Holder ĊĠĠĠ Ġprivate Ġval Ġside Effects : ĠSide Effects ? ĊĊĠĠĠ Ġlateinit Ġvar Ġcurrent State : ĠState < *, Ġ*> ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġflow Builder Ġ= ĠFlow Builder (). apply ( body ) ĊĊĠĠĠĠĠĠĠ Ġflow Builder . default State ?. let Ġ{ Ġ( state , Ġdata ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠsetCurrent State ( state Ġas ĠState < Any ?, Ġ* >, Ġdata ) ĊĠĠĠĠĠĠĠ Ġ} Ġ?: Ġthrow ĠDefault State Missing Exception (" Default Ġstate Ġis Ġmissing Ġfor Ġflow Ġ$ this ") ĊĊĠĠĠĠĠĠĠ Ġtransitions Holder Ġ= Ġflow Builder . transitions Holder ĊĠĠĠĠĠĠĠ Ġside Effects Ġ= Ġflow Builder . side Effects ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġadd On State ChangeListener ( listener : ĠOn State ChangeListener ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġlistener ( currentState , Ġthis ) ĊĠĠĠĠĠĠĠ Ġreturn Ġstate Change Listeners . add ( listener ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġremove On State ChangeListener ( listener : ĠOn State ChangeListener ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġstate Change Listeners . remove ( listener ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġadd On Transition Listener ( listener : ĠOn Transition Listener ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtransition Listeners . add ( listener ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġremove On Transition Listener ( listener : ĠOn Transition Listener ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtransition Listeners . remove ( listener ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġ< INPUT , ĠACTION Ġ: ĠAny > Ġdispatch Action ( state : ĠState < INPUT , ĠACTION >, Ġaction : ĠACTION ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( state Ġ!= Ġcurrent State ) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġval Ġprevious State Ġ= Ġcurrent State ĊĊĠĠĠĠĠĠĠ Ġval Ġtransition Ġ= Ġtransitions Holder . get Transition ( state )?. invoke ( Transition Builder ( state ), ĠgetState Data ( state ) Ġas ĠINPUT , Ġaction ) ĊĠĠĠĠĠĠĠ Ġtransition ?. run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġperform ( this @ Flow ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( previous State Ġ!= Ġcurrent State ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition Listeners . forEach Ġ{ Ġit . on Transition ( previous State Ġto Ġcurrent State , Ġthis @ Flow ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġ?: Ġthrow ĠTransition Missing Exception (" transition Ġis Ġmissing Ġfor Ġaction Ġ$ action Ġin Ġstate Ġ$ state ") ĊĊĊĠĠĠĠĠĠĠ Ġside Effects ?. invoke ( this , Ġtransition . from Ġto Ġtransition . to , Ġaction ) ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġ< INPUT > ĠsetCurrent State ( state : ĠState < INPUT , Ġ* >, Ġdata : ĠINPUT ?) Ġ{ ĊĠĠĠĠĠĠĠ ĠsetState Data ( state , Ġdata ) ĊĠĠĠĠĠĠĠ Ġcurrent State Ġ= Ġstate ĊĠĠĠĠĠĠĠ Ġstate Change Listeners . forEach Ġ{ Ġit ( currentState , Ġthis ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġ< INPUT > ĠgetState Data ( state : ĠState < INPUT , Ġ* >): ĠINPUT ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġdata Store . getData ( state ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġ< INPUT , ĠSTATE Ġ: ĠState < INPUT , Ġ* >> ĠsetState Data ( state : ĠSTATE , Ġdata : ĠINPUT ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġdata ?. let Ġ{ Ġdata Store . put Data ( state , Ġit ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġclass ĠData Store Ġ{ ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġstore Ġ= Ġhash Map Of < String , ĠAny ?> () ĊĊĠĠĠĠĠĠĠ Ġfun Ġ< DATA > ĠgetData ( state : ĠState < DATA , Ġ* >): ĠDATA ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġstore [ state . java Class . canonical Name ] Ġas ? ĠDATA ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġ< DATA , ĠSTATE Ġ: ĠState < DATA , Ġ* >> Ġput Data ( state : ĠSTATE , Ġdata : ĠDATA ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstore [ state . java Class . canonical Name ] Ġ= Ġdata ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinterface ĠOn Transition Listener Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġon Transition ( transition : ĠPair < State < *, Ġ* >, ĠState < *, Ġ* >>, Ġflow : ĠFlow ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ inline Ġfun Ġ< re ified ĠSTATE Ġ: ĠState < *, Ġ* >> ĠFlow . currentState As (): ĠSTATE ? Ġ= Ġcurrent State Ġas ? ĠSTATE