package Ġcom . github . c 5 fr 7 q . jun gle Ċ Ċ import Ġcom . github . c 5 fr 7 q . jun gle . command .* Ċ import Ġio . reactivex . Observable Ċ import Ġio . reactivex . Scheduler Ċ import Ġio . reactivex . dis pos ables . Composite Disposable Ċ import Ġio . reactivex . subjects . Behavior Subject Ċ import Ġio . reactivex . subjects . Publish Subject Ċ import Ġio . reactivex . subjects . Replay Subject Ċ Ċ abstract Ġclass ĠStore < Event , ĠState , ĠAction >( Ċ ĉ private Ġval Ġforeground Scheduler : ĠScheduler , Ċ ĉ private Ġval Ġbackground Scheduler : ĠScheduler Ċ ) Ġ{ ĊĊ ĉ private Ġval Ġcommands Ġ= ĠPublish Subject . create < Command >() Ċ ĉ private Ġval Ġstates Ġ= ĠBehavior Subject . create < State >() Ċ ĉ private Ġval Ġactions Ġ= ĠPublish Subject . create < Action >() ĊĊ ĉ private Ġval Ġsubscriptions Ġ= ĠComposite Disposable () ĊĊ ĉ private Ġvar Ġattached Ġ= Ġfalse ĊĊ ĉ protected Ġopen Ġval ĠinitialState : ĠState Ċĉ ĉ get () Ġ= Ġthrow ĠNotImplementedException () Ċ ĉ protected Ġopen Ġval Ġbootstrap Commands Ġ= Ġempty List < Command >() Ċ ĉ protected Ġopen Ġval Ġstate ful Middle wares Ġ= Ġempty List < State ful Middleware < *, ĠState >>() Ċ ĉ protected Ġopen Ġval Ġmiddle wares Ġ= Ġempty List < Middleware <* >>() ĊĊ ĉ fun Ġdispatch Event ( event : ĠEvent ) Ġ{ Ċĉ ĉ dispatchEvent Source ( Observable . just ( event )) Ċ ĉ } ĊĊ ĉ fun Ġdispatch EventSource ( event Source : ĠObservable < Event >) Ġ{ Ċĉ ĉ if Ġ( attached ) Ġ{ Ċĉĉ ĉ subscriptions . add ( Ċĉĉĉ ĉ event Source . observe On ( foreground Scheduler ). subscribe Ġ{ Ġevent Ġ-> Ċĉĉĉĉ ĉ try Ġ{ Ċĉĉĉĉĉ ĉ val Ġcommand Ġ= Ġconvert Event ( event ) Ċĉĉĉĉĉ ĉ commands . onNext ( command ) Ċĉĉĉĉ ĉ } Ġcatch Ġ( ignored : ĠNotImplementedException ) Ġ{ Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } Ċĉĉ ĉ ) Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ fun Ġattach ( view : ĠM vi View < State , ĠAction >) Ġ{ Ċĉ ĉ val Ġbootstrap Commands Source Ġ= ĠObservable . from Iterable ( bootstrap Commands ) Ċĉ ĉ val Ġcommand Source Subject : ĠRe play Subject < Command > Ġ= ĠRe play Subject . create () Ċĉ ĉ commands . let Ġ{ Ġbootstrap Commands Source . merge With ( it ) Ġ?: Ġit Ġ} Ċĉĉ ĉ . subscribe On ( background Scheduler ) Ċĉĉ ĉ . subscribe ( command Source Subject ) Ċĉ ĉ subscriptions . add ( Ċĉĉ ĉ command Source Subject . observe On ( foreground Scheduler ). subscribe Ġ{ Ġcommand Ġ-> Ċĉĉĉ ĉ produce Action ( command )?. let Ġ{ Ġactions . onNext ( it ) Ġ} Ċĉĉ ĉ } Ċĉ ĉ ) Ċĉ ĉ val Ġcommand Result Source Subject : ĠRe play Subject < Command Result > Ġ= ĠRe play Subject . create () Ċĉ ĉ Observable . merge ( Ċĉĉ ĉ execute Commands ( command Source Subject , Ġstates ), Ċĉĉ ĉ command Source Subject . of Type ( Command Command Result :: class . java ) Ċĉ ĉ ). subscribe ( command Result Source Subject ) Ċĉ ĉ subscriptions . add ( Ċĉĉ ĉ command Result Source Subject . subscribe Ġ{ Ġcommand Result Ġ-> Ċĉĉĉ ĉ produce Command ( command Result )?. let Ġ{ Ġcommands . onNext ( it ) Ġ} Ċĉĉ ĉ } Ċĉ ĉ ) Ċĉ ĉ try Ġ{ Ċĉĉ ĉ if Ġ(! states . hasValue ()) Ġ{ Ċĉĉĉ ĉ states . onNext ( initialState ) Ċĉĉ ĉ } Ċĉĉ ĉ val Ġinit State Ġ= Ġstates . value !! Ċĉĉ ĉ subscriptions . add ( Ċĉĉĉ ĉ command Result Source Subject . scan ( init State , Ġ{ Ġstate , Ġcommand Result Ġ-> Ġreduce Command Result ( state , Ġcommand Result ) Ġ}) Ċĉĉĉĉ ĉ . distinct Until Changed () Ċĉĉĉĉ ĉ . subscribe Ġ{ Ġstates . onNext ( it ) Ġ} Ċĉĉ ĉ ) Ċĉ ĉ } Ġcatch Ġ( ignored : ĠNotImplementedException ) Ġ{ Ċĉ ĉ } Ċĉ ĉ subscriptions . add ( Ċĉĉ ĉ states . observe On ( foreground Scheduler ). subscribe Ġ{ Ġview . render ( it ) Ġ} Ċĉ ĉ ) Ċĉ ĉ subscriptions . add ( Ċĉĉ ĉ actions . observe On ( foreground Scheduler ). subscribe Ġ{ Ġview . process Action ( it ) Ġ} Ċĉ ĉ ) Ċĉ ĉ attached Ġ= Ġtrue Ċ ĉ } ĊĊ ĉ fun Ġdetach () Ġ{ Ċĉ ĉ subscriptions . dispose () Ċĉ ĉ attached Ġ= Ġfalse Ċ ĉ } ĊĊ ĉ protected Ġopen Ġfun Ġconvert Event ( event : ĠEvent ): ĠCommand Ġ= Ġthrow ĠNotImplementedException () Ċ ĉ protected Ġopen Ġfun Ġproduce Action ( command : ĠCommand ): ĠAction ? Ġ= Ġnull Ċ ĉ protected Ġopen Ġfun Ġproduce Command ( command Result : ĠCommand Result ): ĠCommand ? Ġ= Ġnull Ċ ĉ protected Ġopen Ġfun Ġreduce Command Result ( state : ĠState , Ġcommand Result : ĠCommand Result ): ĠState Ġ= Ġstate ĊĊ ĉ private Ġfun Ġexecute Commands ( commands : ĠObservable < Command >, Ġstate : ĠObservable < State >): ĠObservable < Command Result > Ġ= Ċĉ ĉ commands . publish Ġ{ Ġcommand Source Ġ-> Ċĉĉ ĉ state ful Middle wares . forEach Ġ{ Ġit . attach State ( state ) Ġ} Ċĉĉ ĉ Observable . merge ( mutable ListOf < Observable < Command Result >> (). apply Ġ{ Ċĉĉĉ ĉ addAll ( state ful Middle wares . map Ġ{ Ġcommand Source . compose ( it ) Ġ}) Ċĉĉĉ ĉ addAll ( middle wares . map Ġ{ Ġcommand Source . compose ( it ) Ġ}) Ċĉĉ ĉ }) Ċĉ ĉ } Ċ } Ċ