/* Ċ Ġ* ĠCopyright Ġ 2 0 1 9 Ġ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 . Ċ Ġ*/ Ċ Ċ @ file : Suppress (" DE PREC ATION ", Ġ" UNUSED _ PARAMETER ") Ċ Ċ package Ġandroidx . ui . core Ċ Ċ import Ġandroidx . compose . Observer Map Ċ import Ġandroidx . compose . frames . Frame Commit Observer Ċ import Ġandroidx . compose . frames . Frame Read Observer Ċ import Ġandroidx . compose . frames . observe All Reads Ċ import Ġandroidx . compose . ui . util . fast ForEach Ċ Ċ /** Ċ Ġ* ĠAllows Ġfor Ġeasy Ġmodel Ġread Ġobservation . ĠTo Ġbegin Ġobserve Ġa Ġchange , Ġyou Ġmust Ġpass Ġa Ċ Ġ* Ġnon - lambda Ġ` on Commit ` Ġlistener Ġto Ġthe Ġ[ observe Reads ] Ġmethod . Ċ Ġ* Ċ Ġ* ĠWhen Ġa Ġstate Ġchange Ġhas Ġbeen Ġcommitted , Ġthe Ġ` on Commit ` Ġlistener Ġwill Ġbe Ġcalled Ċ Ġ* Ġwith Ġthe Ġ` target Object ` Ġas Ġthe Ġargument . ĠThere Ġare Ġno Ġorder Ġguarantees Ġfor Ċ Ġ* Ġ` on Commit ` Ġlistener Ġcalls . ĠCommit Ġcallbacks Ġare Ġmade Ġon Ġthe Ġthread Ġthat Ġmodel Ġchanges Ċ Ġ* Ġare Ġcommitted , Ġso Ġthe Ġ[ commit Executor ] Ġallows Ġthe Ġdeveloper Ġto Ġcontrol Ġthe Ġthread Ġon Ġwhich Ġthe Ċ Ġ* Ġ` on Commit ` calls Ġare Ġmade . ĠAn Ġexample Ġuse Ġwould Ġbe Ġto Ġhave Ġthe Ġexecutor Ġshift Ġto Ġthe Ċ Ġ* Ġthe ĠUI Ġthread Ġfor Ġthe Ġ` on Commit ` Ġcallbacks Ġto Ġbe Ġmade . Ċ Ġ* Ċ Ġ* ĠA Ġdifferent ĠModel Observer Ġshould Ġbe Ġused Ġwith Ġeach Ġthread Ġthat Ġ[ observe Reads ] Ġis Ġcalled Ġon . Ċ Ġ* Ċ Ġ* Ġ@ param Ġcommit Executor ĠThe Ġexecutor Ġon Ġwhich Ġall Ġ` on Commit ` Ġcalls Ġwill Ġbe Ġmade . Ċ Ġ*/ Ċ @ Deprecated (" Frames Ġhave Ġbeen Ġreplaced Ġby Ġsnapshots ", ĊĠĠĠ ĠReplace With ( ĊĠĠĠĠĠĠĠ Ġ" Snapshot State Observer ", ĊĠĠĠĠĠĠĠ Ġ" android x . compose . snapshots " ĊĠĠĠ Ġ) Ċ ) Ċ class ĠModel Observer ( private Ġval Ġcommit Executor : Ġ( command : Ġ() Ġ-> ĠUnit ) Ġ-> ĠUnit ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġcommit Observer : ĠFrame Commit Observer Ġ= Ġ{ Ġcommitted , Ġ_ Ġ-> ĊĠĠĠĠĠĠĠ Ġvar Ġhas Values Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ// ĠThis Ġarray Ġis Ġin Ġthe Ġsame Ġorder Ġas Ġcommit Maps ĊĠĠĠĠĠĠĠ Ġ@ Suppress (" DE PREC ATION _ ERROR ") ĊĠĠĠĠĠĠĠ Ġval Ġtargets Array Ġ= Ġsynchronized ( commit Maps ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠArray ( commit Maps . size ) Ġ{ Ġindex Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcommit Maps [ index ]. map . get ( committed ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( isNotEmpty ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhas Values Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( has Values ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcommit Executor Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcall On Commit ( targets Array ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġ[ Frame Read Observer ] Ġused Ġby Ġthis Ġ[ Model Observer ] Ġduring Ġ[ observe Reads ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġread Observer : ĠFrame Read Observer Ġ= Ġ{ Ġmodel Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ(! is Paused ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Suppress (" DE PREC ATION _ ERROR ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsynchronized ( commit Maps ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Map !!. add ( model , Ġcurrent Target !! ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠList Ġof Ġall Ġ[ Commit Map ] s . ĠWhen Ġ[ observe Reads ] Ġis Ġcalled , Ġthere Ġwill Ġbe ĊĠĠĠĠ Ġ* Ġa Ġ[ Commit Map ] Ġassociated Ġwith Ġits Ġ` on Commit ` Ġcallback Ġin Ġthis Ġlist . ĠThe Ġlist ĊĠĠĠĠ Ġ* Ġonly Ġg rows . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġcommit Maps Ġ= Ġmutable ListOf < Commit Map <* >>() ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠMethod Ġto Ġcall Ġwhen Ġun sub scri bing Ġfrom Ġthe Ġcommit Ġobserver . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġcommit Un subscribe : Ġ(() Ġ-> ĠUnit )? Ġ= Ġnull ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ` true ` Ġwhen Ġan Ġ[ observe Reads ] Ġis Ġin Ġprogress Ġand Ġ[ read Observer ] Ġis Ġactive Ġand ĊĠĠĠĠ Ġ* Ġ` false ` Ġwhen Ġ[ read Observer ] Ġis Ġno Ġlonger Ġob serving Ġchanges . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġis Ob serving Ġ= Ġfalse ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ` true ` Ġwhen Ġ[ pause Ob serving Reads ] Ġis Ġcalled Ġand Ġread Ġobservations Ġshould Ġno ĊĠĠĠĠ Ġ* Ġlonger Ġbe Ġconsidered Ġinvalid ations Ġfor Ġthe Ġ` on Commit ` Ġcallback . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġis Paused Ġ= Ġfalse ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġ[ Observer Map ] Ġthat Ġshould Ġbe Ġadded Ġto Ġwhen Ġa Ġmodel Ġis Ġread Ġduring Ġ[ observe Reads ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġcurrent Map : ĠObserver Map < Any , ĠAny >? Ġ= Ġnull ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġtarget Ġassociated Ġwith Ġthe Ġactive Ġ[ observe Reads ] Ġcall . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġcurrent Target : ĠAny ? Ġ= Ġnull ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠTest - only Ġaccess Ġto Ġthe Ġinternal Ġcommit Ġlistener . ĠThis Ġis Ġused Ġfor Ġbenchmark ing ĊĠĠĠĠ Ġ* Ġthe Ġcommit Ġnotification Ġcallback . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ suppress ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġframe Commit Observer : ĠFrame Commit Observer ĊĠĠĠĠĠĠĠ Ġ@ Internal Core Api ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġcommit Observer ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠExec utes Ġ[ block ], Ġob serving Ġmodel Ġreads Ġduring Ġits Ġexecution . ĊĠĠĠĠ Ġ* ĠThe Ġ[ target ] Ġis Ġstored Ġas Ġa Ġweak Ġreference Ġto Ġbe Ġpassed Ġto Ġ[ on Commit ] Ġwhen Ġa Ġchange Ġto Ġthe ĊĠĠĠĠ Ġ* Ġmodel Ġhas Ġbeen Ġdetected . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠOb servation Ġfor Ġ[ target ] Ġwill Ġbe Ġpaused Ġwhen Ġa Ġnew Ġ[ observe Reads ] Ġcall Ġis Ġmade Ġor Ġwhen ĊĠĠĠĠ Ġ* Ġ[ pause Ob serving Reads ] Ġis Ġcalled . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠAny Ġprevious Ġobservation Ġwith Ġthe Ġgiven Ġ[ target ] Ġand Ġ[ on Commit ] Ġwill Ġbe ĊĠĠĠĠ Ġ* Ġcleared Ġand Ġonly Ġthe Ġnew Ġobservation Ġon Ġ[ block ] Ġwill Ġbe Ġstored . ĠIt Ġis Ġimportant Ġthat ĊĠĠĠĠ Ġ* Ġthe Ġsame Ġinstance Ġof Ġ[ on Commit ] Ġis Ġused Ġbetween Ġcalls Ġor Ġprevious Ġreferences Ġwill ĊĠĠĠĠ Ġ* Ġnot Ġbe Ġcleared . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThe Ġ[ on Commit ] Ġwill Ġbe Ġcalled Ġwhen Ġa Ġmodel Ġthat Ġwas Ġaccessed Ġduring Ġ[ block ] Ġhas Ġbeen ĊĠĠĠĠ Ġ* Ġcommitted , Ġand Ġit Ġwill Ġbe Ġcalled Ġwith Ġ[ commit Executor ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġ< T Ġ: ĠAny > Ġobserve Reads ( target : ĠT , Ġon Commit : Ġ( T ) Ġ-> ĠUnit , Ġblock : Ġ() Ġ-> ĠUnit ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġold Map Ġ= Ġcurrent Map ĊĠĠĠĠĠĠĠ Ġval Ġold Target Ġ= Ġcurrent Target ĊĠĠĠĠĠĠĠ Ġval Ġold Paused Ġ= Ġis Paused ĊĊĠĠĠĠĠĠĠ Ġcurrent Map Ġ= Ġ@ Suppress (" DE PREC ATION _ ERROR ") Ġsynchronized ( commit Maps ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġensure Map ( on Commit ). apply Ġ{ Ġremove Value ( target ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcurrent Target Ġ= Ġtarget ĊĠĠĠĠĠĠĠ Ġis Paused Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġif Ġ(! is Ob serving ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Ob serving Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġobserve All Reads ( read Observer , Ġblock ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Ob serving Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġblock () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcurrent Map Ġ= Ġold Map ĊĠĠĠĠĠĠĠ Ġcurrent Target Ġ= Ġold Target ĊĠĠĠĠĠĠĠ Ġis Paused Ġ= Ġold Paused ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSto ps Ġob serving Ġmodel Ġreads Ġwhile Ġexecuting Ġ[ block ]. ĠModel Ġreads Ġmay Ġbe Ġrestarted ĊĠĠĠĠ Ġ* Ġby Ġcalling Ġ[ observe Reads ] Ġinside Ġ[ block ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġpause Ob serving Reads ( block : Ġ() Ġ-> ĠUnit ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġold Paused Ġ= Ġis Paused ĊĠĠĠĠĠĠĠ Ġis Paused Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġblock () ĊĠĠĠĠĠĠĠ Ġis Paused Ġ= Ġold Paused ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠClear s Ġall Ġmodel Ġread Ġobservations Ġfor Ġa Ġgiven Ġ[ target ]. ĠThis Ġclears Ġvalues Ġfor Ġall ĊĠĠĠĠ Ġ* Ġ` on Commit ` Ġmethods Ġpassed Ġin Ġ[ observe Reads ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġclear ( target : ĠAny ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ@ Suppress (" DE PREC ATION _ ERROR ") ĊĠĠĠĠĠĠĠ Ġsynchronized ( commit Maps ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcommit Maps . fast ForEach Ġ{ Ġcommit Map Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcommit Map . map . remove Value ( target ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠStarts Ġor Ġstops Ġwatching Ġfor Ġmodel Ġcommits Ġbased Ġon Ġ[ enabled ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġenable Model Updates Ob serving ( enabled : ĠBoolean ): ĠUnit Ġ= Ġerror (" deprecated ") ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCalls Ġthe Ġ` on Commit ` Ġcallback Ġfor Ġthe Ġgiven Ġtargets . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġcall On Commit ( targets Array : ĠArray < List < Any >>) Ġ{ ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 .. targets Array . last Index ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtargets Ġ= Ġtargets Array [ i ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( targets . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Suppress (" DE PREC ATION _ ERROR ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcommit Caller Ġ= Ġsynchronized ( commit Maps ) Ġ{ Ġcommit Maps [ i ] Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcommit Caller . call On Commit ( targets ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġthe Ġ[ Observer Map ] Ġwithin Ġ[ commit Maps ] Ġassociated Ġwith Ġ[ on Commit ] Ġor Ġa Ġnewly - ĊĠĠĠĠ Ġ* Ġinserted Ġone Ġif Ġit Ġdoesn 't Ġexist . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġ< T Ġ: ĠAny > Ġensure Map ( on Commit : Ġ( T ) Ġ-> ĠUnit ): ĠObserver Map < Any , ĠAny > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġindex Ġ= Ġcommit Maps . indexOf First Ġ{ Ġit . on Commit Ġ=== Ġon Commit Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( index Ġ== Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcommit Map Ġ= ĠCommit Map ( on Commit ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcommit Maps . add ( commit Map ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcommit Map . map ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġcommit Maps [ index ]. map ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠUsed Ġto Ġtie Ġan Ġ` on Commit ` Ġto Ġits Ġtarget Ġby Ġtype . ĠThis Ġworks Ġaround Ġsome Ġdifficult ies Ġin ĊĠĠĠĠ Ġ* Ġunchecked Ġcast s Ġwith Ġkotlin . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Suppress (" UN CHECK ED _ CAST ") ĊĠĠĠ Ġprivate Ġclass ĠCommit Map < T Ġ: ĠAny >( val Ġon Commit : Ġ( T ) Ġ-> ĠUnit ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠObserver Map Ġ( key Ġ= Ġmodel , Ġvalue Ġ= Ġtarget ). ĠThese Ġare Ġthe Ġmodels Ġthat Ġhave Ġbeen ĊĠĠĠĠĠĠĠĠ Ġ* Ġread Ġduring Ġthe Ġtarget 's Ġ[ Model Observer . observe Reads ]. ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġval Ġmap Ġ= ĠObserver Map < Any , ĠAny >() ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠCalls Ġthe Ġ` on Commit ` Ġcallback Ġfor Ġtargets Ġaffected Ġby Ġthe Ġgiven Ġcommitted Ġvalues . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġcall On Commit ( targets : ĠList < Any >) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtargets . forEach Ġ{ Ġtarget Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Commit ( target Ġas ĠT ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ