package Ġcom . pv _ libs . coroutine _ cache pro . api _ caller Ċ Ċ import Ġandroid . util . Log Ċ import Ġcom . pv _ libs . coroutine _ cache pro . Api Result Ċ import Ġcom . pv _ libs . coroutine _ cache pro . utils . is From Cache Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . flow .* Ċ import Ġkotlinx . coroutines . run Blocking Ċ import Ġretrofit 2 . Call Ċ import Ġretrofit 2 . Call Adapter Ċ import Ġretrofit 2 . Response Ċ Ċ internal Ġclass ĠCor outine Api Caller Imp < Network Response >( ĊĠĠĠ Ġprivate Ġval Ġbuilder : ĠBuilder < Network Response > Ċ ) Ġ: ĠCor outine Api Caller < Network Response > Ġ{ ĊĠĠĠ Ġprivate Ġval ĠTAG Ġ= Ġ" Coroutine Api Caller Imp " ĊĠĠĠ Ġprivate Ġval Ġis Api InProgress Mutable State Flow Ġ= ĠMutable State Flow ( false ) ĊĠĠĠ Ġoverride Ġval Ġis Api InProgress S ate Flow : ĠState Flow < Boolean > Ġ= Ġis Api InProgress Mutable State Flow ĊĊĠĠĠ Ġprivate Ġval Ġnetwork Calls Mutable Flow Ġ= ĊĠĠĠĠĠĠĠ ĠMutable Shared Flow < Flow < Response < Network Response >> >() ĊĊĠĠĠ Ġprivate Ġval Ġcache Call Flow Ġ= Ġflow Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" emit Ġget New Cache Call ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( builder . getResponse From Cache ()) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġerror Ġin Ġcache Ġcall Ġis Ġignored ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġresponse Flow Ġ= Ġmerge ( cache Call Flow , Ġnetwork Calls Mutable Flow . flatten Concat ()) ĊĠĠĠĠĠĠĠ Ġ. filter Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" response Flow Ġfilter ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" is Loaded At Least Once Ġ- Ġ$ is Loaded At Least Once ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" is From Cache Ġ- Ġ${ it . is From Cache () }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Loaded At Least Once Ġ&& Ġit . is From Cache ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Loaded At Least Once Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ. map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" response Flow Ġ- ĠApi Result . Success Ġ") ĊĠĠĠĠĠĠĠĠĠĠĠ ĠApi Result . Success ( it ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ. catch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" response Flow Ġ- ĠApi Result . Error ") ĊĠĠĠĠĠĠĠĠĠĠĠ ĠApi Result . Error ( it Ġas ĠException ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ. flow On ( Dispatch ers . IO ) ĊĊĠĠĠ Ġprivate Ġvar Ġis Loaded At Least Once Ġ= Ġfalse ĊĊĠĠĠ Ġoverride Ġfun Ġget Response Flow ( call Server On Collect : ĠBoolean ): ĠFlow < Api Result < Response < Network Response >>> Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( call Server On Collect ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfetch From Server () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġresponse Flow ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġfetch From Server () Ġ{ ĊĠĠĠĠĠĠĠ Ġlog (" fetch From Server ") ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġrun Blocking Ġis Ġonly Ġused Ġbecause Ġbelow Ġfunction Ġnever Ġsus p ends ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnetwork Calls Mutable Flow . emit ( flow Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" emit ĠNew Server Call ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( builder . getResponse From Server ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. onStart Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" is Api InProgress Mutable State Flow . value Ġ= Ġtrue ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Api InProgress Mutable State Flow . value Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. on Completion Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" is Api InProgress Mutable State Flow . value Ġ= Ġfalse ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Api InProgress Mutable State Flow . value Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġlog ( message : ĠString ) Ġ= ĠLog . d ( TAG , Ġmessage ) ĊĊĠĠĠ Ġclass ĠBuilder < Network Response >( ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġoriginal Call : ĠCall < Network Response >, ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġcache Call Adapter : ĠCall Adapter < Network Response , ĠCall < Network Response >>, ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġserver Call Adapter : ĠCall Adapter < Network Response , ĠCall < Network Response >> ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġbuild (): ĠCor outine Api Caller < Network Response > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCor outine Api Caller Imp ( this ) ĊĊĠĠĠĠĠĠĠ Ġfun Ġget Response From Cache (): ĠResponse < Network Response > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcache Call Adapter . adapt ( original Call . clone ()). execute () ĊĊĠĠĠĠĠĠĠ Ġfun Ġget Response From Server (): ĠResponse < Network Response > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġserver Call Adapter . adapt ( original Call . clone ()). execute () ĊĊĠĠĠ Ġ} Ċ Ċ }