// ĠMIT ĠLicense Ċ // Ċ // ĠPermission Ġis Ġhereby Ġgranted , Ġfree Ġof Ġcharge , Ġto Ġany Ġperson Ġobtaining Ġa Ġ Ċ // Ġcopy Ġof Ġthis Ġsoftware Ġand Ġassociated Ġdocumentation Ġfiles Ġ( the Ġ" Software "), Ġ Ċ // Ġto Ġdeal Ġin Ġthe ĠSoftware Ġwithout Ġrestriction , Ġincluding Ġwithout Ġlimitation Ġ Ċ // Ġthe Ġrights Ġto Ġuse , Ġcopy , Ġmodify , Ġmerge , Ġpublish , Ġdistribute , Ġsublicense , Ġ Ċ // Ġand / or Ġsell Ġcopies Ġof Ġthe ĠSoftware , Ġand Ġto Ġpermit Ġpersons Ġto Ġwhom Ġthe Ġ Ċ // ĠSoftware Ġis Ġfurnished Ġto Ġdo Ġso , Ġsubject Ġto Ġthe Ġfollowing Ġconditions : Ċ // Ċ // ĠThe Ġabove Ġcopyright Ġnotice Ġand Ġthis Ġpermission Ġnotice Ġshall Ġbe Ġincluded Ġin Ċ // Ġall Ġcopies Ġor Ġsubstantial Ġportions Ġof Ġthe ĠSoftware . Ċ // Ċ // ĠTHE ĠSOFTWARE ĠIS ĠPROVIDED Ġ" AS ĠIS ", ĠWITHOUT ĠWARRANTY ĠOF ĠANY ĠKIND , ĠEXPRESS ĠOR Ġ Ċ // ĠIMPLIED , ĠINCLUDING ĠBUT ĠNOT ĠLIMITED ĠTO ĠTHE ĠWARRANTIES ĠOF ĠMERCHANTABILITY , Ġ Ċ // ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE ĠAND ĠNONINFRINGEMENT . ĠIN ĠNO ĠEVENT ĠSHALL ĠTHE Ċ // ĠAUTHORS ĠOR ĠCOPYRIGHT ĠHOLDERS ĠBE ĠLIABLE ĠFOR ĠANY ĠCLAIM , ĠDAMAGES ĠOR ĠOTHER Ġ Ċ // ĠLIABILITY , ĠWHETHER ĠIN ĠAN ĠACTION ĠOF ĠCONTRACT , ĠTORT ĠOR ĠOTHERWISE , ĠARISING Ġ Ċ // ĠFROM , ĠOUT ĠOF ĠOR ĠIN ĠCONNECTION ĠWITH ĠTHE ĠSOFTWARE ĠOR ĠTHE ĠUSE ĠOR ĠOTHER ĠDEALINGS Ċ // ĠIN ĠTHE ĠSOFTWARE . Ċ // Ċ // Ġ ĠNav StateMachine . kt Ċ // Ġ ĠFlow Kit Ċ // Ċ // Ġ ĠCreated Ġby ĠB rian ĠHow ard Ċ // Ġ ĠCopyright ĠÂ© Ġ 2 0 2 0 ĠIn Motion ĠSoftware , ĠLLC . ĠAll Ġrights Ġreserved . Ċ // Ċ package Ġcom . in motion software . flow kit . android Ċ Ċ import Ġandroid . app . Activity Ċ import Ġandroid . app . Activity Manager Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . Intent Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . os . Parcelable Ċ import Ġandroid . os . Persist able Bundle Ċ import Ġandroid . util . Log Ċ import Ġandroid . view . View Ċ import Ġandroid . view . ViewGroup Ċ import Ġandroid . widget . LinearLayout Ċ import Ġandroidx . annotation . Call Super Ċ import Ġandroidx . appcompat . app . AppCompatActivity Ċ import Ġandroidx . fragment . app . Fragment Ċ import Ġandroidx . lifecycle .* Ċ import Ġcom . in motion software . flow kit .* Ċ import Ġcom . in motion software . flow kit . Result Ċ import Ġcom . in motion software . promise kt .* Ċ import Ġkotlinx . android . parcel . Parcel ize Ċ import Ġjava . lang . IllegalStateException Ċ import Ġjava . lang . RuntimeException Ċ import Ġjava . nio . Buffer Under flow Exception Ċ import Ġjava . util .* ĊĊ Ċ interface ĠNav StateMachine Ġ{ ĊĠĠĠ Ġfun Ġ< I , ĠO , ĠF : ĠFlow Fragment < I , O >> Ġsub flow ( fragment : ĠF , Ġcontext : ĠI , Ġanimated : ĠBoolean Ġ= Ġtrue ): ĠPromise < O > ĊĠĠĠ Ġfun Ġ< S : ĠFlow State , ĠI , ĠO , ĠSM : ĠState Machine Activity < S , ĠI , ĠO >> Ġsub flow ( state Machine : ĠClass < SM >, Ġstate : ĠS , Ġanimated : ĠBoolean Ġ= Ġtrue ): ĠPromise < O > ĊĠĠĠ Ġfun Ġ< O , ĠA : ĠActivity > Ġsub flow ( activity : ĠClass < A >, Ġbundle : ĠBundle ?, Ġanimated : ĠBoolean Ġ= Ġtrue ): ĠPromise < O > ĊĠĠĠ Ġfun Ġ< O , ĠA : ĠFlow Activity < O >> Ġsub flow ( activity : ĠClass < A >, Ġcontext : ĠUnit , Ġanimated : ĠBoolean Ġ= Ġtrue ): ĠPromise < O > Ġ= Ġsub flow ( activity = activity , Ġanimated = animated ) ĊĠĠĠ Ġfun Ġ< O , ĠA : ĠFlow Activity < O >> Ġsub flow ( activity : ĠClass < A >, Ġanimated : ĠBoolean Ġ= Ġtrue ): ĠPromise < O > Ġ= Ġsub flow ( activity = activity , Ġbundle = null , Ġanimated = animated ) ĊĠĠĠ Ġfun Ġ< I , ĠO , ĠA : ĠFlow Input Activity < I , O >> Ġsub flow ( activity : ĠClass < A >, Ġcontext : ĠI , Ġanimated : ĠBoolean Ġ= Ġtrue ): ĠPromise < O > Ġ= ĊĠĠĠĠĠĠĠ Ġsub flow ( activity = activity , Ġbundle = Bundle (). put (" context ", Ġcontext ), Ġanimated = animated ) Ċ } Ċ Ċ internal Ġconst Ġval ĠF LOW KIT _ B UNDLE _ CONTEXT Ġ= Ġ" com . in motion software . flow kit . Context " Ċ Ċ fun Ġ< T > Ġignore _ error ( lambda : Ġ() Ġ-> ĠT ): ĠT ? Ġ= ĊĠĠĠ Ġwhen ( val Ġrt Ġ= Ġattempt ( lambda )) Ġ{ ĊĠĠĠĠĠĠĠ Ġis Ġcom . in motion software . promise kt . Result . fulfilled Ġ-> Ġrt . value ĊĠĠĠĠĠĠĠ Ġis Ġcom . in motion software . promise kt . Result . rejected Ġ-> Ġnull ĊĠĠĠ Ġ} Ċ Ċ fun Ġ< T > Ġattempt ( lambda : Ġ() Ġ-> ĠT ): Ġcom . in motion software . promise kt . Result < T > Ġ{ ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġrt Ġ= Ġlambda () ĊĠĠĠĠĠĠĠ Ġreturn Ġcom . in motion software . promise kt . Result . fulfilled ( rt ) ĊĠĠĠ Ġ} Ġcatch ( e : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġcom . in motion software . promise kt . Result . rejected ( e ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ interface ĠState Machine ViewModel Delegate < S : ĠFlow State , ĠI , O >: ĠState Machine Delegate < S > Ġ{ ĊĠĠĠ Ġval Ġstate Machine : ĠState Machine < S , I , O > ĊĠĠĠ Ġfun Ġresolve ( result : ĠO ) ĊĠĠĠ Ġfun Ġreject ( cause : ĠThrowable ) Ċ } Ċ Ċ class ĠState Machine ViewModel < S : ĠFlow State , ĠI , ĠO >: ĠViewModel (), ĠState Machine Delegate < S > Ġ{ ĊĠĠĠ Ġvar Ġstate : ĠS ? Ġ= Ġnull ĊĠĠĠ Ġvar Ġpending : ĠBoolean Ġ= Ġfalse ĊĠĠĠ Ġlateinit Ġvar Ġdelegate : ĠState Machine ViewModel Delegate < S , ĠI , ĠO > ĊĊĠĠĠ Ġoverride Ġfun Ġstate DidChange ( from : ĠS , Ġto : ĠS ) Ġ{ ĊĠĠĠĠĠĠĠ Ġstate Ġ= Ġto ĊĠĠĠĠĠĠĠ Ġthis . delegate . state DidChange ( from = from , Ġto = to ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġjump To State ( state : ĠS ) Ġ= ĊĠĠĠĠĠĠĠ Ġnext State ( prev = state , Ġcurr = state ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. done Ġ{ Ġwhen ( it ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResult . Success Ġ-> Ġdelegate . resolve ( it . value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResult . Failure Ġ-> Ġdelegate . reject ( it . cause ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}} ĊĊĠĠĠ Ġprivate Ġfun Ġnext State ( prev : ĠS , Ġcurr : ĠS ): ĠPromise < Result < O >> Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . state DidChange ( from Ġ= Ġprev , Ġto Ġ= Ġcurr ) ĊĠĠĠĠĠĠĠ Ġdelegate . state Machine . getResult ( state = curr )?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġdelegate . state Machine . on Terminate ( state = curr , Ġcontext = it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ ĠResult . Success ( it ) Ġas ĠResult < O > Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. recover Ġ{ ĠPromise . value ( Result . Failure < O >( it )) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġdelegate . state Machine . dispatch ( prev = prev , Ġstate = curr ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. then Map Ġ{ Ġnext State ( prev = curr , Ġcurr = it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. recover Ġ{ Ġnext State ( prev = curr , Ġcurr = delegate . state Machine . create State ( error = it )) Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ internal Ġobject ĠState Machine ViewModel Provider Ġ{ ĊĠĠĠ Ġprivate Ġclass ĠOwner : ĠViewModel Store Owner Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġstore Ġ= ĠViewModel Store () ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġget ViewModel Store (): ĠViewModel Store Ġ= Ġstore ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġmap Ġ= Ġmutable Map Of < String , ĠViewModel Store Owner >() ĊĊĠĠĠ Ġprivate Ġfun Ġget ViewModel Owner ( key : ĠString ): ĠViewModel Store Owner Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmap Ġ= Ġthis . map ĊĠĠĠĠĠĠĠ Ġmap . get ( key )?. let Ġ{ Ġreturn Ġit Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġowner Ġ= ĠOwner () ĊĠĠĠĠĠĠĠ Ġmap . put ( key , Ġowner ) ĊĠĠĠĠĠĠĠ Ġreturn Ġowner ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġ< S : ĠFlow State , ĠI , O > Ġfinish ( activity : ĠState Machine Activity < S , ĠI , ĠO >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġactivity . java Class . canonical Name !! ĊĠĠĠĠĠĠĠ Ġval Ġmap Ġ= Ġthis . map ĊĠĠĠĠĠĠĠ Ġmap . remove ( key )?. viewModel Store ?. clear () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġ< S : ĠFlow State , ĠI , O , ĠSM : ĠState Machine Activity < S , ĠI , ĠO >> Ġof ( activity : ĠSM ): ĠState Machine ViewModel < S , ĠI , O > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġowner Ġ= Ġget ViewModel Owner ( activity . java Class . canonical Name !! ) ĊĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġget ViewModel Key ( viewModel = StateMachine ViewModel :: class . java , Ġtarget = activity ) ĊĠĠĠĠĠĠĠ Ġ@ Suppress (" UN CHECK ED _ CAST ") ĊĠĠĠĠĠĠĠ Ġreturn ĠViewModel Provider ( owner ). get ( key , ĠState Machine ViewModel :: class . java ) Ġas ĠState Machine ViewModel < S , ĠI , O > ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġ< I , ĠO , ĠF : ĠFlow Fragment < I , O >> Ġof ( activity : ĠActivity , Ġfragment : ĠF ): ĠFlow ViewModel < I , O > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġowner Ġ= Ġget ViewModel Owner ( activity . java Class . canonical Name !! ) ĊĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġget ViewModel Key ( viewModel = Flow ViewModel :: class . java , Ġtarget = Ġfragment ) ĊĠĠĠĠĠĠĠ Ġ@ Suppress (" UN CHECK ED _ CAST ") ĊĠĠĠĠĠĠĠ Ġreturn ĠViewModel Provider ( owner ). get ( key , ĠFlow ViewModel :: class . java ) Ġas ĠFlow ViewModel < I , O > ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġ< I , ĠO , ĠF : ĠFlow Fragment < I , O >> Ġof ( activity : ĠActivity , Ġfragment : ĠF , Ġfactory : ĠViewModel Provider . Factory ): ĠFlow ViewModel < I , O > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġowner Ġ= Ġget ViewModel Owner ( activity . java Class . canonical Name !! ) ĊĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġget ViewModel Key ( viewModel = Flow ViewModel :: class . java , Ġtarget = Ġfragment ) ĊĠĠĠĠĠĠĠ Ġ@ Suppress (" UN CHECK ED _ CAST ") ĊĠĠĠĠĠĠĠ Ġreturn ĠViewModel Provider ( owner , Ġfactory ). get ( key , ĠFlow ViewModel :: class . java ) Ġas ĠFlow ViewModel < I , O > ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġconst Ġval ĠDEFAULT _ KEY Ġ= Ġ" com . in motion software . flow kit . android . ViewModel Provider . Default Key " Ċ internal Ġfun Ġ< VM : ĠViewModel > Ġget ViewModel Key ( viewModel : ĠClass < VM >, Ġtarget : ĠAny ): ĠString Ġ{ ĊĠĠĠ Ġreturn Ġ"${ DEFAULT _ KEY }:${ viewModel . canonical Name }:${ target . java Class . canonical Name }" Ċ } Ċ Ċ abstract Ġclass ĠState Machine Activity < S : ĠFlow State , I , O >: ĠAppCompatActivity (), ĠState Machine ViewModel Delegate < S , ĠI , ĠO >, ĠNav StateMachine , ĠState Machine < S , I , O > Ġ{ ĊĠĠĠ Ġoverride Ġval Ġstate Machine : ĠState Machine < S , I , O > Ġget () Ġ= Ġthis ĊĊĠĠĠ Ġprivate Ġval Ġfragment Cache Ġ= Ġmutable Map Of < Class < Fragment >, ĠFragment >() ĊĊĠĠĠ Ġfun Ġ< F : ĠFragment > Ġget Fragment ( fragment : ĠClass < F >): ĠF Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġfragment Ġas ĠClass < Fragment > ĊĠĠĠĠĠĠĠ Ġfragment Cache . get ( key )?. let Ġ{ Ġreturn Ġit Ġas ĠF Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġf Ġ= Ġfragment . newInstance () ĊĠĠĠĠĠĠĠ Ġfragment Cache [ key ] Ġ= Ġf ĊĠĠĠĠĠĠĠ Ġreturn Ġf ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġvar Ġdelegate : ĠState Machine Delegate < S >? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġview Id Ġ= Ġ 0 ĊĠĠĠ Ġprivate Ġval ĠviewModel Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġvm Ġ= ĠState Machine ViewModel Provider . of ( this ) ĊĠĠĠĠĠĠĠ Ġvm . delegate Ġ= Ġthis ĊĠĠĠĠĠĠĠ Ġvm ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġ< O 2 > Ġdispatch ( intent : ĠIntent ): ĠPromise < O 2 > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġpending Ġ= ĠPromise . pending < O 2 >() ĊĠĠĠĠĠĠĠ Ġval Ġcode Ġ= ĠFlow Dispatcher . register () Ġ{ Ġcode , Ġdata Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġif Ġ( data Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠResult . Failure ( NullPointerException ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget Result < O 2 >( data ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpending . second . resolve ( result ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġstart Ġa Ġnew ĠViewModel Ġstore Ġon Ġthe Ġstack . ĠWe Ġuse Ġthis Ġto Ġscope Ġall Ġof Ġthe Ġsub flow 's ĊĠĠĠĠĠĠĠ Ġ// ĠView Models , Ġthis Ġallows Ġus Ġto Ġdestroy Ġthem Ġafter Ġthe Ġflow Ġun wind s ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . startActivity For Result ( intent , Ġcode ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( t : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpending . second . reject ( t ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġpending . first ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġ< A : ĠActivity > Ġshould Animate ( activity : ĠClass < A >): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġam Ġ= Ġthis . application Context . getSystem Service ( Context . ACTIVITY _ SERVICE ) Ġas ĠActivity Manager ĊĠĠĠĠĠĠĠ Ġval Ġcn Ġ= Ġif Ġ( android . os . Build . VERSION . SDK _ INT Ġ>= Ġandroid . os . Build . VERSION _ CODES . M ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġam . getApp Tasks (). first OrNull ()?. get Task Info ()?. top Activity ; ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// no inspection Ġdeprecation ĊĠĠĠĠĠĠĠĠĠĠĠ Ġam . get Running Tasks ( 1 ). first OrNull ()?. top Activity ; ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcn ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . java Class Ġ== Ġactivity ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġ< O 2 , ĠA : ĠActivity > Ġsub flow ( activity : ĠClass < A >, Ġbundle : ĠBundle ?, Ġanimated : ĠBoolean ): ĠPromise < O 2 > Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( this . is Destroyed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠPromise ( error = IllegalStateException (" Trying Ġto Ġadd Ġfragment Ġto Ġdestroyed ĠActivity ")) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġintent Ġ= ĠIntent ( this , Ġactivity ) ĊĠĠĠĠĠĠĠ Ġintent . putExtra ( FLOW KIT _ B UNDLE _ CONTEXT , Ġbundle ) ĊĠĠĠĠĠĠĠ Ġif Ġ(! animated ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġintent . add Flags ( Intent . FLAG _ ACTIVITY _ NO _ ANIM ATION ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . override Pending Transition ( 0 , Ġ 0 ); ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġdispatch < O 2 >( intent ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġ< S 2 : ĠFlow State , ĠI 2 , ĠO 2 , ĠSM 2 : ĠState Machine Activity < S 2 , ĠI 2 , ĠO 2 >> Ġsub flow ( state Machine : ĠClass < SM 2 >, Ġstate : ĠS 2 , Ġanimated : ĠBoolean ): ĠPromise < O 2 > Ġ= ĊĠĠĠĠĠĠĠ Ġsub flow ( activity = state Machine , Ġbundle = Bundle (). put (" state ", Ġstate ), Ġanimated = animated ) ĊĊĠĠĠ Ġfun Ġ< I 2 , ĠO 2 , ĠF : ĠFlow Fragment < I 2 , O 2 >> Ġsub flow 2 ( fragment : ĠClass < F >, Ġcontext : ĠI 2 , Ġanimated : ĠBoolean Ġ= Ġtrue ): ĠPromise < O 2 > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsub flow ( fragment = get Fragment ( fragment ), Ġcontext = context , Ġanimated = animated ) ĊĊĠĠĠ Ġoverride Ġfun Ġ< I 2 , ĠO 2 , ĠF : ĠFlow Fragment < I 2 , O 2 >> Ġsub flow ( fragment : ĠF , Ġcontext : ĠI 2 , Ġanimated : ĠBoolean ): ĠPromise < O 2 > Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( this . is Destroyed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠPromise ( error = IllegalStateException (" Trying Ġto Ġadd Ġfragment Ġto Ġdestroyed ĠActivity ")) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġpending Ġ= ĠPromise . pending < O 2 >() ĊĠĠĠĠĠĠĠ Ġthis . run On Ui Thread Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfactory Ġ= ĠFlow ViewModel Factory () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠviewModel Ġ= ĠState Machine ViewModel Provider . of ( activity = this , Ġfragment = fragment , Ġfactory = factory ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel . init ( context , Ġpending . second ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpush Fragment ( fragment , Ġanimated ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġpending . first ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġpush Fragment ( fragment : ĠFragment , Ġanimated : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtrans Ġ= Ġthis . support FragmentManager ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. beginTransaction () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. replace ( this . view Id , Ġfragment ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. addTo Back Stack ( null ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! animated ) Ġtrans . set Custom Animations ( 0 , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtrans . commit () ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprotected Ġopen Ġfun Ġcreate Fragment Container View (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġview Id Ġ= ĠView . generate View Id () ĊĊĠĠĠĠĠĠĠ Ġval Ġparams Ġ= ĠViewGroup . LayoutParams ( ViewGroup . LayoutParams . MATCH _ PARENT , ĠViewGroup . LayoutParams . MATCH _ PARENT ) ĊĠĠĠĠĠĠĠ Ġval Ġlayout Ġ= ĠLinearLayout ( this . application Context ) ĊĠĠĠĠĠĠĠ Ġlayout . layout Params Ġ= Ġparams ĊĠĠĠĠĠĠĠ Ġlayout . orientation Ġ= ĠLinearLayout . VERTICAL ĊĠĠĠĠĠĠĠ ĠsetContentView ( layout , Ġparams ) ĊĠĠĠĠĠĠĠ Ġlayout . id Ġ= Ġview Id ĊĠĠĠĠĠĠĠ Ġreturn Ġview Id ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġstate DidChange ( from : ĠS , Ġto : ĠS ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( this . is Destroyed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" activity Ġhas Ġbeen Ġdestroyed !") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġsuper . state DidChange ( from , Ġto ) ĊĠĠĠĠĠĠĠ Ġthis . delegate ?. state DidChange ( from , Ġto ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġopen Ġfun Ġdefault State (): ĠS Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġthis . intent . get Bundle Extra ( FLOW KIT _ B UNDLE _ CONTEXT ). get (" state ") Ġas ĠS ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsetup ( savedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . view Id Ġ= Ġcreate Fragment Container View () ĊĠĠĠĠĠĠĠ Ġthis . viewModel . delegate Ġ= Ġthis ĊĊĠĠĠĠĠĠĠ Ġ// Ġcheck Ġthe ĠViewModel 's Ġstate . ĠIf Ġwe Ġhave Ġone Ġin Ġmemory Ġit 's Ġvery Ġlikely Ġthat Ġit Ġis Ġmore ĊĠĠĠĠĠĠĠ Ġ// Ġup Ġto Ġdate Ġthen Ġour Ġsaved Ġinstance . ĊĠĠĠĠĠĠĠ Ġif Ġ( this . viewModel . state Ġ== Ġnull ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġdon 't Ġhave Ġa ĠViewModel Ġstate , Ġlet 's Ġtry Ġto Ġload Ġone Ġfrom Ġour Ġsaved Ġinstance . ĠF ailing ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthat Ġwe 'll Ġload Ġthe Ġdefault Ġstate ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Ġ= Ġif Ġ( savedInstanceState Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( savedInstanceState . get (" state ") Ġas ? ĠS ) Ġ?: Ġthis . default State () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . default State () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġload Ġour Ġstate Ġmachine ... ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . viewModel . state Ġ= Ġstate ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( this . local ClassName , Ġ" loading Ġstate : Ġ${ state }") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġjump Ġinto Ġthe Ġstate Ġmachine ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . viewModel . jump To State ( state ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠJump Ġto Ġthe Ġsaved Ġstate Ġif Ġthere Ġis Ġone . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠUse Ġcase : ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠ 1 . ĠPut Ġthe Ġapp Ġto Ġthe Ġbackground ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠ 2 . ĠReceive Ġpush Ġnotification ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠ 3 . ĠSelect Ġthe Ġnotification Ġto Ġopen Ġthe Ġapp ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWithout Ġjump ing Ġto Ġthe Ġsaved Ġstate , Ġthe Ġapp Ġwould Ġpresent Ġa Ġblank Ġscreen ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . viewModel . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate ?. let Ġ{ Ġjump To State ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Call Super ĊĠĠĠ Ġoverride Ġfun ĠonCreate ( savedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . onCreate ( savedInstanceState ) ĊĠĠĠĠĠĠĠ Ġ// clear Ġout Ġthe ĠviewModel Ġfor Ġapp Ġrestore ĊĠĠĠĠĠĠĠ Ġthis . viewModel . state Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġsetup ( savedInstanceState ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Call Super ĊĠĠĠ Ġoverride Ġfun Ġon Save InstanceState ( out State : ĠBundle ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Save InstanceState ( out State ) ĊĠĠĠĠĠĠĠ Ġval Ġstate Ġ= Ġthis . viewModel . state ĊĠĠĠĠĠĠĠ ĠLog . d ( this . local ClassName , Ġ" saving Ġstate : Ġ${ state }") ĊĠĠĠĠĠĠĠ Ġout State . put (" state ", Ġstate ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Call Super ĊĠĠĠ Ġoverride Ġfun Ġon Activity Result ( request Code : ĠInt , ĠresultCode : ĠInt , Ġdata : ĠIntent ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Activity Result ( request Code , ĠresultCode , Ġdata ) ĊĠĠĠĠĠĠĠ Ġthis . viewModel . pending Ġ= Ġtrue ĊĠĠĠĠĠĠĠ ĠFlow Dispatcher . dispatch ( request Code , ĠresultCode , Ġdata ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprotected Ġfun Ġfinish ( result : ĠResult < O >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġintent Ġ= Ġresult . to Intent () ĊĠĠĠĠĠĠĠ Ġval Ġcode Ġ= Ġwhen ( result ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResult . Success Ġ-> ĠActivity . RESULT _ OK ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResult . Failure Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult . cause . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠActivity . RESULT _ C ANCE LED ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġthis . set Result ( code , Ġintent ) ĊĠĠĠĠĠĠĠ Ġthis . finish () ĊĠĠĠĠĠĠĠ ĠState Machine ViewModel Provider . finish ( this ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprotected Ġfun Ġclear Provider (){ ĊĠĠĠĠĠĠĠ ĠState Machine ViewModel Provider . finish ( this ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġresolve ( result : ĠO ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( this . is Destroyed ) Ġreturn ĊĠĠĠĠĠĠĠ Ġthis . finish ( Result . Success ( result )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġreject ( cause : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( this . is Destroyed ) Ġreturn ĊĠĠĠĠĠĠĠ Ġthis . finish ( Result . Failure ( cause )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Back Pressed () Ġ{ ĊĠĠĠĠĠĠĠ Ġ( this . support FragmentManager . fragments . first OrNull () Ġas ? ĠBack able )?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . on Back Pressed () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġsuper . on Back Pressed () ĊĠĠĠ Ġ} Ċ } Ċ Ċ abstract Ġclass ĠBootstrap Activity : ĠState Machine Activity < Bootstrap Activity . State , ĠUnit , ĠUnit >(), ĠState Machine < Bootstrap Activity . State , ĠUnit , ĠUnit > Ġ{ ĊĊĠĠĠ Ġsealed Ġclass ĠState : ĠFlow State Ġ{ ĊĠĠĠĠĠĠĠ Ġ@ Parcel ize Ġclass ĠBegin ( val Ġcontext : ĠUnit ): ĠState (), ĠParcel able ĊĠĠĠĠĠĠĠ Ġ@ Parcel ize Ġclass ĠFail ( val Ġcontext : ĠThrowable ): ĠState (), ĠParcel able ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġdefault State () Ġ= ĠcreateState ( Unit ) ĊĠĠĠ Ġoverride Ġfinal Ġfun ĠcreateState ( context : ĠUnit ) Ġ= ĠState . Begin ( context = context ) ĊĠĠĠ Ġoverride Ġfun ĠcreateState ( error : ĠThrowable ): ĠState Ġ= ĠState . Fail ( context = error ) ĊĊĠĠĠ Ġoverride Ġfinal Ġfun Ġdispatch ( prev : ĠState , Ġstate : ĠState ): ĠPromise < State > Ġ= ĊĠĠĠĠĠĠĠ Ġon Begin ( state = prev , Ġcontext = Unit ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. recover Ġ{ Ġon Fail ( state = prev , Ġcontext = it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. ensure Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( Bootstrap Activity :: class . java . simple Name , Ġ" Bootstrap ĠState Machine Ġwas Ġresolved , Ġrestart ing Ġnow ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdispatch ( prev = prev , Ġstate = prev ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġdefault State () Ġ} ĊĊĠĠĠ Ġoverride Ġfinal Ġfun Ġget Result ( state : ĠState ): ĠResult < Unit >? Ġ= Ġnull ĊĠĠĠ Ġoverride Ġfinal Ġfun Ġon Terminate ( state : ĠState , Ġcontext : ĠResult < Unit >) Ġ: Ġ ĠPromise < Unit > Ġ= ĊĠĠĠĠĠĠĠ Ġwhen Ġ( context ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResult . Success Ġ-> ĠPromise . value ( context . value ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResult . Failure Ġ-> ĠPromise ( error = context . cause ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġabstract Ġfun Ġon Begin ( state : ĠState , Ġcontext : ĠUnit ): ĠPromise < Unit > ĊĠĠĠ Ġopen Ġfun Ġon Fail ( state : ĠState , Ġcontext : ĠThrowable ): ĠPromise < Unit > Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . e ( Bootstrap Activity :: class . java . simple Name , Ġ" Un caught Ġerror Ġoccured ", Ġcontext ) ĊĠĠĠĠĠĠĠ Ġreturn ĠPromise . value ( Unit ) ĊĠĠĠ Ġ} Ċ }