/* Ċ Ġ* ĠCopyright Ġ 2 0 2 0 Ġ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 Ġkotlin . random . Random Ċ import Ġkotlinx . atomic fu . atomic Ċ import Ġkotlinx . coroutines . sync . Mutex Ċ import Ġkotlinx . coroutines . sync . with Lock Ċ Ċ /** Ċ Ġ* ĠThread - safe Ġbase Ġmanager Ġfor Ġ[ Proxy Callback ] s . Ċ Ġ* Ċ Ġ* ĠImplement ations Ġcan Ġdefine Ġhow Ġthey Ġwish Ġtheir Ġcallback Ġtokens Ġto Ġbe Ġgenerated . Ċ Ġ*/ Ċ class ĠProxy Callback Manager < Data Ġ: ĠCr dt Data , ĠOp Ġ: ĠCr dt Operation , ĠConsumer Data >( ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGenerates Ġa Ġtoken Ġ[ Int ] Ġto Ġbe Ġassigned Ġto Ġan Ġincoming Ġ[ Proxy Callback ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/* Ġinternal Ġ*/ ĊĠĠĠ Ġval Ġtoken Generator : Ġ( currently Used Tokens : ĠSet < Int >) Ġ-> ĠInt Ċ ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġmutex Ġ= ĠMutex () ĊĠĠĠ Ġ/* Ġinternal Ġ*/ Ġval Ġcallbacks Ġ= Ġmutable Map Of < Int , ĠProxy Callback < Data , ĠOp , ĠConsumer Data >>() ĊĊĠĠĠ Ġprivate Ġvar Ġhas E ver Set Callback Ġ= Ġfalse ĊĊĠĠĠ Ġ/** Ġ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 Ġ= Ġtoken Generator ( callbacks . keys ) ĊĠĠĠĠĠĠĠ Ġcallbacks [ token ] Ġ= Ġproxy Callback ĊĠĠĠĠĠĠĠ Ġhas E ver Set Callback Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġ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 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠTrue Ġif Ġno Ġcallbacks Ġare Ġregistered . Ġ*/ ĊĠĠĠ Ġfun ĠisEmpty (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ(! mutex . try Lock ()) Ġ{ Ġ/* ĠWait . Ġ*/ Ġ} ĊĠĠĠĠĠĠĠ Ġval ĠisEmpty Ġ= Ġcallbacks . isEmpty () ĊĠĠĠĠĠĠĠ Ġmutex . unlock () ĊĠĠĠĠĠĠĠ Ġreturn ĠisEmpty ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠTrue Ġif Ġno Ġcallbacks Ġare Ġregistered , Ġand Ġat Ġleast Ġone Ġhas Ġbeen Ġregistered Ġbefore . Ġ*/ ĊĠĠĠ Ġfun Ġhas Be come Empty (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ(! mutex . try Lock ()) Ġ{ Ġ/* ĠWait . Ġ*/ Ġ} ĊĠĠĠĠĠĠĠ Ġval ĠisEmpty Ġ= Ġhas E ver Set Callback Ġ&& Ġcallbacks . isEmpty () ĊĠĠĠĠĠĠĠ Ġmutex . unlock () ĊĠĠĠĠĠĠĠ Ġreturn ĠisEmpty ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ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 ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ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 . ĊĠĠĠĠĠĠĠ Ġtargets . forEach Ġ{ Ġit ( message ) Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠCreates Ġa Ġ[ Proxy Callback Manager ] Ġwhere Ġeach Ġcallback Ġis Ġgiven Ġa Ġtoken Ġfrom Ġan Ġincreasing Ġsource . Ċ Ġ*/ Ċ /* Ġk tl int - disable Ġmax - line - length Ġ*/ Ċ fun Ġ< Data Ġ: ĠCr dt Data , ĠOp Ġ: ĠCr dt Operation , ĠConsumer Data > ĠProxy Callback Manager (): ĠProxy Callback Manager < Data , ĠOp , ĠConsumer Data > Ġ{ ĊĠĠĠ Ġval Ġnext Callback Token Ġ= Ġatomic ( 0 ) ĊĠĠĠ Ġreturn ĠProxy Callback Manager Ġ{ Ġnext Callback Token . increment AndGet () Ġ} Ċ } Ċ /* Ġk tl int - enable Ġmax - line - length Ġ*/ Ċ Ċ /** Ċ Ġ* ĠCreates Ġa Ġ[ Proxy Callback Manager ] Ġwhich Ġis Ġprefer able Ġto Ġthe Ġregular Ġ[ Proxy Callback Manager ] Ċ Ġ* Ġin Ġsituations Ġwhere Ġmore Ġthan Ġone Ġhost Ġis Ġconnecting Ġto Ġthe Ġstore Ġat Ġa Ġtime . Ċ Ġ* Ċ Ġ* Ġ@ param Ġbase Data Ġa Ġsalt Ġof Ġsorts , Ġused Ġto Ġhelp Ġin Ġmaking Ġcallback ĠIDs Ġmore Ġunique Ġacross Ġhosts . Ċ Ġ* Ġ@ param Ġrandom Ġsource Ġof Ġrandom ness Ġto Ġuse Ġwhen Ġgenerating Ġcallback ĠIDs . Ċ Ġ*/ Ċ fun Ġ< Data Ġ: ĠCr dt Data , ĠOp Ġ: ĠCr dt Operation , ĠConsumer Data > ĠRandom Proxy Callback Manager ( ĊĠĠĠ Ġbase Data : ĠString , ĊĠĠĠ Ġrandom : ĠRandom Ċ ): ĠProxy Callback Manager < Data , ĠOp , ĠConsumer Data > Ġ= ĠProxy Callback Manager Ġ{ Ġcurrently Used Tokens Ġ-> ĊĠĠĠ Ġvar Ġunique Ġ= Ġrandom . nextInt () ĊĠĠĠ Ġvar Ġtoken String Ġ= Ġ"$ unique ::$ base Data " ĊĊĠĠĠ Ġwhile Ġ( token String . hashCode () Ġin Ġcurrently Used Tokens ) Ġ{ ĊĠĠĠĠĠĠĠ Ġunique Ġ= Ġrandom . nextInt () ĊĠĠĠĠĠĠĠ Ġtoken String Ġ= Ġ"$ unique ::$ base Data " ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġtoken String . hashCode () Ċ } Ċ