/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 2 0 ĠThe ĠAndroid ĠOpen ĠSource ĠProject Ċ Ġ* Ċ Ġ* Ġ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 Ġcom . android . tools . idea . ui . resourcemanager . rendering Ċ Ċ import Ġcom . android . tools . idea . ui . resourcemanager . model . Asset Ċ import Ġcom . android . tools . idea . ui . resourcemanager . model . Asset Key Ċ import Ġcom . google . common . cache . Cache Ċ import Ġcom . google . common . cache . Cache Builder Ċ import Ġcom . intellij . openapi . Disposable Ċ import Ġcom . intellij . openapi . util . Dis poser Ċ import Ġcom . intellij . util . concurrency . Ed t ExecutorService Ċ import Ġcom . intellij . util . ui . update . Mer ging Update Queue Ċ import Ġcom . intellij . util . ui . update . Update Ċ import Ġorg . jetbrains . annotations . Async Ċ import Ġjava . awt . image . Buffered Image Ċ import Ġjava . util . concurrent . Comp letableFuture Ċ import Ġjava . util . concurrent . Executor Ċ import Ġjava . util . concurrent . TimeUnit Ċ import Ġkotlin . math . pow Ċ Ċ private Ġval ĠCACHE _ WEIGHT _ BYTES Ġ= Ġ( 1 0 0 Ġ* Ġ 1 0 2 4 . 0 . pow ( 2 )). to Long () Ġ// Ġ 1 0 0 ĠMB Ċ Ċ /** Ċ Ġ* ĠHelper Ġclass Ġthat Ġcaches Ġthe Ġresult Ġof Ġa Ġcomputation Ġof Ġ[ Buffered Image ]. Ċ Ġ* Ċ Ġ* ĠThe Ġkeys Ġof Ġthe Ġcache Ġare Ġstrong Ġreferences Ġto Ġlet Ċ Ġ* Ġ@ see ĠCache Ċ Ġ* Ġ@ see ĠCache Builder . soft Values Ċ Ġ*/ Ċ class ĠImage Cache Ġprivate Ġconstructor ( mer ging Update Queue : ĠMer ging Update Queue ?, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġobject To Image : ĠCache < Asset Key , ĠBufferedImage > Ċ ) Ġ: ĠDis posable Ġ{ ĊĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠ Ġprivate Ġval Ġobject To Image Cache Ġby Ġlazy Ġ{ ĊĠĠĠĠĠ Ġcreate Object To Image Cache ( 5 , ĠCACHE _ WEIGHT _ BYTES ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġan ĠImage Cache Ġthat Ġuses Ġan Ġimage Ġpool Ġof Ġsize Ġ[ CACHE _ WEIGHT _ BYTES ] Ġto Ġstore Ġpre views Ġfor Ġa Ġgiven Ġ[ Asset ] ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġparent Disposable ĠUsed Ġto Ġdispose Ġof Ġthe Ġreturned Ġ[ Image Cache ], Ġused Ġas Ġthe Ġparent Ġdis posable Ġfor Ġthe Ġdefault ĊĠĠĠĠ Ġ* Ġ[ Mer ging Update Queue ] Ġwhen Ġthe Ġ[ mer ging Update Queue ] Ġparameter Ġis Ġnull . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġcreate Image Cache ( ĊĠĠĠĠĠ Ġparent Disposable : ĠDis posable , ĊĠĠĠĠĠ Ġmerging Update Queue : ĠMer ging Update Queue ? Ġ= Ġnull ĊĠĠĠ Ġ) Ġ= ĠImage Cache ( mer ging Update Queue , Ġobject To Image Cache ). apply Ġ{ ĠDis poser . register ( parent Disposable , Ġthis ) Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġval Ġpending F utures Ġ= ĠHashMap < Asset , ĠCompletableFuture < *> ?> () ĊĊĠ Ġprivate Ġval Ġupdate Queue Ġ= Ġmerging Update Queue Ġ?: ĠMer ging Update Queue (" queue ", Ġ 3 0 0 0 , Ġtrue , ĠMer ging Update Queue . ANY _ COMPONENT , Ġthis , Ġnull , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠ Ġfalse ) ĊĊĠ Ġ@ Async . Schedule ĊĠ Ġprivate Ġfun Ġrun Or Queue ( asset : ĠAsset , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexecute Immediate ly : ĠBoolean Ġ= Ġfalse , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrunnable : Ġ() Ġ-> ĠUnit ) Ġ{ ĊĠĠĠ Ġ// ĠWe Ġmap Ġto Ġnull Ġto Ġmark Ġthat Ġthe Ġcomputation Ġfor Ġasset Ġhas Ġstarted Ġand Ġavoid Ġany Ġnew Ġcomputation . ĊĠĠĠ Ġ// ĠIt Ġwill Ġthen Ġbe Ġreplaced Ġby Ġthe Ġcomputation Ġfuture Ġonce Ġit Ġis Ġcreated . ĊĠĠĠ Ġpending F utures [ asset ] Ġ= Ġnull ĊĠĠĠ Ġif Ġ( execute Immediate ly ) Ġ{ ĊĠĠĠĠĠ Ġrunnable () ĊĠĠĠ Ġ} ĊĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠ Ġval Ġupdate Ġ= ĠUpdate . create ( asset . name , Ġrunnable ) ĊĠĠĠĠĠ Ġupdate Queue . queue ( update ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġdispose () Ġ{ ĊĠĠĠ Ġsynchronized ( pending F utures ) Ġ{ ĊĠĠĠĠĠ Ġpending F utures . values . forEach Ġ{ Ġit ?. cancel ( true ) Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġfun Ġclear ( asset : ĠAsset ) Ġ{ ĊĠĠĠ Ġobject To Image . invalidate ( asset . key ) ĊĠ Ġ} ĊĊĠ Ġfun Ġclear () Ġ{ ĊĠĠĠ Ġobject To Image . invalidate All () ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠReturn Ġthe Ġvalue Ġidentified Ġby Ġ[ Asset Key ] Ġin Ġthe Ġcache Ġif Ġit Ġexists , Ġotherwise Ġreturns Ġthe Ġ[ placeholder ] Ġimage ĊĠĠ Ġ* Ġand Ġgets Ġthe Ġimage Ġfrom Ġthe Ġ[ Comp letableFuture ] Ġreturned Ġby Ġ[ computation Future Provider ]. ĊĠĠ Ġ* ĊĠĠ Ġ* ĠIf Ġ[ force Computation ] Ġis Ġtrue , Ġthe Ġ[ Comp letableFuture ] Ġwill Ġbe Ġran Ġeven Ġif Ġa Ġvalue Ġis Ġpresent Ġin Ġthe Ġcache . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠNote Ġthat Ġif Ġa Ġvalue Ġis Ġpresent Ġin Ġthe Ġcache Ġand Ġ[ force Computation ] Ġis Ġtrue , Ġthe Ġreturned Ġ[ Buffered Image ] Ġwill Ġbe Ġthe Ġvalue Ġfrom ĊĠĠ Ġ* Ġthe Ġcache . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠOnce Ġthe Ġimage Ġis Ġcached , Ġ[ on Image Cached ] Ġis Ġinvoked Ġon Ġ[ executor ] Ġ( or Ġthe ĠE DT Ġif Ġnone Ġis Ġprovided ) ĊĠĠ Ġ*/ ĊĠ Ġfun Ġcompute AndGet (@ Async . Schedule Ġasset : ĠAsset , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplaceholder : ĠBufferedImage , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġforce Computation : ĠBoolean , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Image Cached : Ġ() Ġ-> ĠUnit Ġ= Ġ{}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexecutor : ĠExecutor Ġ= ĠE dt ExecutorService . getInstance (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcomputation Future Provider : Ġ(() Ġ-> ĠCompletableFuture < out ĠBufferedImage ?> )) ĊĠĠĠ Ġ: ĠBufferedImage Ġ{ ĊĠĠĠ Ġval Ġcached Image Ġ= Ġobject To Image . get If Present ( asset . key ) ĊĠĠĠ Ġif Ġ(( cached Image Ġ== Ġnull Ġ|| Ġforce Computation ) Ġ&& Ġ! pending F utures . containsKey ( asset )) Ġ{ ĊĠĠĠĠĠ Ġval Ġexecute Immediate ly Ġ= Ġcached Image Ġ== Ġnull Ġ// ĠIf Ġwe Ġdon 't Ġhave Ġany Ġimage , Ġno Ġneed Ġto Ġwait . ĊĠĠĠĠĠ Ġrun Or Queue ( asset , Ġexecute Immediate ly ) Ġ{ ĊĠĠĠĠĠĠĠ Ġstart Computation ( computation Future Provider , Ġasset , Ġon Image Cached , Ġexecutor ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġcached Image Ġ?: Ġplaceholder ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġstart Computation ( computation Future Provider : Ġ() Ġ-> ĠCompletableFuture < out ĠBufferedImage ? >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Async . Execute Ġasset : ĠAsset , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Image Cached : Ġ() Ġ-> ĠUnit , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexecutor : ĠExecutor ) Ġ{ ĊĠĠĠ Ġval Ġfuture Ġ= Ġcomputation Future Provider () ĊĠĠĠĠĠ Ġ. then Accept Ġ{ Ġimage : ĠBufferedImage ? Ġ-> ĊĠĠĠĠĠĠĠ Ġsynchronized ( pending F utures ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġpending F utures . remove ( asset ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( image Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġobject To Image . put ( asset . key , Ġimage ) ĊĠĠĠĠĠĠĠĠĠ Ġexecutor . execute ( on Image Cached ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġsynchronized ( pending F utures ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ(! future . is Done ) Ġ{ ĊĠĠĠĠĠĠĠ Ġpending F utures [ asset ] Ġ= Ġfuture ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġcreate Object To Image Cache ( duration : ĠLong , Ġsize : ĠLong ): ĠCache < Asset Key , ĠBufferedImage > Ġ= ĊĠ ĠCache Builder . newBuilder () ĊĠĠĠ Ġ. expire After Access ( duration , ĠTimeUnit . MIN UTES ) ĊĠĠĠ Ġ. soft Values () ĊĠĠĠ Ġ. we igh er < Asset Key , ĠBufferedImage > Ġ{ Ġ_, Ġimage Ġ-> Ġimage . raster . data Buffer . size Ġ* ĠInteger . BYTES Ġ} ĊĠĠĠ Ġ. maximum Weight ( size ) ĊĠĠĠ Ġ. build < Asset Key , ĠBufferedImage >()