package Ġcom . m ct ech . architecture . mv vm . x . core Ċ Ċ import Ġandroidx . lifecycle . LiveData Ċ import Ġandroidx . lifecycle . ViewModel Ċ import Ġandroidx . lifecycle . viewModel Scope Ċ import Ġkotlinx . coroutines . launch Ċ import Ġjava . util .* Ċ import Ġkotlin . reflect . K Class Ċ import Ġkotlin . reflect . full . call Suspend Ċ import Ġkotlin . reflect . jvm . is Accessible Ċ Ċ /** Ċ Ġ* ĠI Ġdo Ġnot Ġlike Ġ' Base ' Ġclasses . ĠBut Ġin Ġthis Ġcase , Ġit Ġhelps Ġa Ġlot . Ċ Ġ* ĠThis Ġclass Ġis Ġbasically Ġa Ġsimple ĠViewModel , Ġbut Ġit Ġalso Ġkeep Ġthe Ġwhole Ġuser Ġflow Ġinteractions Ġwith Ġyour Ġscreen . Ċ Ġ* Ċ Ġ*/ Ċ abstract Ġclass ĠBase ViewModel Ġ: ĠViewModel () Ġ{ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIt Ġis Ġgonna Ġkeep Ġthe Ġwhole Ġuser Ġflow Ġon Ġyour Ġview . ĊĠĠĠĠ Ġ* ĠSo Ġlet 's Ġsay Ġsome Ġerror Ġhappen , Ġyou Ġcould Ġprint Ġthe Ġwhole Ġstack Ġtrace Ġand Ġsend Ġit Ġto Ġyour Ġbackend Ġerror Ġlog . ĊĠĠĠĠ Ġ* ĠIt Ġwill Ġhelp Ġyou Ġto Ġtrace Ġyour Ġissues Ġon Ġyour Ġcode Ġand Ġmake Ġthe Ġtesting Ġprocess Ġeasier . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġuser Flow Interaction Ġ= ĠStack < User Interaction >() ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIt Ġkeeps Ġthe Ġconsumers Ġfor Ġeach Ġuser Ġinteraction Ġon Ġthe Ġflow . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprotected Ġvar Ġmapped User Interactions Ġ= Ġhash Map Of < K Class < out ĠUser Interaction >, Ġsuspend Ġ( User Interaction ) Ġ-> ĠUnit >() ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġis Ġonly Ġa Ġsimple Ġobservable Ġthat Ġyour Ġview Ġwill Ġbe Ġob serving Ġto Ġhandle Ġsome Ġcommand . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġ_ command Observable Ġ= ĠSingle Live Event < View Command >() ĊĠĠĠ Ġval Ġcommand Observable Ġ: ĠLive Data < View Command > Ġget () Ġ= Ġ_ command Observable ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġmap Interaction Observer s () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCalled Ġby Ġview Ġto Ġsend Ġ' an Ġinteraction ' Ġto Ġthe Ġview Ġmodel Ġby Ġusing Ġthe Ġview Ġmodel Ġscope . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġinteract ( user Interaction : ĠUser Interaction ) Ġ{ ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsus pended Interaction ( user Interaction ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCalled Ġby Ġview Ġto Ġsend Ġ' a Ġsus pended Ġinteraction ' Ġto Ġthe Ġview Ġmodel . ĊĠĠĠĠ Ġ* ĠIt 's Ġcalled Ġwhen Ġthe Ġsus pended Ġfunction Ġmust Ġbe Ġconnect Ġwith Ġthe Ġview Ġlife Ġcycle . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġsus pended Interaction ( user Interaction : ĠUser Interaction ) Ġ{ ĊĠĠĠĠĠĠĠ Ġuser Flow Interaction . push ( user Interaction ) ĊĠĠĠĠĠĠĠ Ġinternal Interaction Handler ( user Interaction ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIt Ġis Ġthe Ġfunction Ġthat Ġis Ġcalled Ġevery Ġsingle Ġinteraction Ġthe Ġscreen Ġsend . ĊĠĠĠĠ Ġ* ĠSo Ġyou Ġcan Ġbasically Ġoverride Ġit Ġand Ġhandle Ġthe Ġspecific Ġinteraction Ġby Ġusing Ġa Ġ' when ' Ġflow Ġfor Ġexample . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprotected Ġopen Ġsuspend Ġfun Ġhandle User Interaction ( interaction : ĠUser Interaction ) Ġ= ĠUnit ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIt Ġis Ġthe Ġfunction Ġthat Ġis Ġcalled Ġevery Ġsingle Ġinteraction Ġthe Ġscreen Ġsend . ĊĠĠĠĠ Ġ* ĠSo Ġyou Ġcan Ġbasically Ġoverride Ġit Ġand Ġhandle Ġthe Ġspecific Ġinteraction Ġby Ġusing Ġa Ġ' when ' Ġflow Ġfor Ġexample . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġinternal Interaction Handler ( interaction : ĠUser Interaction ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠIt Ġis Ġa Ġmapped Ġfunction ĊĠĠĠĠĠĠĠ Ġif ( mapped User Interactions . containsKey ( interaction :: class )){ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmapped User Interactions [ interaction :: class ]?. invoke ( interaction ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠHandle Ġby Ġusing Ġlegacy Ġway ĊĠĠĠĠĠĠĠ Ġhandle User Interaction ( interaction ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠUsed Ġto Ġsend Ġa Ġcommand Ġto Ġyour Ġview . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprotected Ġopen Ġsuspend Ġfun Ġsend Command ( view Command : ĠView Command ){ ĊĠĠĠĠĠĠĠ Ġ_ command Observable . value Ġ= Ġview Command ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠLet 's Ġsay Ġthe Ġuser Ġhas Ġfilled Ġin Ġyour Ġlogin Ġform . ĠWhen Ġthe Ġ' Sign Ġin ' Ġbutton Ġis Ġpressed ĊĠĠĠĠ Ġ* Ġyour Ġview Ġwill Ġsend Ġa Ġ' Try Login Interaction ( user , Ġpassword )' Ġto Ġyour Ġview Ġmodel Ġhandle Ġit . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠBut Ġsome Ġerror Ġhappen Ġand Ġyour Ġview Ġwill Ġreceive Ġa Ġerror Ġstate . ĠBut Ġyou Ġw anna Ġtry Ġto Ġsign Ġin Ġagain . ĊĠĠĠĠ Ġ* ĠSo , Ġinstead Ġof Ġcreate Ġanother Ġinteraction Ġand Ġsend Ġto Ġthe Ġview Ġmodel . ĠYou Ġcould Ġjust Ġcall Ġthis Ġmethod ĊĠĠĠĠ Ġ* Ġand Ġit Ġwill Ġmake Ġsure Ġto Ġcall Ġthe Ġlast Ġinteraction Ġyou 've Ġtried Ġto Ġsend . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġre process Last Interaction () Ġ{ ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsus pended Re process Last Interaction () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġsus pended Re process Last Interaction () Ġ{ ĊĠĠĠĠĠĠĠ Ġinternal Interaction Handler ( user Flow Interaction . last ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIf Ġyou Ġneed Ġto Ġcheck Ġif Ġthere Ġis Ġa Ġspecific Ġinteraction Ġon Ġyour Ġflow . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġ< T Ġ: ĠUser Interaction > Ġhas Interaction On Flow ( item Ġ: ĠT ) Ġ: ĠBoolean { ĊĠĠĠĠĠĠĠ Ġreturn Ġuser Flow Interaction . first OrNull () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . java Class Ġ== Ġitem . java Class ĊĠĠĠĠĠĠĠ Ġ} Ġ!= Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIf Ġyou Ġneed Ġto Ġcheck Ġif Ġthere Ġis Ġa Ġspecific Ġinteraction Ġon Ġyour Ġflow . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġ< T Ġ: ĠUser Interaction > Ġhas More Interaction On Flow Then ( item Ġ: ĠT , Ġcount Ġ: ĠInt ) Ġ: ĠBoolean { ĊĠĠĠĠĠĠĠ Ġreturn Ġuser Flow Interaction . count Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . java Class Ġ== Ġitem . java Class ĊĠĠĠĠĠĠĠ Ġ} Ġ> Ġcount ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġis Ġexperimental . ĠYou Ġshould Ġnot Ġuse Ġthis Ġcode Ġon Ġproduction Ġcode . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġmap Interaction Observer s () Ġ{ ĊĠĠĠĠĠĠĠ Ġthis :: class . members . forEach Ġ{ Ġmember Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmember . annotations . forEach Ġ{ Ġannotation Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( annotation Ġis ĠOn Interaction ){ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmember . is Accessible Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmapped User Interactions [ annotation . target ] Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( member . parameters . size Ġ<= Ġ 1 ){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmember . call Suspend ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse { ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmember . call Suspend ( this , Ġit ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Cle ared () Ġ{ ĊĠĠĠĠĠĠĠ Ġuser Flow Interaction . clear () ĊĠĠĠĠĠĠĠ Ġsuper . on Cle ared () ĊĠĠĠ Ġ} Ċ }