/* Ċ Ġ* ĠCopyright Ġ 2 0 1 9 ĠGoogle ĠLLC . Ċ Ġ* Ċ Ġ* ĠThis Ġcode Ġmay Ġonly Ġbe Ġused Ġunder Ġthe ĠBSD Ġstyle Ġlicense Ġfound Ġat Ċ Ġ* Ġhttp :// polymer . github . io / LICENSE . txt Ċ Ġ* Ċ Ġ* ĠCode Ġdistributed Ġby ĠGoogle Ġas Ġpart Ġof Ġthis Ġproject Ġis Ġalso Ġsubject Ġto Ġan Ġadditional ĠIP Ġrights Ċ Ġ* Ġgrant Ġfound Ġat Ċ Ġ* Ġhttp :// polymer . github . io / PAT ENTS . txt Ċ Ġ*/ Ċ Ċ package Ġar cs . core . storage . util Ċ Ċ import Ġar cs . core . cr dt . Cr dt Data Ċ import Ġar cs . core . cr dt . Cr dt Operation Ċ import Ġar cs . core . storage . Proxy Callback Ċ import Ġar cs . core . storage . Proxy Message Ċ import Ġkotlinx . atomic fu . atomic Ċ import Ġkotlinx . coroutines . sync . Mutex Ċ import Ġkotlinx . coroutines . sync . with Lock Ċ Ċ /** ĠThread - safe Ġmanager Ġof Ġa Ġcollection Ġof Ġ[ Proxy Callback ] s . Ġ*/ Ċ class ĠProxy Callback Manager < Data Ġ: ĠCr dt Data , ĠOp Ġ: ĠCr dt Operation , ĠConsumer Data > Ġ{ ĊĠĠĠ Ġprivate Ġval Ġmutex Ġ= ĠMutex () ĊĠĠĠ Ġval Ġnext Callback Token Ġ= Ġatomic ( 1 ) ĊĠĠĠ Ġ/* Ġinternal Ġ*/ Ġval Ġcallbacks Ġ= Ġmutable Map Of < Int , ĠProxy Callback < Data , ĠOp , ĠConsumer Data >>() ĊĊĠĠĠ Ġ/** ĠAdds Ġa Ġ[ Proxy Callback ] Ġto Ġthe Ġcollection , Ġand Ġreturns Ġits Ġtoken . Ġ*/ ĊĠĠĠ Ġfun Ġregister ( proxy Callback : ĠProxy Callback < Data , ĠOp , ĠConsumer Data >): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ(! mutex . try Lock ()) Ġ{ Ġ/* ĠWait . Ġ*/ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġtoken Ġ= Ġnext Callback Token . get And Increment () ĊĠĠĠĠĠĠĠ Ġcallbacks [ token ] Ġ= Ġproxy Callback ĊĠĠĠĠĠĠĠ Ġmutex . unlock () ĊĠĠĠĠĠĠĠ Ġreturn Ġtoken ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠRemoves Ġthe Ġcallback Ġwith Ġthe Ġgiven Ġ[ callback Token ] Ġfrom Ġthe Ġcollection . Ġ*/ ĊĠĠĠ Ġfun Ġunregister ( callback Token : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ(! mutex . try Lock ()) Ġ{ Ġ/* ĠWait . Ġ*/ Ġ} ĊĠĠĠĠĠĠĠ Ġcallbacks . remove ( callback Token ) ĊĠĠĠĠĠĠĠ Ġmutex . unlock () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠGets Ġa Ġparticular Ġ[ Proxy Callback ] Ġby Ġits Ġ[ callback Token ]. Ġ*/ ĊĠĠĠ Ġfun Ġget Callback ( callback Token : ĠInt ?): ĠProxy Callback < Data , ĠOp , ĠConsumer Data >? Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ(! mutex . try Lock ()) Ġ{ Ġ/* ĠWait . Ġ*/ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġres Ġ= Ġcallbacks [ callback Token ] ĊĠĠĠĠĠĠĠ Ġmutex . unlock () ĊĠĠĠĠĠĠĠ Ġreturn Ġres ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠNot ifies Ġall Ġregistered Ġ[ Proxy Callback Manager ] Ġof Ġa Ġ[ message ]. ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠOptionally : Ġyou Ġmay Ġspecify Ġ[ except To ] Ġto Ġomit Ġsending Ġto Ġa Ġparticular Ġcallback . Ġ( with Ġtoken ĊĠĠĠĠ Ġ* Ġvalue Ġ== Ġ[ except To ]) ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġsend ( ĊĠĠĠĠĠĠĠ Ġmessage : ĠProxy Message < Data , ĠOp , ĠConsumer Data >, ĊĠĠĠĠĠĠĠ Ġexcept To : ĠInt ? Ġ= Ġnull ĊĠĠĠ Ġ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtargets Ġ= Ġmutex . with Lock Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( except To Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcallbacks . values . toList () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcallbacks . filter Ġ{ Ġit . key Ġ!= Ġexcept To Ġ}. values . toList () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠCall Ġour Ġtargets Ġoutside Ġof Ġthe Ġmutex Ġso Ġwe Ġdon 't Ġdead lock Ġif Ġa Ġcallback Ġleads Ġto Ġanother ĊĠĠĠĠĠĠĠ Ġ// Ġregistration . ĊĠĠĠĠĠĠĠ Ġreturn Ġtargets . fold ( true ) Ġ{ Ġsuccess , Ġcallback Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuccess Ġ&& Ġcallback ( message ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠNot ifies Ġall Ġmultip lex ed Ġ[ Proxy Callback ] s Ġregistered Ġof Ġa Ġ[ message ] Ġfor Ġa Ġparticular Ġ[ mux Id ]. ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠOptionally : Ġyou Ġmay Ġspecify Ġ[ except To ] Ġto Ġomit Ġsending Ġto Ġa Ġparticular Ġcallback . Ġ( with Ġtoken ĊĠĠĠĠ Ġ* Ġvalue Ġ== Ġ[ except To ]) ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġsend Multip lex ed ( ĊĠĠĠĠĠĠĠ Ġmessage : ĠProxy Message < Data , ĠOp , ĠConsumer Data >, ĊĠĠĠĠĠĠĠ Ġmux Id : ĠString , ĊĠĠĠĠĠĠĠ Ġexcept To : ĠInt ? Ġ= Ġnull ĊĠĠĠ Ġ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtargets Ġ= Ġmutex . with Lock Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( except To Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠArrayList ( callbacks . values ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠArrayList ( callbacks . filter Ġ{ Ġit . key Ġ!= Ġexcept To Ġ}. values ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠCall Ġour Ġtargets Ġoutside Ġof Ġthe Ġmutex Ġso Ġwe Ġdon 't Ġdead lock Ġif Ġa Ġcallback Ġleads Ġto Ġanother ĊĠĠĠĠĠĠĠ Ġ// Ġregistration . ĊĠĠĠĠĠĠĠ Ġreturn Ġtargets . fold ( true ) Ġ{ Ġsuccess , Ġcallback Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuccess Ġ&& Ġcallback ( message , Ġmux Id ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ