package Ġorg . opp ia . android . domain . ex ploration Ċ Ċ import Ġkotlinx . coroutines . Coroutine Dispatcher Ċ import Ġkotlinx . coroutines . Coroutine Scope Ċ import Ġkotlinx . coroutines . channels . Channel Ċ import Ġkotlinx . coroutines . channels . Send Channel Ċ import Ġkotlinx . coroutines . channels . actor Ċ import Ġkotlinx . coroutines . flow . Mutable State Flow Ċ import Ġkotlinx . coroutines . flow . State Flow Ċ import Ġkotlinx . coroutines . flow . launch In Ċ import Ġkotlinx . coroutines . flow . on Each Ċ import Ġorg . opp ia . android . app . model . Answer Outcome Ċ import Ġorg . opp ia . android . app . model . Checkpoint State Ċ import Ġorg . opp ia . android . app . model . Ep hemeral State Ċ import Ġorg . opp ia . android . app . model . Ex ploration Ċ import Ġorg . opp ia . android . app . model . Ex ploration Checkpoint Ċ import Ġorg . opp ia . android . app . model . Help Index Ċ import Ġorg . opp ia . android . app . model . Profile Id Ċ import Ġorg . opp ia . android . app . model . User Answer Ċ import Ġorg . opp ia . android . domain . classify . Answer Classification Controller Ċ import Ġorg . opp ia . android . domain . ex ploration . Ex ploration Progress . Play Stage . LOADING _ EX PL OR ATION Ċ import Ġorg . opp ia . android . domain . ex ploration . Ex ploration Progress . Play Stage . NOT _ PLAY ING Ċ import Ġorg . opp ia . android . domain . ex ploration . Ex ploration Progress . Play Stage . SUBMIT TING _ AN SW ER Ċ import Ġorg . opp ia . android . domain . ex ploration . Ex ploration Progress . Play Stage . VIEW ING _ STATE Ċ import Ġorg . opp ia . android . domain . ex ploration . light weight checkpoint ing . Ex ploration Checkpoint Controller Ċ import Ġorg . opp ia . android . domain . hint sand solution . Hint Handler Ċ import Ġorg . opp ia . android . domain . opp ialog ger . Opp ia Logger Ċ import Ġorg . opp ia . android . domain . opp ialog ger . exceptions . Exceptions Controller Ċ import Ġorg . opp ia . android . domain . topic . Story Progress Controller Ċ import Ġorg . opp ia . android . domain . translation . Translation Controller Ċ import Ġorg . opp ia . android . util . data . AsyncResult Ċ import Ġorg . opp ia . android . util . data . DataProvider Ċ import Ġorg . opp ia . android . util . data . Data Providers Ċ import Ġorg . opp ia . android . util . data . Data Providers . Companion . combine With Ċ import Ġorg . opp ia . android . util . system . Opp ia Clock Ċ import Ġorg . opp ia . android . util . threading . Background Dispatcher Ċ import Ġjava . util . UUID Ċ import Ġjavax . inject . Inject Ċ import Ġjavax . inject . Singleton Ċ Ċ private Ġconst Ġval ĠBEGIN _ EX PL OR ATION _ RESULT _ PROVIDER _ ID Ġ= ĊĠ Ġ" Ex ploration Progress Controller . begin _ ex ploration _ result " Ċ private Ġconst Ġval ĠFIN ISH _ EX PL OR ATION _ RESULT _ PROVIDER _ ID Ġ= ĊĠ Ġ" Ex ploration Progress Controller . finish _ ex ploration _ result " Ċ private Ġconst Ġval ĠSUB MIT _ AN SW ER _ RESULT _ PROVIDER _ ID Ġ= ĊĠ Ġ" Ex ploration Progress Controller . submit _ answer _ result " Ċ private Ġconst Ġval ĠSUB MIT _ HINT _ RE VE AL ED _ RESULT _ PROVIDER _ ID Ġ= ĊĠ Ġ" Ex ploration Progress Controller . submit _ hint _ re ve aled _ result " Ċ private Ġconst Ġval ĠSUB MIT _ SOL UTION _ RE VE AL ED _ RESULT _ PROVIDER _ ID Ġ= ĊĠ Ġ" Ex ploration Progress Controller . submit _ solution _ re ve aled _ result " Ċ private Ġconst Ġval ĠMOVE _ TO _ PREVIOUS _ STATE _ RESULT _ PROVIDER _ ID Ġ= ĊĠ Ġ" Ex ploration Progress Controller . move _ to _ previous _ state _ result " Ċ private Ġconst Ġval ĠMOVE _ TO _ NEXT _ STATE _ RESULT _ PROVIDER _ ID Ġ= ĊĠ Ġ" Ex ploration Progress Controller . move _ to _ next _ state _ result " Ċ private Ġconst Ġval ĠCURRENT _ STATE _ PROVIDER _ ID Ġ= Ġ" Ex ploration Progress Controller . current _ state " Ċ private Ġconst Ġval ĠLOCAL IZED _ STATE _ PROVIDER _ ID Ġ= Ġ" Ex ploration Progress Controller . localized _ state " Ċ Ċ /** Ċ Ġ* ĠA Ġdefault Ġsession ĠID Ġto Ġbe Ġused Ġbefore Ġa Ġsession Ġhas Ġbeen Ġinitialized . Ċ Ġ* Ċ Ġ* ĠThis Ġsession ĠID Ġwill Ġnever Ġmatch , Ġso Ġmessages Ġthat Ġare Ġreceived Ġwith Ġthis ĠID Ġwill Ġnever Ġbe Ċ Ġ* Ġprocessed . Ċ Ġ*/ Ċ private Ġconst Ġval ĠDEFAULT _ SESSION _ ID Ġ= Ġ" default _ session _ id " Ċ Ċ /** Ċ Ġ* ĠController Ġthat Ġtracks Ġand Ġreports Ġthe Ġle arner 's Ġep hemeral / non - pers isted Ġprogress Ġthrough Ġan Ċ Ġ* Ġexploration . ĠNote Ġthat Ġthis Ġcontroller Ġonly Ġsupports Ġone Ġactive Ġexploration Ġat Ġa Ġtime . Ċ Ġ* Ċ Ġ* ĠThe Ġcurrent Ġexploration Ġsession Ġis Ġstarted Ġvia Ġthe Ġexploration Ġdata Ġcontroller . Ċ Ġ* Ċ Ġ* ĠThis Ġclass Ġis Ġnot Ġsafe Ġto Ġuse Ġacross Ġmultiple Ġthreads , Ġand Ġshould Ġonly Ġever Ġbe Ġinteract ed Ġwith Ċ Ġ* Ġvia Ġthe Ġmain Ġthread . ĠThe Ġcontroller Ġmakes Ġuse Ġof Ġmultiple Ġthreads Ġto Ġoff load Ġall Ġstate Ċ Ġ* Ġoperations , Ġso Ġcalls Ġinto Ġthis Ġcontroller Ġshould Ġreturn Ġquickly Ġand Ġwill Ġnever Ġblock . ĠEach Ġmethod Ċ Ġ* Ġreturns Ġa Ġ[ DataProvider ] Ġthat Ġcan Ġbe Ġobserved Ġfor Ġthe Ġfuture Ġresult Ġof Ġthe Ġmethod 's Ġcorresponding Ċ Ġ* Ġoperation . Ċ Ġ* Ċ Ġ* ĠNote Ġthat Ġoperations Ġare Ġguaranteed Ġto Ġexecute Ġin Ġthe Ġorder Ġof Ġcontroller Ġmethod Ġcalls , Ġinternal Ċ Ġ* Ġstate Ġis Ġalways Ġkept Ġinternally Ġconsistent Ġ( so Ġlong - running Ġ[ DataProvider ] Ġsubscriptions Ġfor Ġa Ċ Ġ* Ġparticular Ġplay Ġsession Ġwill Ġreceive Ġupdates ), Ġand Ġstate Ġcan Ġnever Ġleak Ġacross Ġsession Ċ Ġ* Ġboundaries Ġ( though Ġre - subscription Ġwill Ġbe Ġnecessary Ġto Ġobserve Ġstate Ġin Ġa Ġnew Ġplay Ġsession -- see Ċ Ġ* Ġ[ submit Answer ] Ġand Ġ[ getCurrent State ] Ġmethod ĠK Docs Ġfor Ġmore Ġdetails ). Ċ Ġ*/ Ċ @ Singleton Ċ class ĠEx ploration Progress Controller Ġ@ Inject Ġconstructor ( ĊĠ Ġprivate Ġval Ġexploration Retriever : ĠEx ploration Retriever , ĊĠ Ġprivate Ġval Ġanswer Classification Controller : ĠAnswer Classification Controller , ĊĠ Ġprivate Ġval Ġexceptions Controller : ĠExceptions Controller , ĊĠ Ġprivate Ġval Ġexploration Checkpoint Controller : ĠEx ploration Checkpoint Controller , ĊĠ Ġprivate Ġval Ġstory Progress Controller : ĠStory Progress Controller , ĊĠ Ġprivate Ġval Ġopp ia Clock : ĠO pp ia Clock , ĊĠ Ġprivate Ġval Ġopp ia Logger : ĠO pp ia Logger , ĊĠ Ġprivate Ġval Ġhint Handler Factory : ĠHint Handler . Factory , ĊĠ Ġprivate Ġval Ġtranslation Controller : ĠTranslation Controller , ĊĠ Ġprivate Ġval Ġdata Providers : ĠData Providers , ĊĠ Ġ@ Background Dispatcher Ġprivate Ġval Ġbackground Coroutine Dispatcher : ĠCor outine Dispatcher Ċ ) Ġ{ ĊĠ Ġ// ĠTODO (# 1 7 9 ): ĠAdd Ġsupport Ġfor Ġparameters . ĊĠ Ġ// ĠTODO (# 3 4 6 7 ): ĠUpdate Ġthe Ġmechanism Ġto Ġsave Ġcheck points Ġto Ġeliminate Ġthe Ġrace Ġcondition Ġthat Ġmay ĊĠ Ġ// Ġ Ġar ise Ġif Ġthe Ġfunction Ġfinish Ex ploration Async Ġacquire s Ġlock Ġbefore Ġthe Ġinvoke On Completion ĊĠ Ġ// Ġ Ġcallback Ġon Ġthe Ġdeferred Ġreturned Ġon Ġsaving Ġcheck points . ĠIn Ġthis Ġcase ĠEx ploration Activity Ġwill ĊĠ Ġ// Ġ Ġmake Ġdecisions Ġbased Ġon Ġa Ġvalue Ġof Ġthe Ġcheckpoint State Ġwhich Ġmight Ġnot Ġbe Ġup - to Ġdate . ĊĊĠ Ġ// ĠTODO (# 6 0 6 ): ĠReplace Ġthis Ġwith Ġa Ġprofile Ġscope Ġto Ġavoid Ġthis Ġhack y Ġworkaround Ġ( which Ġis Ġneeded ĊĠ Ġ// Ġ Ġfor ĠgetCurrent State ). ĊĠ Ġprivate Ġlateinit Ġvar Ġprofile Id : ĠProfile Id ĊĊĠ Ġprivate Ġvar Ġmost Recent SessionId : ĠString ? Ġ= Ġnull ĊĠ Ġprivate Ġval Ġactive SessionId : ĠString ĊĠĠĠ Ġget () Ġ= Ġmost Recent SessionId Ġ?: ĠDEFAULT _ SESSION _ ID ĊĊĠ Ġprivate Ġvar Ġmost Recent Ep hemeral State Flow Ġ= ĊĠĠĠ Ġcreate AsyncResult State Flow < Ep hemeral State >( ĊĠĠĠĠĠ ĠAsync Result . Failure ( IllegalStateException (" Ex ploration Ġis Ġnot Ġyet Ġinitialized .")) ĊĠĠĠ Ġ) ĊĊĠ Ġprivate Ġvar Ġmost Recent Command Queue : ĠSend Channel < Controller Message <* >> ? Ġ= Ġnull ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠRe sets Ġthis Ġcontroller Ġto Ġbegin Ġplaying Ġthe Ġspecified Ġ[ Ex ploration ], Ġand Ġreturns Ġa ĊĠĠ Ġ* Ġ[ DataProvider ] Ġindicating Ġwhether Ġthe Ġstart Ġwas Ġsuccessful . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠThe Ġreturned Ġ[ DataProvider ] Ġhas Ġthe Ġsame Ġlifecycle Ġconsider ations Ġas Ġthe Ġprovider Ġreturned Ġby ĊĠĠ Ġ* Ġ[ submit Answer ]. ĊĠĠ Ġ*/ ĊĠ Ġinternal Ġfun Ġbegin Ex ploration Async ( ĊĠĠĠ Ġprofile Id : ĠProfile Id , ĊĠĠĠ Ġtopic Id : ĠString , ĊĠĠĠ Ġstory Id : ĠString , ĊĠĠĠ Ġexploration Id : ĠString , ĊĠĠĠ Ġshould Save Partial Progress : ĠBoolean , ĊĠĠĠ Ġexploration Checkpoint : ĠEx ploration Checkpoint ĊĠ Ġ): ĠData Provider < Any ?> Ġ{ ĊĠĠĠ Ġval Ġep hemeral State Flow Ġ= Ġcreate AsyncResult State Flow < Ep hemeral State >() ĊĠĠĠ Ġval ĠsessionId Ġ= ĠUUID . randomUUID (). toString (). also Ġ{ ĊĠĠĠĠĠ Ġmost Recent SessionId Ġ= Ġit ĊĠĠĠĠĠ Ġmost Recent Ep hemeral State Flow Ġ= Ġep hemeral State Flow ĊĠĠĠĠĠ Ġmost Recent Command Queue Ġ= Ġcreate Controller Command Actor () ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġbegin Ex ploration Result Flow Ġ= Ġcreate AsyncResult State Flow < Any ?> () ĊĠĠĠ Ġval Ġmessage Ġ= ĊĠĠĠĠĠ ĠController Message . Initialize Controller ( ĊĠĠĠĠĠĠĠ Ġprofile Id , ĊĠĠĠĠĠĠĠ Ġtopic Id , ĊĠĠĠĠĠĠĠ Ġstory Id , ĊĠĠĠĠĠĠĠ Ġexploration Id , ĊĠĠĠĠĠĠĠ Ġshould Save Partial Progress , ĊĠĠĠĠĠĠĠ Ġexploration Checkpoint , ĊĠĠĠĠĠĠĠ Ġep hemeral State Flow , ĊĠĠĠĠĠĠĠ ĠsessionId , ĊĠĠĠĠĠĠĠ Ġbegin Ex ploration Result Flow ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġthis . profile Id Ġ= Ġprofile Id ĊĠĠĠ Ġsend Command For Operation ( message ) Ġ{ ĊĠĠĠĠĠ Ġ" Failed Ġto Ġschedule Ġcommand Ġfor Ġinitializing Ġthe Ġexploration Ġprogress Ġcontroller ." ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġbegin Ex ploration Result Flow . convertTo Session Provider ( BEGIN _ EX PL OR ATION _ RESULT _ PROVIDER _ ID ) ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠIndicates Ġthat Ġthe Ġcurrent Ġexploration Ġbeing Ġplayed Ġis Ġnow Ġcompleted , Ġand Ġreturns Ġa ĊĠĠ Ġ* Ġ[ DataProvider ] Ġindicating Ġwhether Ġthe Ġcleanup Ġwas Ġsuccessful . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠThe Ġreturned Ġ[ DataProvider ] Ġhas Ġthe Ġsame Ġlifecycle Ġconsider ations Ġas Ġthe Ġprovider Ġreturned Ġby ĊĠĠ Ġ* Ġ[ submit Answer ] Ġwith Ġone Ġadditional Ġcave at : Ġthis Ġmethod Ġdoes Ġnot Ġactually Ġneed Ġto Ġbe Ġcalled Ġwhen ĊĠĠ Ġ* Ġa Ġsession Ġis Ġover . ĠCalling Ġit Ġensures Ġall Ġother Ġ[ DataProvider ] s Ġreset Ġto Ġa Ġcorrect ĊĠĠ Ġ* Ġout - of - session Ġstate , Ġbut Ġsubsequent Ġcalls Ġto Ġ[ begin Ex ploration Async ] Ġwill Ġreset Ġthe Ġsession . ĊĠĠ Ġ*/ ĊĠ Ġinternal Ġfun Ġfinish Ex ploration Async (): ĠData Provider < Any ?> Ġ{ ĊĠĠĠ Ġval Ġfinish Ex ploration Result Flow Ġ= Ġcreate AsyncResult State Flow < Any ?> () ĊĠĠĠ Ġval Ġmessage Ġ= ĠController Message . Finish Ex ploration ( active SessionId , Ġfinish Ex ploration Result Flow ) ĊĠĠĠ Ġsend Command For Operation ( message ) Ġ{ ĊĠĠĠĠĠ Ġ" Failed Ġto Ġschedule Ġcommand Ġfor Ġcleaning Ġup Ġafter Ġfinish ing Ġthe Ġexploration ." ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġfinish Ex ploration Result Flow . convertTo Session Provider ( ĊĠĠĠĠĠ ĠFIN ISH _ EX PL OR ATION _ RESULT _ PROVIDER _ ID ĊĠĠĠ Ġ) ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠSubmit s Ġan Ġanswer Ġto Ġthe Ġcurrent Ġstate Ġand Ġreturns Ġhow Ġthe ĠUI Ġshould Ġrespond Ġto Ġthis Ġanswer . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠIf Ġthe Ġapp Ġunder go es Ġa Ġconfiguration Ġchange , Ġcalling Ġcode Ġshould Ġrely Ġon Ġthe Ġ[ DataProvider ] ĊĠĠ Ġ* Ġfrom Ġ[ getCurrent State ] Ġto Ġknow Ġwhether Ġa Ġcurrent Ġanswer Ġis Ġpending . ĠThat Ġ[ DataProvider ] Ġwill ĊĠĠ Ġ* Ġhave Ġits Ġstate Ġchanged Ġto Ġpending Ġduring Ġanswer Ġsubmission Ġand Ġuntil Ġanswer Ġresolution . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠSubmit ting Ġan Ġanswer Ġshould Ġresult Ġin Ġthe Ġle arner Ġstay ing Ġin Ġthe Ġcurrent Ġstate , Ġmoving Ġto Ġa Ġnew ĊĠĠ Ġ* Ġstate Ġin Ġthe Ġexploration , Ġbeing Ġshown Ġa Ġconcept Ġcard , Ġor Ġbeing Ġnavig ated Ġto Ġanother Ġexploration ĊĠĠ Ġ* Ġal together . ĠNote Ġthat Ġonce Ġa Ġcorrect Ġanswer Ġis Ġprocessed , Ġthe Ġcurrent Ġstate Ġreported Ġto ĊĠĠ Ġ* Ġ[ getCurrent State ] Ġwill Ġchange Ġfrom Ġa Ġpending Ġstate Ġto Ġa Ġcompleted Ġstate Ġsince Ġthe Ġle arner ĊĠĠ Ġ* Ġcompleted Ġthat Ġcard . ĠThe Ġle arner Ġcan Ġthen Ġproceed Ġfrom Ġthe Ġcurrent Ġcompleted Ġstate Ġto Ġthe Ġnext ĊĠĠ Ġ* Ġpending Ġstate Ġusing Ġ[ moveTo Next State ]. ĊĠĠ Ġ* ĊĠĠ Ġ* Ġ### ĠLifecycle Ġbehavior ĊĠĠ Ġ* ĠThe Ġreturned Ġ[ DataProvider ] Ġwill Ġinitially Ġbe Ġpending Ġuntil Ġthe Ġoperation Ġcompletes Ġ( unless ĊĠĠ Ġ* Ġcalled Ġbefore Ġa Ġsession Ġis Ġstarted ). ĠNote Ġthat Ġa Ġdifferent Ġprovider Ġis Ġreturned Ġfor Ġeach Ġcall , ĊĠĠ Ġ* Ġthough Ġit 's Ġtied Ġto Ġthe Ġsame Ġsession Ġso Ġit Ġcan Ġbe Ġmon itored Ġmedium - term Ġ( i . e . Ġfor Ġthe Ġduration ĊĠĠ Ġ* Ġof Ġthe Ġplay Ġsession , Ġbut Ġnot Ġpast Ġit ). ĠFurthermore , Ġthe Ġreturned Ġprovider Ġdoes Ġnot Ġactually ĊĠĠ Ġ* Ġneed Ġto Ġbe Ġmon itored Ġin Ġorder Ġfor Ġthe Ġoperation Ġto Ġcomplete , Ġthough Ġit 's Ġrecommended Ġsince ĊĠĠ Ġ* Ġ[ getCurrent State ] Ġcan Ġonly Ġbe Ġused Ġto Ġmonitor Ġthe Ġeffects Ġof Ġthe Ġoperation , Ġnot Ġwhether Ġthe ĊĠĠ Ġ* Ġoperation Ġitself Ġsucceeded . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠIf Ġthis Ġis Ġcalled Ġbefore Ġa Ġsession Ġbegins Ġit Ġwill Ġreturn Ġa Ġprovider Ġthat Ġstays Ġfailing Ġwith Ġno ĊĠĠ Ġ* Ġupdates . ĠThe Ġoperation Ġwill Ġalso Ġsilently Ġfail Ġrather Ġthan Ġqueue Ġup Ġin Ġthese Ġcircumstances , Ġso ĊĠĠ Ġ* Ġstarting Ġa Ġsession Ġwill Ġnot Ġtrigger Ġan Ġanswer Ġsubmission Ġfrom Ġan Ġolder Ġcall . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠMultiple Ġsubsequent Ġcalls Ġduring Ġa Ġvalid Ġsession Ġwill Ġqueue Ġup Ġand Ġhave Ġresults Ġdelivered Ġin ĊĠĠ Ġ* Ġorder Ġ( though Ġbased Ġon Ġthe Ġevent ual Ġconsistency Ġnature Ġof Ġ[ DataProvider ] s Ġno Ġassumptions Ġcan Ġbe ĊĠĠ Ġ* Ġmade Ġabout Ġwhether Ġall Ġresults Ġwill Ġactually Ġbe Ġreceived -- [ getCurrent State ] Ġshould Ġbe Ġused Ġas ĊĠĠ Ġ* Ġthe Ġsource Ġof Ġtruth Ġfor Ġthe Ġcurrent Ġstate Ġof Ġthe Ġsession ). ĊĠĠ Ġ* ĊĠĠ Ġ* ĠNo Ġassumptions Ġshould Ġbe Ġmade Ġabout Ġthe Ġcompletion Ġorder Ġof Ġthe Ġreturned Ġ[ DataProvider ] Ġvs . Ġthe ĊĠĠ Ġ* Ġ[ DataProvider ] Ġfrom Ġ[ getCurrent State ]. ĊĠĠ Ġ*/ ĊĠ Ġfun Ġsubmit Answer ( user Answer : ĠUser Answer ): ĠData Provider < Answer Outcome > Ġ{ ĊĠĠĠ Ġval Ġsubmit Result Flow Ġ= Ġcreate AsyncResult State Flow < Answer Outcome >() ĊĠĠĠ Ġval Ġmessage Ġ= ĠController Message . Submit Answer ( user Answer , Ġactive SessionId , Ġsubmit Result Flow ) ĊĠĠĠ Ġsend Command For Operation ( message ) Ġ{ Ġ" Failed Ġto Ġschedule Ġcommand Ġfor Ġanswer Ġsubmission ." Ġ} ĊĠĠĠ Ġreturn Ġsubmit Result Flow . convertTo Session Provider ( SUBMIT _ AN SW ER _ RESULT _ PROVIDER _ ID ) ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠNot ifies Ġthe Ġcontroller Ġthat Ġthe Ġuser Ġw ishes Ġto Ġreveal Ġa Ġhint . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠThe Ġreturned Ġ[ DataProvider ] Ġhas Ġthe Ġsame Ġlifecycle Ġconsider ations Ġas Ġthe Ġprovider Ġreturned Ġby ĊĠĠ Ġ* Ġ[ submit Answer ]. ĊĠĠ Ġ* ĊĠĠ Ġ* Ġ@ param Ġhint Index Ġindex Ġof Ġthe Ġhint Ġthat Ġwas Ġreve aled Ġin Ġthe Ġhint Ġlist Ġof Ġthe Ġcurrent Ġpending ĊĠĠ Ġ* ĠĠĠĠ Ġstate ĊĠĠ Ġ* Ġ@ return Ġa Ġ[ DataProvider ] Ġthat Ġindicates Ġsuccess / failure Ġof Ġthe Ġoperation Ġ( the Ġactual Ġpayload Ġof ĊĠĠ Ġ* ĠĠĠĠ Ġthe Ġresult Ġisn 't Ġrelevant ) ĊĠĠ Ġ*/ ĊĠ Ġfun Ġsubmit Hint Is Re ve aled ( hint Index : ĠInt ): ĠData Provider < Any ?> Ġ{ ĊĠĠĠ Ġval Ġsubmit Result Flow Ġ= Ġcreate AsyncResult State Flow < Any ?> () ĊĠĠĠ Ġval Ġmessage Ġ= ĠController Message . Hint Is Re ve aled ( hint Index , Ġactive SessionId , Ġsubmit Result Flow ) ĊĠĠĠ Ġsend Command For Operation ( message ) Ġ{ ĊĠĠĠĠĠ Ġ" Failed Ġto Ġschedule Ġcommand Ġfor Ġreveal ing Ġhint : Ġ$ hint Index ." ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġsubmit Result Flow . convertTo Session Provider ( SUBMIT _ HINT _ RE VE AL ED _ RESULT _ PROVIDER _ ID ) ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠNot ifies Ġthe Ġcontroller Ġthat Ġthe Ġuser Ġhas Ġreve aled Ġthe Ġsolution Ġto Ġthe Ġcurrent Ġstate . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠThe Ġreturned Ġ[ DataProvider ] Ġhas Ġthe Ġsame Ġlifecycle Ġconsider ations Ġas Ġthe Ġprovider Ġreturned Ġby ĊĠĠ Ġ* Ġ[ submit Answer ]. ĊĠĠ Ġ* ĊĠĠ Ġ* Ġ@ return Ġa Ġ[ DataProvider ] Ġthat Ġindicates Ġsuccess / failure Ġof Ġthe Ġoperation Ġ( the Ġactual Ġpayload Ġof ĊĠĠ Ġ* ĠĠĠĠ Ġthe Ġresult Ġisn 't Ġrelevant ) ĊĠĠ Ġ*/ ĊĠ Ġfun Ġsubmit Solution Is Re ve aled (): ĠData Provider < Any ?> Ġ{ ĊĠĠĠ Ġval Ġsubmit Result Flow Ġ= Ġcreate AsyncResult State Flow < Any ?> () ĊĠĠĠ Ġval Ġmessage Ġ= ĠController Message . Solution Is Re ve aled ( active SessionId , Ġsubmit Result Flow ) ĊĠĠĠ Ġsend Command For Operation ( message ) Ġ{ Ġ" Failed Ġto Ġschedule Ġcommand Ġfor Ġreveal ing Ġthe Ġsolution ." Ġ} ĊĠĠĠ Ġreturn Ġsubmit Result Flow . convertTo Session Provider ( SUBMIT _ SOL UTION _ RE VE AL ED _ RESULT _ PROVIDER _ ID ) ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠNavig ates Ġto Ġthe Ġprevious Ġstate Ġin Ġthe Ġgraph . ĠIf Ġthe Ġle arner Ġis Ġcurrently Ġon Ġthe Ġinitial Ġstate , ĊĠĠ Ġ* Ġthis Ġmethod Ġwill Ġthrow Ġan Ġexception . ĠCalling Ġcode Ġis Ġresponsible Ġfor Ġensuring Ġthis Ġmethod Ġis ĊĠĠ Ġ* Ġonly Ġcalled Ġwhen Ġit 's Ġpossible Ġto Ġnavigate Ġbackward . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠThe Ġreturned Ġ[ DataProvider ] Ġhas Ġthe Ġsame Ġlifecycle Ġconsider ations Ġas Ġthe Ġprovider Ġreturned Ġby ĊĠĠ Ġ* Ġ[ submit Answer ]. ĊĠĠ Ġ* ĊĠĠ Ġ* Ġ@ return Ġa Ġ[ DataProvider ] Ġindicating Ġwhether Ġthe Ġmovement Ġto Ġthe Ġprevious Ġstate Ġwas Ġsuccessful , ĊĠĠ Ġ* ĠĠĠĠ Ġor Ġa Ġfailure Ġif Ġstate Ġnavigation Ġwas Ġattempted Ġat Ġan Ġinvalid Ġtime Ġin Ġthe Ġstate Ġgraph Ġ( e . g . ĊĠĠ Ġ* ĠĠĠĠ Ġif Ġcurrently Ġviewing Ġthe Ġinitial Ġstate Ġof Ġthe Ġexploration ). ĠIt 's Ġrecommended Ġthat Ġcalling ĊĠĠ Ġ* ĠĠĠĠ Ġcode Ġonly Ġlisten Ġto Ġthis Ġresult Ġfor Ġfailures , Ġand Ġinstead Ġrely Ġon Ġ[ getCurrent State ] Ġfor ĊĠĠ Ġ* ĠĠĠĠ Ġob serving Ġa Ġsuccessful Ġtransition Ġto Ġanother Ġstate . ĊĠĠ Ġ*/ ĊĠ Ġfun Ġmove To Previous State (): ĠData Provider < Any ?> Ġ{ ĊĠĠĠ Ġval Ġmove Result Flow Ġ= Ġcreate AsyncResult State Flow < Any ?> () ĊĠĠĠ Ġval Ġmessage Ġ= ĠController Message . MoveTo Previous State ( active SessionId , Ġmove Result Flow ) ĊĠĠĠ Ġsend Command For Operation ( message ) Ġ{ ĊĠĠĠĠĠ Ġ" Failed Ġto Ġschedule Ġcommand Ġfor Ġmoving Ġto Ġthe Ġprevious Ġstate ." ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġmove Result Flow . convertTo Session Provider ( MOVE _ TO _ PREVIOUS _ STATE _ RESULT _ PROVIDER _ ID ) ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠNavig ates Ġto Ġthe Ġnext Ġstate Ġin Ġthe Ġgraph . ĠThis Ġmethod Ġis Ġonly Ġvalid Ġif Ġthe Ġcurrent ĊĠĠ Ġ* Ġ[ Ep hemeral State ] Ġreported Ġby Ġ[ getCurrent State ] Ġis Ġa Ġcompleted Ġstate . ĠCalling Ġcode Ġis ĊĠĠ Ġ* Ġresponsible Ġfor Ġensuring Ġthis Ġmethod Ġis Ġonly Ġcalled Ġwhen Ġit 's Ġpossible Ġto Ġnavigate Ġforward . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠNote Ġthat Ġif Ġthe Ġcurrent Ġstate Ġis Ġa Ġpending Ġstate , Ġthe Ġuser Ġneeds Ġto Ġsubmit Ġa Ġcorrect Ġanswer ĊĠĠ Ġ* Ġthat Ġroutes Ġto Ġa Ġlater Ġstate Ġvia Ġ[ submit Answer ] Ġin Ġorder Ġfor Ġthe Ġcurrent Ġstate Ġto Ġchange Ġto Ġa ĊĠĠ Ġ* Ġcompleted Ġstate Ġbefore Ġforward Ġnavigation Ġcan Ġoccur . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠThe Ġreturned Ġ[ DataProvider ] Ġhas Ġthe Ġsame Ġlifecycle Ġconsider ations Ġas Ġthe Ġprovider Ġreturned Ġby ĊĠĠ Ġ* Ġ[ submit Answer ]. ĊĠĠ Ġ* ĊĠĠ Ġ* Ġ@ return Ġa Ġ[ DataProvider ] Ġindicating Ġwhether Ġthe Ġmovement Ġto Ġthe Ġnext Ġstate Ġwas Ġsuccessful Ġ( see ĊĠĠ Ġ* ĠĠĠĠ Ġ[ moveTo Previous State ] Ġfor Ġdetails Ġon Ġpotential Ġfailure Ġcases ) ĊĠĠ Ġ*/ ĊĠ Ġfun Ġmove To Next State (): ĠData Provider < Any ?> Ġ{ ĊĠĠĠ Ġval Ġmove Result Flow Ġ= Ġcreate AsyncResult State Flow < Any ?> () ĊĠĠĠ Ġval Ġmessage Ġ= ĠController Message . MoveTo Next State ( active SessionId , Ġmove Result Flow ) ĊĠĠĠ Ġsend Command For Operation ( message ) Ġ{ Ġ" Failed Ġto Ġschedule Ġcommand Ġfor Ġmoving Ġto Ġthe Ġnext Ġstate ." Ġ} ĊĠĠĠ Ġreturn Ġmove Result Flow . convertTo Session Provider ( MOVE _ TO _ NEXT _ STATE _ RESULT _ PROVIDER _ ID ) ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠReturns Ġa Ġ[ DataProvider ] Ġmonitoring Ġthe Ġcurrent Ġ[ Ep hemeral State ] Ġthe Ġle arner Ġis Ġcurrently ĊĠĠ Ġ* Ġviewing . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠIf Ġthis Ġstate Ġcorresponds Ġto Ġa Ġa Ġterminal Ġstate , Ġthen Ġthe Ġle arner Ġhas Ġcompleted Ġthe ĊĠĠ Ġ* Ġexploration . ĠNote Ġthat Ġ[ moveTo Previous State ] Ġand Ġ[ moveTo Next State ] Ġwill Ġautomatically Ġupdate ĊĠĠ Ġ* Ġob servers Ġof Ġthis Ġdata Ġprovider Ġwhen Ġthe Ġnext Ġstate Ġis Ġnavig ated Ġto . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠThis Ġ[ DataProvider ] Ġmay Ġinitially Ġbe Ġpending Ġwhile Ġthe Ġexploration Ġobject Ġis Ġloaded . ĠIt Ġmay ĊĠĠ Ġ* Ġalso Ġswitch Ġfrom Ġa Ġcompleted Ġto Ġa Ġpending Ġresult Ġduring Ġtransient Ġoperations Ġlike Ġsubmitting Ġan ĊĠĠ Ġ* Ġanswer Ġvia Ġ[ submit Answer ]. ĠCalling Ġcode Ġshould Ġbe Ġmade Ġres il ient Ġto Ġthis Ġby Ġcaching Ġthe Ġcurrent ĊĠĠ Ġ* Ġstate Ġobject Ġto Ġdisplay Ġsince Ġit Ġmay Ġdis appear Ġtemporarily Ġduring Ġanswer Ġsubmission . ĠCalling ĊĠĠ Ġ* Ġcode Ġshould Ġpersist Ġthis Ġstate Ġobject Ġacross Ġconfiguration Ġchanges Ġif Ġneeded Ġsince Ġit Ġcannot ĊĠĠ Ġ* Ġrely Ġon Ġthis Ġ[ DataProvider ] Ġfor Ġimmediate Ġstate Ġre const itution Ġafter Ġconfiguration Ġchanges . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠThe Ġunderlying Ġstate Ġreturned Ġby Ġthis Ġfunction Ġcan Ġonly Ġbe Ġchanged Ġby Ġcalls Ġto ĊĠĠ Ġ* Ġ[ moveTo Next State ] Ġand Ġ[ moveTo Previous State ], Ġor Ġthe Ġexploration Ġdata Ġcontroller Ġif Ġanother ĊĠĠ Ġ* Ġexploration Ġis Ġloaded . ĠUI Ġcode Ġcannot Ġassume Ġthat Ġonly Ġcalls Ġfrom Ġthe ĠUI Ġlayer Ġwill Ġtrigger ĊĠĠ Ġ* Ġstate Ġchanges Ġhere Ġsince Ġinternal Ġdomain Ġprocesses Ġmay Ġalso Ġaffect Ġstate Ġ( such Ġas Ġhint Ġtimers ). ĊĠĠ Ġ* ĊĠĠ Ġ* ĠThis Ġmethod Ġis Ġsafe Ġto Ġbe Ġcalled Ġbefore Ġthe Ġexploration Ġhas Ġstarted , Ġbut Ġthe Ġreturned Ġprovider ĊĠĠ Ġ* Ġis Ġtied Ġto Ġthe Ġcurrent Ġplay Ġsession Ġ( similar Ġto Ġthe Ġprovider Ġreturned Ġby Ġ[ submit Answer ]), Ġso ĊĠĠ Ġ* Ġthe Ġreturned Ġ[ DataProvider ] Ġprior Ġto Ġ[ begin Ex ploration Async ] Ġbeing Ġcalled Ġwill Ġbe Ġa Ġper manently ĊĠĠ Ġ* Ġfailing Ġprovider . ĠFurthermore , Ġthe Ġreturned Ġprovider Ġwill Ġnot Ġbe Ġupdated Ġafter Ġthe Ġplay Ġsession ĊĠĠ Ġ* Ġhas Ġended Ġ( either Ġdue Ġto Ġ[ finish Ex ploration Async ] Ġbeing Ġcalled , Ġor Ġa Ġnew Ġsession Ġstarting ). ĊĠĠ Ġ* ĠThere Ġwill Ġbe Ġa Ġ[ DataProvider ] Ġavailable Ġimmediately Ġafter Ġ[ begin Ex ploration Async ] Ġreturns , ĊĠĠ Ġ* Ġthough Ġit Ġmay Ġnot Ġever Ġprovide Ġuseful Ġdata Ġif Ġthe Ġstart Ġof Ġthe Ġsession Ġfailed Ġ( which Ġcan Ġonly ĊĠĠ Ġ* Ġbe Ġobserved Ġvia Ġthe Ġprovider Ġreturned Ġby Ġ[ begin Ex ploration Async ]). ĊĠĠ Ġ* ĊĠĠ Ġ* ĠThis Ġmethod Ġdoes Ġnot Ġactually Ġneed Ġto Ġbe Ġcalled Ġfor Ġthe Ġ[ Ep hemeral State ] Ġto Ġbe Ġcomputed ; Ġit 's ĊĠĠ Ġ* Ġalways Ġcomputed Ġeager ly Ġby Ġother Ġstate - changing Ġmethods Ġregardless Ġof Ġwhether Ġthere 's Ġan Ġactive ĊĠĠ Ġ* Ġsubscription Ġto Ġthis Ġmethod 's Ġreturned Ġ[ DataProvider ]. ĊĠĠ Ġ*/ ĊĠ Ġfun ĠgetCurrent State (): ĠData Provider < Ep hemeral State > Ġ{ ĊĠĠĠ Ġval Ġwritten Translation Content Locale Ġ= ĊĠĠĠĠĠ Ġtranslation Controller . get Written Translation Content Locale ( profile Id ) ĊĠĠĠ Ġval Ġep hemeral State DataProvider Ġ= ĊĠĠĠĠĠ Ġmost Recent Ep hemeral State Flow . convertTo Session Provider ( CURRENT _ STATE _ PROVIDER _ ID ) ĊĠĠĠ Ġreturn Ġwritten Translation Content Locale . combine With ( ĊĠĠĠĠĠ Ġep hemeral State DataProvider , ĠLOCAL IZED _ STATE _ PROVIDER _ ID ĊĠĠĠ Ġ) Ġ{ Ġlocale , Ġep hemeral State Ġ-> ĊĠĠĠĠĠ Ġep hemeral State . to Builder (). apply Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠAug ment Ġthe Ġstate Ġto Ġinclude Ġtranslation Ġinformation Ġ( which Ġmay Ġnot Ġnecessarily Ġbe ĊĠĠĠĠĠĠĠ Ġ// Ġup - to - date Ġin Ġthe Ġstate Ġdeck ). ĊĠĠĠĠĠĠĠ Ġwritten Translation Context Ġ= ĊĠĠĠĠĠĠĠĠĠ Ġtranslation Controller . compute Written Translation Context ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate . written Translations Map , Ġlocale ĊĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠ Ġ}. build () ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġcreate Controller Command Actor (): ĠSend Channel < Controller Message <* >> Ġ{ ĊĠĠĠ Ġlateinit Ġvar Ġcontroller State : ĠController State ĊĠĠĠ Ġ// ĠUse Ġan Ġun limited Ġcapacity Ġbuffer Ġso Ġthat Ġcommands Ġcan Ġbe Ġsent Ġasynchronously Ġwithout Ġblocking ĊĠĠĠ Ġ// Ġthe Ġmain Ġthread Ġor Ġscheduling Ġan Ġextra Ġcoroutine . ĊĠĠĠ Ġ@ Suppress (" Join Declaration And Assignment ") Ġ// ĠWarning Ġis Ġincorrect Ġin Ġthis Ġcase . ĊĠĠĠ Ġlateinit Ġvar Ġcommand Queue : ĠSend Channel < Controller Message <* >> ĊĠĠĠ Ġcommand Queue Ġ= ĠCor outine Scope ( ĊĠĠĠĠĠ Ġbackground Coroutine Dispatcher ĊĠĠĠ Ġ). actor ( capacity Ġ= ĠChannel . UN LIMIT ED ) Ġ{ ĊĠĠĠĠĠ Ġfor Ġ( message Ġin Ġchannel ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ@ Suppress (" UNUSED _ VARIABLE ") Ġ// ĠA Ġvariable Ġis Ġused Ġto Ġcreate Ġan Ġex haustive Ġwhen Ġstatement . ĊĠĠĠĠĠĠĠĠĠ Ġval Ġunused Ġ= Ġwhen Ġ( message ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠController Message . Initialize Controller Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠEnsure Ġthe Ġstate Ġis Ġcompletely Ġre created Ġfor Ġeach Ġsession Ġto Ġavoid Ġle aking Ġstate ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġacross Ġsessions . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller State Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠController State ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEx ploration Progress (), Ġmessage . sessionId , Ġmessage . ep hemeral State Flow , Ġcommand Queue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ). also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . begin Ex ploration Impl ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . callback Flow , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . profile Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . topic Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . story Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . ex ploration Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . should Save Partial Progress , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . ex ploration Checkpoint ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠController Message . Finish Ex ploration Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠEnsure Ġfinish Ġis Ġalways Ġexecuted Ġeven Ġif Ġthe Ġcontroller Ġstate Ġisn 't Ġyet ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġinitialized . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller State . finish Ex ploration Impl ( message . callback Flow ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠEnsure Ġthe Ġactor Ġends Ġsince Ġthe Ġsession Ġrequires Ġno Ġfurther Ġmessage Ġprocessing . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠController Message . Submit Answer Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller State . submit Answer Impl ( message . callback Flow , Ġmessage . user Answer ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠController Message . Hint Is Re ve aled Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller State . submit Hint Is Re ve aled Impl ( message . callback Flow , Ġmessage . hint Index ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠController Message . Solution Is Re ve aled Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller State . submit Solution Is Re ve aled Impl ( message . callback Flow ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠController Message . MoveTo Previous State Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller State . moveTo Previous State Impl ( message . callback Flow ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠController Message . MoveTo Next State Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller State . moveTo Next State Impl ( message . callback Flow ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠController Message . Process Saved Checkpoint Result Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller State . process Save Checkpoint Result ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . profile Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . topic Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . story Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . ex ploration Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . last Play ed Timestamp , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . new Checkpoint State ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠController Message . Save Checkpoint Ġ-> Ġcontroller State . save Ex ploration Checkpoint () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠController Message . Re compute State And Notify Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller State . re compute Current State And Notify Impl () ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġexceptions Controller . log Non Fatal Exception ( e ) ĊĠĠĠĠĠĠĠĠĠ Ġopp ia Logger . w ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Ex ploration Progress Controller ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Encounter ed Ġexception Ġwhile Ġprocessing Ġcommand : Ġ$ message ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe ĊĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġcommand Queue ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġ< T > Ġsend Command For Operation ( ĊĠĠĠ Ġmessage : ĠController Message < T >, ĊĠĠĠ Ġlazy Failure Message : Ġ() Ġ-> ĠString ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġ// ĠTODO (# 4 1 1 9 ): ĠSwitch Ġthis Ġto Ġuse Ġtry Send (), Ġinstead , Ġwhich Ġis Ġmuch Ġcleaner Ġand Ġdoesn 't Ġrequire ĊĠĠĠ Ġ// Ġ Ġcatch ing Ġan Ġexception . ĊĠĠĠ Ġval Ġflow Result : ĠAsync Result < T > Ġ= Ġtry Ġ{ ĊĠĠĠĠĠ Ġval Ġcommand Queue Ġ= Ġmost Recent Command Queue ĊĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġcommand Queue Ġ== Ġnull Ġ-> ĊĠĠĠĠĠĠĠĠĠ ĠAsync Result . Failure ( IllegalStateException (" Session Ġisn 't Ġinitialized Ġyet .")) ĊĠĠĠĠĠĠĠ Ġ! command Queue . offer ( message ) Ġ-> ĊĠĠĠĠĠĠĠĠĠ ĠAsync Result . Failure ( IllegalStateException ( lazy Failure Message ())) ĊĠĠĠĠĠĠĠ Ġ// ĠEnsure Ġthat Ġthe Ġresult Ġis Ġfirst Ġreset Ġsince Ġthere Ġwill Ġbe Ġa Ġdelay Ġbefore Ġthe Ġmessage Ġis ĊĠĠĠĠĠĠĠ Ġ// Ġprocessed Ġ( if Ġthere 's Ġa Ġflow ). ĊĠĠĠĠĠĠĠ Ġelse Ġ-> ĠAsync Result . Pending () ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĠAsync Result . Failure ( e ) Ġ} ĊĊĠĠĠ Ġ// ĠThis Ġmust Ġbe Ġassigned Ġseparately Ġsince Ġflow Result Ġshould Ġalways Ġbe Ġcalculated , Ġeven Ġif ĊĠĠĠ Ġ// Ġthere 's Ġno Ġcallback Flow Ġto Ġreport Ġit . ĊĠĠĠ Ġmessage . callback Flow ?. value Ġ= Ġflow Result ĊĠ Ġ} ĊĊĠ Ġprivate Ġsuspend Ġfun ĠController State . begin Ex ploration Impl ( ĊĠĠĠ Ġbegin Ex ploration Result Flow : ĠMutable State Flow < AsyncResult < Any ? >>, ĊĠĠĠ Ġprofile Id : ĠProfile Id , ĊĠĠĠ Ġtopic Id : ĠString , ĊĠĠĠ Ġstory Id : ĠString , ĊĠĠĠ Ġexploration Id : ĠString , ĊĠĠĠ Ġshould Save Partial Progress : ĠBoolean , ĊĠĠĠ Ġexploration Checkpoint : ĠEx ploration Checkpoint ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġtry Operation ( begin Ex ploration Result Flow ) Ġ{ ĊĠĠĠĠĠ Ġcheck ( ex ploration Progress . play Stage Ġ== ĠNOT _ PLAY ING ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Expected Ġto Ġfinish Ġprevious Ġexploration Ġbefore Ġstarting Ġa Ġnew Ġone ." ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġexploration Progress . apply Ġ{ ĊĠĠĠĠĠĠĠ Ġcurrent Profile Id Ġ= Ġprofile Id ĊĠĠĠĠĠĠĠ Ġcurrent Topic Id Ġ= Ġtopic Id ĊĠĠĠĠĠĠĠ Ġcurrent Story Id Ġ= Ġstory Id ĊĠĠĠĠĠĠĠ Ġcurrent Ex ploration Id Ġ= Ġexploration Id ĊĠĠĠĠĠĠĠ Ġthis . should Save Partial Progress Ġ= Ġshould Save Partial Progress ĊĠĠĠĠĠĠĠ Ġcheckpoint State Ġ= ĠCheck point State . CHECK POINT _ UN SA VED ĊĠĠĠĠĠĠĠ Ġthis . ex ploration Checkpoint Ġ= Ġexploration Checkpoint ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġhint Handler Ġ= Ġhint Handler Factory . create () ĊĠĠĠĠĠ Ġhint Handler . getCurrent Help Index (). on Each Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠFire Ġan Ġevent Ġto Ġsave Ġthe Ġlatest Ġprogress Ġstate Ġin Ġa Ġcheckpoint Ġto Ġavoid Ġcross - thread ĊĠĠĠĠĠĠĠ Ġ// Ġsynchronization Ġbeing Ġrequired Ġ( since Ġthe Ġstate Ġof Ġhints / solutions Ġhas Ġchanged ). ĊĠĠĠĠĠĠĠ Ġcommand Queue . send ( Controller Message . Save Checkpoint ( sessionId )) ĊĠĠĠĠĠĠĠ Ġre compute Current State And Notify Async () ĊĠĠĠĠĠ Ġ}. launch In ( Coroutine Scope ( background Coroutine Dispatcher )) ĊĠĠĠĠĠ Ġexploration Progress . advance Play Stage To ( LOADING _ EX PL OR ATION ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġsuspend Ġfun ĠController State ?. finish Ex ploration Impl ( ĊĠĠĠ Ġfinish Ex ploration Result Flow : ĠMutable State Flow < AsyncResult < Any ? >> ĊĠ Ġ) Ġ{ ĊĠĠĠ ĠcheckNotNull ( this ) Ġ{ Ġ" Cannot Ġfinish Ġplaying Ġan Ġexploration Ġthat Ġhasn 't Ġyet Ġbeen Ġstarted " Ġ} ĊĠĠĠ Ġtry Operation ( finish Ex ploration Result Flow , Ġre compute State Ġ= Ġfalse ) Ġ{ ĊĠĠĠĠĠ Ġexploration Progress . advance Play Stage To ( NOT _ PLAY ING ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġsuspend Ġfun ĠController State . submit Answer Impl ( ĊĠĠĠ Ġsubmit Answer Result Flow : ĠMutable State Flow < AsyncResult < Answer Outcome >>, ĊĠĠĠ Ġuser Answer : ĠUser Answer ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġtry Operation ( submit Answer Result Flow ) Ġ{ ĊĠĠĠĠĠ Ġcheck ( ex ploration Progress . play Stage Ġ!= ĠNOT _ PLAY ING ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Cannot Ġsubmit Ġan Ġanswer Ġif Ġan Ġexploration Ġis Ġnot Ġbeing Ġplayed ." ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġcheck ( ex ploration Progress . play Stage Ġ!= ĠLO ADING _ EX PL OR ATION ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Cannot Ġsubmit Ġan Ġanswer Ġwhile Ġthe Ġexploration Ġis Ġbeing Ġloaded ." ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġcheck ( ex ploration Progress . play Stage Ġ!= ĠSUB MIT TING _ AN SW ER ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Cannot Ġsubmit Ġan Ġanswer Ġwhile Ġanother Ġanswer Ġis Ġpending ." ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġ// ĠNotify Ġob servers Ġthat Ġthe Ġsubmitted Ġanswer Ġis Ġcurrently Ġpending . ĊĠĠĠĠĠ Ġexploration Progress . advance Play Stage To ( SUBMIT TING _ AN SW ER ) ĊĠĠĠĠĠ Ġre compute Current State And Notify Sync () ĊĊĠĠĠĠĠ Ġvar Ġanswer Outcome : ĠAnswer Outcome ? Ġ= Ġnull ĊĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtop Pending State Ġ= Ġexploration Progress . state Deck . get Pending Top State () ĊĠĠĠĠĠĠĠ Ġval Ġoutcome Ġ= ĊĠĠĠĠĠĠĠĠĠ Ġanswer Classification Controller . classify ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtop Pending State . interaction , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġuser Answer . answer , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġuser Answer . written Translation Context ĊĠĠĠĠĠĠĠĠĠ Ġ). outcome ĊĠĠĠĠĠĠĠ Ġanswer Outcome Ġ= ĊĠĠĠĠĠĠĠĠĠ Ġexploration Progress . state Graph . compute Answer Outcome For Result ( top Pending State , Ġoutcome ) ĊĠĠĠĠĠĠĠ Ġexploration Progress . state Deck . submit Answer ( ĊĠĠĠĠĠĠĠĠĠ Ġuser Answer , Ġanswer Outcome . feedback , Ġanswer Outcome . labelled As Correct Answer ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠFollow Ġthe Ġanswer 's Ġoutcome Ġto Ġanother Ġpart Ġof Ġthe Ġgraph Ġif Ġit 's Ġdifferent . ĊĠĠĠĠĠĠĠ Ġval Ġep hemeral State Ġ= Ġcompute Base Current Ep hemeral State () ĊĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġanswer Outcome . destination Case Ġ== ĠAnswer Outcome . Destination Case . STATE _ NAME Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠnewState Ġ= Ġexploration Progress . state Graph . getState ( answer Outcome . state Name ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexploration Progress . state Deck . push State ( newState , Ġpro hibit Same State Name Ġ= Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhint Handler . finish State ( newState ) ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġep hemeral State . state Type Case Ġ== ĠEp hemeral State . State Type Case . PENDING _ STATE Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSchedule , Ġor Ġshow Ġimmediately , Ġa Ġnew Ġhint Ġor Ġsolution Ġbased Ġon Ġthe Ġcurrent ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġep hemeral Ġstate Ġof Ġthe Ġexploration Ġbecause Ġa Ġnew Ġwrong Ġanswer Ġwas Ġsubmitted . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhint Handler . handle Wrong Answer Submission ( ep hemeral State . pending State . wrong Answer Count ) ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( answer Outcome Ġ!= Ġnull Ġ&& ĊĠĠĠĠĠĠĠĠĠ Ġ! does Interaction Auto Continue ( answer Outcome . state . interaction . id ) ĊĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġthe Ġanswer Ġwas Ġnot Ġsubmitted Ġon Ġbehalf Ġof Ġthe ĠContinue Ġinteraction , Ġupdate Ġthe ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġhint Ġstate Ġand Ġsave Ġcheckpoint Ġbecause Ġit Ġwill Ġbe Ġsaved Ġwhen Ġthe Ġle arner Ġmoves Ġto Ġthe ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġnext Ġstate . ĊĠĠĠĠĠĠĠĠĠ Ġsave Ex ploration Checkpoint () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠEnsure Ġthat Ġthe Ġuser Ġalways Ġreturns Ġto Ġthe ĠVIEW ING _ STATE Ġstage Ġto Ġavoid Ġgetting Ġstuck ĊĠĠĠĠĠĠĠ Ġ// Ġin Ġan Ġ' always Ġsubmitting Ġanswer ' Ġsituation . ĠThis Ġcan Ġspecifically Ġhappen Ġif Ġanswer ĊĠĠĠĠĠĠĠ Ġ// Ġclassification Ġthrows Ġan Ġexception . ĊĠĠĠĠĠĠĠ Ġexploration Progress . advance Play Stage To ( VIEW ING _ STATE ) ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġreturn @ try Operation ĠcheckNotNull ( answer Outcome ) Ġ{ Ġ" Expected Ġanswer Ġoutcome ." Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġsuspend Ġfun ĠController State . submit Hint Is Re ve aled Impl ( ĊĠĠĠ Ġsubmit Hint Re ve aled Result Flow : ĠMutable State Flow < AsyncResult < Any ? >>, ĊĠĠĠ Ġhint Index : ĠInt ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġtry Operation ( submit Hint Re ve aled Result Flow ) Ġ{ ĊĠĠĠĠĠ Ġcheck ( ex ploration Progress . play Stage Ġ!= ĠNOT _ PLAY ING ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Cannot Ġsubmit Ġan Ġanswer Ġif Ġan Ġexploration Ġis Ġnot Ġbeing Ġplayed ." ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġcheck ( ex ploration Progress . play Stage Ġ!= ĠLO ADING _ EX PL OR ATION ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Cannot Ġsubmit Ġan Ġanswer Ġwhile Ġthe Ġexploration Ġis Ġbeing Ġloaded ." ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġcheck ( ex ploration Progress . play Stage Ġ!= ĠSUB MIT TING _ AN SW ER ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Cannot Ġsubmit Ġan Ġanswer Ġwhile Ġanother Ġanswer Ġis Ġpending ." ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġhint Handler . view Hint ( hint Index ) ĊĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠEnsure Ġthat Ġthe Ġuser Ġalways Ġreturns Ġto Ġthe ĠVIEW ING _ STATE Ġstage Ġto Ġavoid Ġgetting Ġstuck ĊĠĠĠĠĠĠĠ Ġ// Ġin Ġan Ġ' always Ġshowing Ġhint ' Ġsituation . ĠThis Ġcan Ġspecifically Ġhappen Ġif Ġhint Ġthrows Ġan ĊĠĠĠĠĠĠĠ Ġ// Ġexception . ĊĠĠĠĠĠĠĠ Ġexploration Progress . advance Play Stage To ( VIEW ING _ STATE ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġsuspend Ġfun ĠController State . submit Solution Is Re ve aled Impl ( ĊĠĠĠ Ġsubmit Solution Re ve aled Result Flow : ĠMutable State Flow < AsyncResult < Any ? >> ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġtry Operation ( submit Solution Re ve aled Result Flow ) Ġ{ ĊĠĠĠĠĠ Ġcheck ( ex ploration Progress . play Stage Ġ!= ĠNOT _ PLAY ING ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Cannot Ġsubmit Ġan Ġanswer Ġif Ġan Ġexploration Ġis Ġnot Ġbeing Ġplayed ." ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġcheck ( ex ploration Progress . play Stage Ġ!= ĠLO ADING _ EX PL OR ATION ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Cannot Ġsubmit Ġan Ġanswer Ġwhile Ġthe Ġexploration Ġis Ġbeing Ġloaded ." ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġcheck ( ex ploration Progress . play Stage Ġ!= ĠSUB MIT TING _ AN SW ER ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Cannot Ġsubmit Ġan Ġanswer Ġwhile Ġanother Ġanswer Ġis Ġpending ." ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġhint Handler . view Solution () ĊĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠEnsure Ġthat Ġthe Ġuser Ġalways Ġreturns Ġto Ġthe ĠVIEW ING _ STATE Ġstage Ġto Ġavoid Ġgetting Ġstuck ĊĠĠĠĠĠĠĠ Ġ// Ġin Ġan Ġ' always Ġshowing Ġsolution ' Ġsituation . ĠThis Ġcan Ġspecifically Ġhappen Ġif Ġsolution ĊĠĠĠĠĠĠĠ Ġ// Ġthrows Ġan Ġexception . ĊĠĠĠĠĠĠĠ Ġexploration Progress . advance Play Stage To ( VIEW ING _ STATE ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġsuspend Ġfun ĠController State . moveTo Previous State Impl ( ĊĠĠĠ Ġmove To Previous State Result Flow : ĠMutable State Flow < AsyncResult < Any ? >> ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġtry Operation ( moveTo Previous State Result Flow ) Ġ{ ĊĠĠĠĠĠ Ġcheck ( ex ploration Progress . play Stage Ġ!= ĠNOT _ PLAY ING ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Cannot Ġnavigate Ġto Ġa Ġprevious Ġstate Ġif Ġan Ġexploration Ġis Ġnot Ġbeing Ġplayed ." ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġcheck ( ex ploration Progress . play Stage Ġ!= ĠLO ADING _ EX PL OR ATION ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Cannot Ġnavigate Ġto Ġa Ġprevious Ġstate Ġif Ġan Ġexploration Ġis Ġbeing Ġloaded ." ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġcheck ( ex ploration Progress . play Stage Ġ!= ĠSUB MIT TING _ AN SW ER ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Cannot Ġnavigate Ġto Ġa Ġprevious Ġstate Ġif Ġan Ġanswer Ġsubmission Ġis Ġpending ." ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġhint Handler . navigate To Previous State () ĊĠĠĠĠĠ Ġexploration Progress . state Deck . navigate To Previous State () ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġsuspend Ġfun ĠController State . moveTo Next State Impl ( ĊĠĠĠ Ġmove To Next State Result Flow : ĠMutable State Flow < AsyncResult < Any ? >> ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġtry Operation ( moveTo Next State Result Flow ) Ġ{ ĊĠĠĠĠĠ Ġcheck ( ex ploration Progress . play Stage Ġ!= ĠNOT _ PLAY ING ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Cannot Ġnavigate Ġto Ġa Ġnext Ġstate Ġif Ġan Ġexploration Ġis Ġnot Ġbeing Ġplayed ." ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġcheck ( ex ploration Progress . play Stage Ġ!= ĠLO ADING _ EX PL OR ATION ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Cannot Ġnavigate Ġto Ġa Ġnext Ġstate Ġif Ġan Ġexploration Ġis Ġbeing Ġloaded ." ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġcheck ( ex ploration Progress . play Stage Ġ!= ĠSUB MIT TING _ AN SW ER ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Cannot Ġnavigate Ġto Ġa Ġnext Ġstate Ġif Ġan Ġanswer Ġsubmission Ġis Ġpending ." ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġexploration Progress . state Deck . navigate To Next State () ĊĊĠĠĠĠĠ Ġif Ġ( ex ploration Progress . state Deck . is Current State Top Of Deck ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġhint Handler . navigate Back To Latest Pending State () ĊĊĠĠĠĠĠĠĠ Ġ// ĠOnly Ġmark Ġcheckpoint Ġif Ġcurrent Ġstate Ġis Ġpending Ġstate . ĠThis Ġensures Ġthat Ġcheck points ĊĠĠĠĠĠĠĠ Ġ// Ġwill Ġnot Ġbe Ġmarked Ġon Ġany Ġof Ġthe Ġcompleted Ġstates . ĊĠĠĠĠĠĠĠ Ġsave Ex ploration Checkpoint () ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġsuspend Ġfun Ġ< T > ĠController State . try Operation ( ĊĠĠĠ Ġresult Flow : ĠMutable State Flow < AsyncResult < T >>, ĊĠĠĠ Ġre compute State : ĠBoolean Ġ= Ġtrue , ĊĠĠĠ Ġoperation : Ġsuspend ĠController State . () Ġ-> ĠT ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠ Ġresult Flow . emit ( AsyncResult . Success ( operation ())) ĊĠĠĠĠĠ Ġif Ġ( re compute State ) Ġ{ ĊĠĠĠĠĠĠĠ Ġre compute Current State And Notify Sync () ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠ Ġexceptions Controller . log Non Fatal Exception ( e ) ĊĠĠĠĠĠ Ġresult Flow . emit ( AsyncResult . Failure ( e )) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠIm mediate ly Ġre comp utes Ġthe Ġcurrent Ġstate Ġ& Ġnot ifies Ġit 's Ġbeen Ġchanged . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠThis Ġshould Ġonly Ġbe Ġcalled Ġwhen Ġthe Ġcaller Ġcan Ġguarantee Ġthat Ġthe Ġcurrent Ġ[ Controller State ] Ġis ĊĠĠ Ġ* Ġcorrect Ġand Ġup - to - date Ġ( i . e . Ġthat Ġthis Ġis Ġbeing Ġcalled Ġvia Ġa Ġdirect Ġcall Ġpath Ġfrom Ġthe Ġactor ). ĊĠĠ Ġ* ĊĠĠ Ġ* ĠAll Ġother Ġcases Ġmust Ġuse Ġ[ re compute Current State And Notify Async ]. ĊĠĠ Ġ*/ ĊĠ Ġprivate Ġsuspend Ġfun ĠController State . re compute Current State And Notify Sync () Ġ{ ĊĠĠĠ Ġre compute Current State And Notify Impl () ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠSends Ġa Ġmessage Ġto Ġre compute Ġthe Ġcurrent Ġstate Ġ& Ġnotify Ġit 's Ġbeen Ġchanged . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠThis Ġmust Ġbe Ġused Ġin Ġcases Ġwhen Ġthe Ġcurrent Ġ[ Controller State ] Ġmay Ġno Ġlonger Ġbe Ġup - to - date Ġto ĊĠĠ Ġ* Ġensure Ġstate Ġisn 't Ġle aked Ġacross Ġplay Ġsessions . ĊĠĠ Ġ*/ ĊĠ Ġprivate Ġsuspend Ġfun ĠController State . re compute Current State And Notify Async () Ġ{ ĊĠĠĠ Ġcommand Queue . send ( Controller Message . Re compute State And Notify ( sessionId )) ĊĠ Ġ} ĊĊĠ Ġprivate Ġsuspend Ġfun ĠController State . re compute Current State And Notify Impl () Ġ{ ĊĠĠĠ Ġep hemeral State Flow . emit ( retrieve Current State Async ()) ĊĠ Ġ} ĊĊĠ Ġprivate Ġsuspend Ġfun ĠController State . retrieve Current State Async (): ĠAsync Result < Ep hemeral State > Ġ{ ĊĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠ Ġretrieve State Within Cache () ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠ Ġexceptions Controller . log Non Fatal Exception ( e ) ĊĠĠĠĠĠ ĠAsync Result . Failure ( e ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġsuspend Ġfun ĠController State . retrieve State Within Cache (): ĠAsync Result < Ep hemeral State > Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ( ex ploration Progress . play Stage ) Ġ{ ĊĠĠĠĠĠ ĠNOT _ PLAY ING Ġ-> ĠAsync Result . Pending () ĊĠĠĠĠĠ ĠLO ADING _ EX PL OR ATION Ġ-> Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġval Ġexploration Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexploration Retriever . load Ex ploration ( ex ploration Progress . current Ex ploration Id ) ĊĠĠĠĠĠĠĠĠĠ Ġfinish Load Ex ploration ( ex ploration , Ġexploration Progress ) ĊĠĠĠĠĠĠĠĠĠ ĠAsync Result . Success ( compute Current Ep hemeral State ()) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġexceptions Controller . log Non Fatal Exception ( e ) ĊĠĠĠĠĠĠĠĠĠ ĠAsync Result . Failure ( e ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ ĠVIEW ING _ STATE Ġ-> ĠAsync Result . Success ( compute Current Ep hemeral State ()) ĊĠĠĠĠĠ ĠSUB MIT TING _ AN SW ER Ġ-> ĠAsync Result . Pending () ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġsuspend Ġfun ĠController State . finish Load Ex ploration ( ĊĠĠĠ Ġexploration : ĠEx ploration , ĊĠĠĠ Ġprogress : ĠEx ploration Progress ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġ// ĠThe Ġexploration Ġmust Ġbe Ġinitialized Ġfirst Ġsince Ġother Ġlazy Ġfields Ġdepend Ġon Ġit Ġbeing Ġinit ed . ĊĠĠĠ Ġprogress . current Ex ploration Ġ= Ġexploration ĊĠĠĠ Ġprogress . state Graph . reset ( ex ploration . states Map ) ĊĊĠĠĠ Ġif Ġ( progress . ex ploration Checkpoint Ġ!= ĠEx ploration Checkpoint . getDefaultInstance ()) Ġ{ ĊĠĠĠĠĠ Ġ// ĠRestore Ġthe ĠState Deck Ġand Ġthe ĠHint Handler Ġif Ġthe Ġexploration Ġis Ġbeing Ġres umed . ĊĠĠĠĠĠ Ġprogress . resume State Deck For Saved State ( ex ploration ) ĊĠĠĠĠĠ Ġhint Handler . resume Hints For Saved State ( ĊĠĠĠĠĠĠĠ Ġprogress . ex ploration Checkpoint . pending User Answers Count , ĊĠĠĠĠĠĠĠ Ġprogress . ex ploration Checkpoint . help Index , ĊĠĠĠĠĠĠĠ Ġprogress . state Deck . getCurrent State () ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ Ġ// ĠIf Ġthe Ġexploration Ġis Ġnot Ġbeing Ġres umed , Ġreset Ġthe ĠState Deck Ġand Ġthe ĠHint Handler . ĊĠĠĠĠĠ Ġprogress . state Deck . reset Deck ( progress . state Graph . getState ( ex ploration . init State Name )) ĊĠĠĠĠĠ Ġhint Handler . start Watch ing For Hints In New State ( progress . state Deck . getCurrent State ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠAdv ance Ġthe Ġstage , Ġbut Ġdo Ġnot Ġnotify Ġob servers Ġsince Ġthe Ġcurrent Ġstate Ġcan Ġbe Ġreported ĊĠĠĠ Ġ// Ġimmediately Ġto Ġthe ĠUI . ĊĠĠĠ Ġprogress . advance Play Stage To ( VIEW ING _ STATE ) ĊĊĠĠĠ Ġ// ĠMark Ġa Ġcheckpoint Ġin Ġthe Ġexploration Ġonce Ġthe Ġexploration Ġhas Ġloaded . ĊĠĠĠ Ġsave Ex ploration Checkpoint () ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun ĠController State . compute Base Current Ep hemeral State (): ĠEp hemeral State Ġ= ĊĠĠĠ Ġexploration Progress . state Deck . getCurrent Ep hemeral State ( retrieve Current Help Index ()) ĊĊĠ Ġprivate Ġfun ĠController State . compute Current Ep hemeral State (): ĠEp hemeral State Ġ{ ĊĠĠĠ Ġreturn Ġcompute Base Current Ep hemeral State (). to Builder (). apply Ġ{ ĊĠĠĠĠĠ Ġ// ĠEnsure Ġthat Ġthe Ġstate Ġhas Ġan Ġup - to - date Ġcheckpoint Ġstate . ĊĠĠĠĠĠ Ġcheckpoint State Ġ= Ġexploration Progress . checkpoint State ĊĠĠĠ Ġ}. build () ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun ĠController State . retrieve Current Help Index (): ĠHelp Index Ġ= ĊĠĠĠ Ġhint Handler . getCurrent Help Index (). value ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠChecks Ġif Ġcheckpoint ing Ġis Ġenabled , Ġif Ġcheckpoint ing Ġis Ġenabled Ġthis Ġfunction Ġcreates Ġa ĊĠĠ Ġ* Ġcheckpoint Ġwith Ġthe Ġlatest Ġprogress Ġand Ġsaves Ġit Ġusing Ġ[ Ex ploration Checkpoint Controller ]. ĊĠĠ Ġ* ĊĠĠ Ġ* ĠThis Ġfunction Ġalso Ġwaits Ġfor Ġthe Ġsave Ġoperation Ġto Ġcomplete , Ġupon Ġcompletion Ġthis Ġfunction ĊĠĠ Ġ* Ġuses Ġthe Ġfunction Ġ[ process Save Checkpoint Result ] Ġto Ġmark Ġthe Ġexploration Ġas ĊĠĠ Ġ* ĠIN _ PROGRESS _ SA VED Ġor ĠIN _ PROGRESS _ NOT _ SA VED Ġdepending Ġupon Ġthe Ġresult . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠNote Ġthat Ġwhile Ġthis Ġis Ġchanging Ġinternal Ġep hemeral Ġstate , Ġit Ġdoes Ġnot Ġnotify Ġof Ġchanges Ġ( it ĊĠĠ Ġ* Ġinstead Ġexpects Ġcall ers Ġto Ġdo Ġthis Ġwhen Ġit 's Ġbest Ġto Ġnotify Ġfrontend Ġob servers Ġof Ġthe Ġchanges ). ĊĠĠ Ġ*/ ĊĠ Ġprivate Ġfun ĠController State . save Ex ploration Checkpoint () Ġ{ ĊĠĠĠ Ġ// ĠDo Ġnot Ġsave Ġcheck points Ġif Ġshould Save Partial Progress Ġis Ġfalse . ĠThis Ġis Ġexpected Ġto Ġhappen ĊĠĠĠ Ġ// Ġwhen Ġthe Ġcurrent Ġexploration Ġhas Ġbeen Ġalready Ġcompleted Ġpreviously . ĊĠĠĠ Ġif Ġ(! ex ploration Progress . should Save Partial Progress ) Ġreturn ĊĠĠĠ Ġval Ġprofile Id : ĠProfile Id Ġ= Ġexploration Progress . current Profile Id ĊĠĠĠ Ġval Ġtopic Id : ĠString Ġ= Ġexploration Progress . current Topic Id ĊĠĠĠ Ġval Ġstory Id : ĠString Ġ= Ġexploration Progress . current Story Id ĊĠĠĠ Ġval Ġexploration Id : ĠString Ġ= Ġexploration Progress . current Ex ploration Id ĊĊĠĠĠ Ġval Ġcheckpoint : ĠEx ploration Checkpoint Ġ= ĊĠĠĠĠĠ Ġexploration Progress . state Deck . create Ex ploration Checkpoint ( ĊĠĠĠĠĠĠĠ Ġexploration Progress . current Ex ploration . version , ĊĠĠĠĠĠĠĠ Ġexploration Progress . current Ex ploration . title , ĊĠĠĠĠĠĠĠ Ġopp ia Clock . getCurrent Time Ms (), ĊĠĠĠĠĠĠĠ Ġretrieve Current Help Index () ĊĠĠĠĠĠ Ġ) ĊĊĠĠĠ Ġval Ġdeferred Ġ= Ġexploration Checkpoint Controller . record Ex ploration Checkpoint Async ( ĊĠĠĠĠĠ Ġprofile Id , ĊĠĠĠĠĠ Ġexploration Id , ĊĠĠĠĠĠ Ġcheckpoint ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġdeferred . invoke On Completion Ġ{ ĊĠĠĠĠĠ Ġval Ġcheckpoint State Ġ= Ġif Ġ( it Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġdeferred . get Completed () ĊĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġopp ia Logger . e (" Light weight Ġcheckpoint ing ", Ġ" Failed Ġto Ġsave Ġcheckpoint Ġin Ġexploration ", Ġit ) ĊĠĠĠĠĠĠĠ Ġ// ĠCheck point State Ġis Ġmarked Ġas ĠCHECK POINT _ UN SA VED Ġbecause Ġthe Ġdeferred Ġdid Ġnot ĊĠĠĠĠĠĠĠ Ġ// Ġcomplete Ġsuccessfully . ĊĠĠĠĠĠĠĠ ĠCheck point State . CHECK POINT _ UN SA VED ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġ// ĠSchedule Ġan Ġevent Ġto Ġprocess Ġthe Ġcheckpoint Ġresults Ġin Ġa Ġsynchronized Ġenvironment Ġto Ġavoid ĊĠĠĠĠĠ Ġ// Ġneeding Ġto Ġlock Ġon ĠController State . ĊĠĠĠĠĠ Ġval Ġprocess Event Ġ= ĊĠĠĠĠĠĠĠ ĠController Message . Process Saved Checkpoint Result ( ĊĠĠĠĠĠĠĠĠĠ Ġprofile Id , ĊĠĠĠĠĠĠĠĠĠ Ġtopic Id , ĊĠĠĠĠĠĠĠĠĠ Ġstory Id , ĊĠĠĠĠĠĠĠĠĠ Ġexploration Id , ĊĠĠĠĠĠĠĠĠĠ Ġopp ia Clock . getCurrent Time Ms (), ĊĠĠĠĠĠĠĠĠĠ Ġcheckpoint State , ĊĠĠĠĠĠĠĠĠĠ ĠsessionId ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠ Ġsend Command For Operation ( process Event ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Failed Ġto Ġschedule Ġcommand Ġfor Ġprocessing Ġa Ġsaved Ġcheckpoint ." ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠPro cesses Ġthe Ġresult Ġobtained Ġupon Ġcomplete Ġexecution Ġof Ġthe Ġfunction ĊĠĠ Ġ* Ġ[ save Ex ploration Checkpoint ]. ĊĠĠ Ġ* ĊĠĠ Ġ* ĠMark s Ġthe Ġexploration Ġas Ġin _ progress _ saved Ġor Ġin _ progress _ not _ saved Ġif Ġit Ġis Ġnot Ġalready Ġmarked ĊĠĠ Ġ* Ġcorrectly . ĠThis Ġfunction Ġalso Ġupdates Ġthe Ġcheckpoint Ġstate Ġof Ġthe Ġexploration Ġto Ġthe ĊĠĠ Ġ* Ġspecified Ġnew Ġcheckpoint Ġstate . ĊĠĠ Ġ* ĊĠĠ Ġ* Ġ@ param Ġprofile Id Ġis Ġthe Ġprofile Ġid Ġcurrently Ġplaying Ġthe Ġexploration ĊĠĠ Ġ* Ġ@ param Ġtopic Id Ġis Ġthe Ġid Ġof Ġthe Ġtopic Ġwhich Ġcontains Ġthe Ġstory Ġwith Ġthe Ġcurrent Ġexploration ĊĠĠ Ġ* Ġ@ param Ġstory Id Ġis Ġthe Ġid Ġof Ġthe Ġstory Ġwhich Ġcontains Ġthe Ġcurrent Ġexploration ĊĠĠ Ġ* Ġ@ param Ġlast Play ed Timestamp Ġtimestamp Ġof Ġthe Ġtime Ġwhen Ġthe Ġcheck points Ġstate Ġfor Ġthe Ġexploration ĊĠĠ Ġ* ĠĠĠĠ Ġwas Ġlast Ġupdated ĊĠĠ Ġ* Ġ@ param Ġnew Checkpoint State Ġthe Ġlatest Ġstate Ġobtained Ġafter Ġsaving Ġcheckpoint Ġsuccessfully Ġor ĊĠĠ Ġ* ĠĠĠĠ Ġun successfully ĊĠĠ Ġ*/ ĊĠ Ġprivate Ġsuspend Ġfun ĠController State . process Save Checkpoint Result ( ĊĠĠĠ Ġprofile Id : ĠProfile Id , ĊĠĠĠ Ġtopic Id : ĠString , ĊĠĠĠ Ġstory Id : ĠString , ĊĠĠĠ Ġexploration Id : ĠString , ĊĠĠĠ Ġlast Play ed Timestamp : ĠLong , ĊĠĠĠ Ġnew Checkpoint State : ĠCheck point State ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġ// ĠOnly Ġprocesses Ġthe Ġresult Ġof Ġthe Ġlast Ġsave Ġoperation Ġif Ġthe Ġcheckpoint State Ġhas Ġchanged . ĊĠĠĠ Ġif Ġ( ex ploration Progress . checkpoint State Ġ!= Ġnew Checkpoint State ) Ġ{ ĊĠĠĠĠĠ Ġ// ĠMark Ġexploration Ġas ĠIN _ PROGRESS _ SA VED Ġor ĠIN _ PROGRESS _ NOT _ SA VED Ġif Ġthe Ġcheckpoint State Ġhas ĊĠĠĠĠĠ Ġ// Ġeither Ġchanged Ġfrom ĠUNS AV ED Ġto ĠS AV ED Ġor Ġvice Ġvers a . ĊĠĠĠĠĠ Ġif Ġ( ĊĠĠĠĠĠĠĠ Ġexploration Progress . checkpoint State Ġ!= ĠCheck point State . CHECK POINT _ UN SA VED Ġ&& ĊĠĠĠĠĠĠĠ Ġnew Checkpoint State Ġ== ĠCheck point State . CHECK POINT _ UN SA VED ĊĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġmark Ex ploration As InProgress Not Saved ( ĊĠĠĠĠĠĠĠĠĠ Ġprofile Id , ĊĠĠĠĠĠĠĠĠĠ Ġtopic Id , ĊĠĠĠĠĠĠĠĠĠ Ġstory Id , ĊĠĠĠĠĠĠĠĠĠ Ġexploration Id , ĊĠĠĠĠĠĠĠĠĠ Ġlast Play ed Timestamp ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( ĊĠĠĠĠĠĠĠ Ġexploration Progress . checkpoint State Ġ== ĠCheck point State . CHECK POINT _ UN SA VED Ġ&& ĊĠĠĠĠĠĠĠ Ġnew Checkpoint State Ġ!= ĠCheck point State . CHECK POINT _ UN SA VED ĊĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġmark Ex ploration As InProgress Saved ( ĊĠĠĠĠĠĠĠĠĠ Ġprofile Id , ĊĠĠĠĠĠĠĠĠĠ Ġtopic Id , ĊĠĠĠĠĠĠĠĠĠ Ġstory Id , ĊĠĠĠĠĠĠĠĠĠ Ġexploration Id , ĊĠĠĠĠĠĠĠĠĠ Ġlast Play ed Timestamp ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġexploration Progress . update Checkpoint State ( new Checkpoint State ) ĊĊĠĠĠĠĠ Ġ// ĠThe Ġep hemeral Ġstate Ġtechnically Ġchanges Ġwhen Ġa Ġcheckpoint Ġis Ġsuccessfully Ġsaved . ĊĠĠĠĠĠ Ġre compute Current State And Notify Sync () ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠReturns Ġwhether Ġthe Ġspecified Ġinteraction Ġautomatically Ġcontinues Ġthe Ġuser Ġto Ġthe Ġnext Ġstate ĊĠĠ Ġ* Ġupon Ġcompletion . ĊĠĠ Ġ*/ ĊĠ Ġprivate Ġfun Ġdoes Interaction Auto Continue ( interaction Id : ĠString ): ĠBoolean Ġ= ĊĠĠĠ Ġinteraction Id Ġ== Ġ" Continue " ĊĊĠ Ġprivate Ġfun Ġmark Ex ploration As InProgress Saved ( ĊĠĠĠ Ġprofile Id : ĠProfile Id , ĊĠĠĠ Ġtopic Id : ĠString , ĊĠĠĠ Ġstory Id : ĠString , ĊĠĠĠ Ġexploration Id : ĠString , ĊĠĠĠ Ġlast Play ed Timestamp : ĠLong ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġstory Progress Controller . record Chapter As InProgress Saved ( ĊĠĠĠĠĠ Ġprofile Id , ĊĠĠĠĠĠ Ġtopic Id , ĊĠĠĠĠĠ Ġstory Id , ĊĠĠĠĠĠ Ġexploration Id , ĊĠĠĠĠĠ Ġlast Play ed Timestamp ĊĠĠĠ Ġ) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġmark Ex ploration As InProgress Not Saved ( ĊĠĠĠ Ġprofile Id : ĠProfile Id , ĊĠĠĠ Ġtopic Id : ĠString , ĊĠĠĠ Ġstory Id : ĠString , ĊĠĠĠ Ġexploration Id : ĠString , ĊĠĠĠ Ġlast Play ed Timestamp : ĠLong ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġstory Progress Controller . record Chapter As InProgress Not Saved ( ĊĠĠĠĠĠ Ġprofile Id , ĊĠĠĠĠĠ Ġtopic Id , ĊĠĠĠĠĠ Ġstory Id , ĊĠĠĠĠĠ Ġexploration Id , ĊĠĠĠĠĠ Ġlast Play ed Timestamp ĊĠĠĠ Ġ) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġ< T > Ġcreate AsyncResult State Flow ( initial Value : ĠAsync Result < T > Ġ= ĠAsync Result . Pending ()) Ġ= ĊĠĠĠ ĠMutable State Flow ( initial Value ) ĊĊĠ Ġprivate Ġfun Ġ< T > ĠState Flow < AsyncResult < T >> . convertTo Session Provider ( ĊĠĠĠ Ġbase Id : ĠString ĊĠ Ġ): ĠData Provider < T > Ġ= Ġdata Providers . run Ġ{ ĊĠĠĠ Ġconvert Async To Automatic DataProvider ("${ base Id }_ $ active SessionId ") ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠRepresents Ġthe Ġcurrent Ġsynchronized Ġstate Ġof Ġthe Ġcontroller . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠThis Ġobject 's Ġinstance Ġis Ġtied Ġdirectly Ġto Ġa Ġsingle Ġexploration Ġsession , Ġand Ġit 's Ġnot ĊĠĠ Ġ* Ġthread - safe Ġso Ġall Ġaccess Ġmust Ġbe Ġsynchronized . ĊĠĠ Ġ* ĊĠĠ Ġ* Ġ@ property Ġexploration Progress Ġthe Ġ[ Ex ploration Progress ] Ġcorresponding Ġto Ġthe Ġsession ĊĠĠ Ġ* Ġ@ property ĠsessionId Ġthe ĠGUID Ġcorresponding Ġto Ġthe Ġsession ĊĠĠ Ġ* Ġ@ property Ġep hemeral State Flow Ġthe Ġ[ Mutable State Flow ] Ġthat Ġthe Ġupdated Ġ[ Ep hemeral State ] Ġis ĊĠĠ Ġ* ĠĠĠĠ Ġdelivered Ġto ĊĠĠ Ġ* Ġ@ property Ġcommand Queue Ġthe Ġactor Ġcommand Ġqueue Ġexecuting Ġall Ġmessages Ġthat Ġchange Ġthis Ġstate ĊĠĠ Ġ*/ ĊĠ Ġprivate Ġclass ĠController State ( ĊĠĠĠ Ġval Ġexploration Progress : ĠEx ploration Progress , ĊĠĠĠ Ġval ĠsessionId : ĠString , ĊĠĠĠ Ġval Ġep hemeral State Flow : ĠMutable State Flow < AsyncResult < Ep hemeral State >>, ĊĠĠĠ Ġval Ġcommand Queue : ĠSend Channel < Controller Message <* >> ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġ[ Hint Handler ] Ġused Ġto Ġmonitor Ġand Ġtrigger Ġhints Ġin Ġthe Ġplay Ġsession Ġcorresponding Ġto Ġthis ĊĠĠĠĠ Ġ* Ġcontroller Ġstate . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġlateinit Ġvar Ġhint Handler : ĠHint Handler ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠRepresents Ġa Ġmessage Ġthat Ġcan Ġbe Ġsent Ġto Ġ[ most Recent Command Queue ] Ġto Ġprocess Ġchanges Ġto ĊĠĠ Ġ* Ġ[ Controller State ] Ġ( since Ġall Ġchanges Ġmust Ġbe Ġsynchronized ). ĊĠĠ Ġ* ĊĠĠ Ġ* ĠMessages Ġare Ġexpected Ġto Ġbe Ġresolved Ġser ially Ġ( though Ġtheir Ġscheduling Ġcan Ġoccur Ġacross ĊĠĠ Ġ* Ġmultiple Ġthreads , Ġso Ġorder Ġcannot Ġbe Ġguaranteed Ġuntil Ġthey 're Ġen queued ). ĊĠĠ Ġ*/ ĊĠ Ġprivate Ġsealed Ġclass ĠController Message < T > Ġ{ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġsession ĠID Ġcorresponding Ġto Ġthis Ġmessage Ġ( the Ġmessage Ġis Ġexpected Ġto Ġbe Ġignored Ġif Ġit ĊĠĠĠĠ Ġ* Ġdoesn 't Ġcorrespond Ġto Ġan Ġactive Ġsession ). ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġabstract Ġval ĠsessionId : ĠString ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġ[ DataProvider ]- t ied Ġ[ Mutable State Flow ] Ġthat Ġrepresents Ġthe Ġresult Ġof Ġthe Ġoperation ĊĠĠĠĠ Ġ* Ġcorresponding Ġto Ġthis Ġmessage , Ġor Ġ`` null `` Ġif Ġthe Ġcaller Ġdoesn 't Ġcare Ġabout Ġob serving Ġthe ĊĠĠĠĠ Ġ* Ġresult . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġabstract Ġval Ġcallback Flow : ĠMutable State Flow < AsyncResult < T >> ? ĊĊĠĠĠ Ġ/** Ġ[ Controller Message ] Ġfor Ġinitializing Ġa Ġnew Ġplay Ġsession . Ġ*/ ĊĠĠĠ Ġdata Ġclass ĠInitialize Controller ( ĊĠĠĠĠĠ Ġval Ġprofile Id : ĠProfile Id , ĊĠĠĠĠĠ Ġval Ġtopic Id : ĠString , ĊĠĠĠĠĠ Ġval Ġstory Id : ĠString , ĊĠĠĠĠĠ Ġval Ġexploration Id : ĠString , ĊĠĠĠĠĠ Ġval Ġshould Save Partial Progress : ĠBoolean , ĊĠĠĠĠĠ Ġval Ġexploration Checkpoint : ĠEx ploration Checkpoint , ĊĠĠĠĠĠ Ġval Ġep hemeral State Flow : ĠMutable State Flow < AsyncResult < Ep hemeral State >>, ĊĠĠĠĠĠ Ġoverride Ġval ĠsessionId : ĠString , ĊĠĠĠĠĠ Ġoverride Ġval Ġcallback Flow : ĠMutable State Flow < AsyncResult < Any ? >> ĊĠĠĠ Ġ) Ġ: ĠController Message < Any ?> () ĊĊĠĠĠ Ġ/** Ġ[ Controller Message ] Ġfor Ġending Ġthe Ġcurrent Ġplay Ġsession . Ġ*/ ĊĠĠĠ Ġdata Ġclass ĠFinish Ex ploration ( ĊĠĠĠĠĠ Ġoverride Ġval ĠsessionId : ĠString , ĊĠĠĠĠĠ Ġoverride Ġval Ġcallback Flow : ĠMutable State Flow < AsyncResult < Any ? >> ĊĠĠĠ Ġ) Ġ: ĠController Message < Any ?> () ĊĊĠĠĠ Ġ/** Ġ[ Controller Message ] Ġfor Ġsubmitting Ġa Ġnew Ġ[ User Answer ]. Ġ*/ ĊĠĠĠ Ġdata Ġclass ĠSubmit Answer ( ĊĠĠĠĠĠ Ġval Ġuser Answer : ĠUser Answer , ĊĠĠĠĠĠ Ġoverride Ġval ĠsessionId : ĠString , ĊĠĠĠĠĠ Ġoverride Ġval Ġcallback Flow : ĠMutable State Flow < AsyncResult < Answer Outcome >> ĊĠĠĠ Ġ) Ġ: ĠController Message < Answer Outcome >() ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ[ Controller Message ] Ġfor Ġindicating Ġthat Ġthe Ġuser Ġreve aled Ġthe Ġhint Ġcorresponding Ġto ĊĠĠĠĠ Ġ* Ġ[ hint Index ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġdata Ġclass ĠHint Is Re ve aled ( ĊĠĠĠĠĠ Ġval Ġhint Index : ĠInt , ĊĠĠĠĠĠ Ġoverride Ġval ĠsessionId : ĠString , ĊĠĠĠĠĠ Ġoverride Ġval Ġcallback Flow : ĠMutable State Flow < AsyncResult < Any ? >> ĊĠĠĠ Ġ) Ġ: ĠController Message < Any ?> () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ[ Controller Message ] Ġfor Ġindicating Ġthat Ġthe Ġuser Ġreve aled Ġthe Ġsolution Ġfor Ġthe Ġcurrent Ġstate . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġdata Ġclass ĠSolution Is Re ve aled ( ĊĠĠĠĠĠ Ġoverride Ġval ĠsessionId : ĠString , ĊĠĠĠĠĠ Ġoverride Ġval Ġcallback Flow : ĠMutable State Flow < AsyncResult < Any ? >> ĊĠĠĠ Ġ) Ġ: ĠController Message < Any ?> () ĊĊĠĠĠ Ġ/** Ġ[ Controller Message ] Ġto Ġmove Ġto Ġthe Ġprevious Ġstate Ġin Ġthe Ġexploration . Ġ*/ ĊĠĠĠ Ġdata Ġclass ĠMove To Previous State ( ĊĠĠĠĠĠ Ġoverride Ġval ĠsessionId : ĠString , ĊĠĠĠĠĠ Ġoverride Ġval Ġcallback Flow : ĠMutable State Flow < AsyncResult < Any ? >> ĊĠĠĠ Ġ) Ġ: ĠController Message < Any ?> () ĊĊĠĠĠ Ġ/** Ġ[ Controller Message ] Ġto Ġmove Ġto Ġthe Ġnext Ġstate Ġin Ġthe Ġexploration . Ġ*/ ĊĠĠĠ Ġdata Ġclass ĠMove To Next State ( ĊĠĠĠĠĠ Ġoverride Ġval ĠsessionId : ĠString , ĊĠĠĠĠĠ Ġoverride Ġval Ġcallback Flow : ĠMutable State Flow < AsyncResult < Any ? >> ĊĠĠĠ Ġ) Ġ: ĠController Message < Any ?> () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ[ Controller Message ] Ġto Ġindicate Ġthat Ġthe Ġsession 's Ġcurrent Ġpartial Ġcompletion Ġprogress Ġshould ĊĠĠĠĠ Ġ* Ġbe Ġsaved Ġto Ġdisk . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠNote Ġthat Ġthis Ġdoes Ġnot Ġactually Ġguarantee Ġan Ġupdate Ġto Ġthe Ġtracked Ġprogress Ġof Ġthe ĊĠĠĠĠ Ġ* Ġexploration Ġ( see Ġ[ Process Saved Checkpoint Result ]). ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġdata Ġclass ĠSave Checkpoint ( ĊĠĠĠĠĠ Ġoverride Ġval ĠsessionId : ĠString , ĊĠĠĠĠĠ Ġoverride Ġval Ġcallback Flow : ĠMutable State Flow < AsyncResult < Any ? >> ? Ġ= Ġnull ĊĠĠĠ Ġ) Ġ: ĠController Message < Any ?> () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ[ Controller Message ] Ġto Ġensure Ġa Ġsuccessfully Ġsaved Ġcheckpoint Ġis Ġreflected Ġin Ġother Ġparts Ġof ĊĠĠĠĠ Ġ* Ġthe Ġapp Ġ( e . g . Ġthat Ġan Ġexploration Ġis Ġconsidered Ġ' in - progress ' Ġin Ġsuch Ġcircumstances ). ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġdata Ġclass ĠProcess Saved Checkpoint Result ( ĊĠĠĠĠĠ Ġval Ġprofile Id : ĠProfile Id , ĊĠĠĠĠĠ Ġval Ġtopic Id : ĠString , ĊĠĠĠĠĠ Ġval Ġstory Id : ĠString , ĊĠĠĠĠĠ Ġval Ġexploration Id : ĠString , ĊĠĠĠĠĠ Ġval Ġlast Play ed Timestamp : ĠLong , ĊĠĠĠĠĠ Ġval Ġnew Checkpoint State : ĠCheck point State , ĊĠĠĠĠĠ Ġoverride Ġval ĠsessionId : ĠString , ĊĠĠĠĠĠ Ġoverride Ġval Ġcallback Flow : ĠMutable State Flow < AsyncResult < Any ? >> ? Ġ= Ġnull ĊĠĠĠ Ġ) Ġ: ĠController Message < Any ?> () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ[ Controller Message ] Ġwhich Ġre comp utes Ġthe Ġcurrent Ġ[ Ep hemeral State ] Ġand Ġnot ifies Ġsubscribers Ġof ĊĠĠĠĠ Ġ* Ġthe Ġ[ DataProvider ] Ġreturned Ġby Ġ[ getCurrent State ] Ġof Ġthe Ġchange . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThis Ġis Ġonly Ġused Ġin Ġcases Ġwhere Ġan Ġexternal Ġoperation Ġtrigger Ġchanges Ġthat Ġare Ġonly ĊĠĠĠĠ Ġ* Ġreflected Ġwhen Ġre computing Ġthe Ġstate Ġ( e . g . Ġa Ġnew Ġhint Ġneeding Ġto Ġbe Ġshown ). ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġdata Ġclass ĠRe compute State And Notify ( ĊĠĠĠĠĠ Ġoverride Ġval ĠsessionId : ĠString , ĊĠĠĠĠĠ Ġoverride Ġval Ġcallback Flow : ĠMutable State Flow < AsyncResult < Any ? >> ? Ġ= Ġnull ĊĠĠĠ Ġ) Ġ: ĠController Message < Any ?> () ĊĠ Ġ} Ċ } Ċ