/** Ċ Ġ* ĠBack pack Ġfor ĠAndroid Ġ- ĠSky scanner 's ĠDesign ĠSystem Ċ Ġ* Ċ Ġ* ĠCopyright Ġ 2 0 1 8 - 2 0 2 1 ĠSky scanner ĠLtd Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġnet . sky scanner . back pack . util Ċ Ċ import Ġkotlinx . coroutines . Coroutine Scope Ċ import Ġkotlinx . coroutines . flow . Mutable Shared Flow Ċ import Ġkotlinx . coroutines . flow . Mutable State Flow Ċ import Ġkotlinx . coroutines . flow . Shared Flow Ċ import Ġkotlinx . coroutines . flow . State Flow Ċ import Ġkotlinx . coroutines . launch Ċ import Ġkotlinx . coroutines . sync . Mutex Ċ import Ġkotlinx . coroutines . sync . with Lock Ċ Ċ /** Ċ Ġ* ĠState Machine Ġap is Ġare Ġused Ġfor Ġsome Ġcomplex Ġcomponents Ġwith Ġsome Ġstate Ġmanagement . Ċ Ġ* Ċ Ġ* ĠEach Ġtime Ġthe Ġstate Ġchanges , Ġa Ġnew Ġversion Ġof Ġit Ġis Ġavailable Ġfor Ġreading Ġin Ġ[ state ]. Ċ Ġ* Ċ Ġ* ĠEach Ġstate Ġchange Ġmay Ġalso Ġem mit Ġa Ġtemporarily Ġexisting Ġ[ effects ] Ġ( for Ġinstance , Ġto Ġshow ĠToast Ġin Ġcase Ġof Ġerror ). Ċ Ġ* Ċ Ġ* ĠThe Ġwidget Ġdecided Ġitself Ġwhen Ġthe Ġstate Ġneeds Ġto Ġbe Ġchanged . ĠIt Ġmay Ġalso Ġprovide Ġsome Ġpublic Ġmethods Ċ Ġ* Ġto Ġhave Ġlimited Ġcontrol Ġover Ġthe Ġstate Ġchanges Ġ( e . g . Ġsettings Ġthe Ġparams ). Ċ Ġ*/ Ċ interface ĠState Machine < State , ĠEffect > Ġ{ ĊĊĠ Ġval Ġstate : ĠState Flow < State > ĊĊĠ Ġval Ġeffects : ĠShared Flow < Effect > Ċ } Ċ Ċ internal Ġinterface ĠMutable StateMachine < State , ĠEffect > Ġ: ĠState Machine < State , ĠEffect > Ġ{ ĊĊĠ Ġinterface ĠCommit Scope < Effect > Ġ{ ĊĊĠĠĠ Ġfun Ġem mit ( effect : ĠEffect ) ĊĠ Ġ} ĊĊĠ Ġfun Ġcommit ( block : Ġsuspend ĠCommit Scope < Effect >. ( State ) Ġ-> ĠState ) Ċ } Ċ Ċ @ Suppress (" FunctionName ") Ċ internal Ġfun Ġ< State , ĠEffect > ĠMutable StateMachine ( ĊĠ Ġscope : ĠCor outine Scope , ĊĠ Ġinitial : ĠState , Ċ ): ĠMutable StateMachine < State , ĠEffect > Ġ{ ĊĊĠ Ġval Ġstate Ġ= ĠMutable State Flow ( initial ) ĊĠ Ġval Ġeffects Ġ= ĠMutable Shared Flow < Effect >() ĊĠ Ġval Ġmutex Ġ= ĠMutex () ĊĊĠ Ġreturn Ġobject Ġ: ĠMutable StateMachine < State , ĠEffect > Ġ{ ĊĊĠĠĠ Ġoverride Ġval Ġeffects : ĠShared Flow < Effect > Ġ= Ġeffects ĊĊĠĠĠ Ġoverride Ġval Ġstate : ĠState Flow < State > Ġ= Ġstate ĊĊĠĠĠ Ġoverride Ġfun Ġcommit ( block : Ġsuspend ĠMutable StateMachine . Commit Scope < Effect >. ( State ) Ġ-> ĠState ) Ġ{ ĊĠĠĠĠĠ Ġscope . launch Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġaccumulator Ġ= ĠEffect s Accumulator < Effect >() ĊĠĠĠĠĠĠĠ Ġmutex . with Lock Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġstate . value Ġ= Ġaccumulator . block ( state . value ) ĊĠĠĠĠĠĠĠĠĠ Ġaccumulator . sink To ( effects ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ Ċ private Ġclass ĠEffect s Accumulator < Effect > Ġ: ĠMutable StateMachine . Commit Scope < Effect > Ġ{ ĊĊĠ Ġprivate Ġvar Ġeffects : ĠMutable List < Effect >? Ġ= Ġnull ĊĊĠ Ġoverride Ġfun Ġem mit ( effect : ĠEffect ) Ġ{ ĊĠĠĠ Ġ( effects Ġ?: Ġmutable ListOf < Effect >(). also Ġ{ Ġeffects Ġ= Ġit Ġ}). add ( effect ) ĊĠ Ġ} ĊĊĠ Ġsuspend Ġfun Ġsink To ( sink : ĠMutable Shared Flow < Effect >) Ġ{ ĊĠĠĠ Ġeffects ?. forEach Ġ{ Ġsink . emit ( it ) Ġ} ĊĠ Ġ} Ċ } Ċ