/* Ċ Ġ* ĠCopyright Ġ 2 0 1 9 ĠT enk iv , ĠInc . Ċ Ġ* Ċ Ġ* ĠPermission Ġis Ġhereby Ġgranted , Ġfree Ġof Ġcharge , Ġto Ġany Ġperson Ġobtaining Ġa Ġcopy Ġof Ġthis Ġsoftware Ġand Ġassociated Ċ Ġ* Ġdocumentation Ġfiles Ġ( the Ġ" Software "), Ġto Ġdeal Ġin Ġthe ĠSoftware Ġwithout Ġrestriction , Ġincluding Ġwithout Ġlimitation Ġthe Ċ Ġ* Ġrights Ġto Ġuse , Ġcopy , Ġmodify , Ġmerge , Ġpublish , Ġdistribute , Ġsublicense , Ġand / or Ġsell Ġcopies Ġof Ġthe ĠSoftware , Ġand Ġto Ċ Ġ* Ġpermit Ġpersons Ġto Ġwhom Ġthe ĠSoftware Ġis Ġfurnished Ġto Ġdo Ġso , Ġsubject Ġto Ġthe Ġfollowing Ġconditions : Ċ Ġ* Ċ Ġ* ĠThe Ġabove Ġcopyright Ġnotice Ġand Ġthis Ġpermission Ġnotice Ġshall Ġbe Ġincluded Ġin Ġall Ġcopies Ġor Ġsubstantial Ġportions Ġof Ġthe Ċ Ġ* ĠSoftware . Ċ Ġ* Ċ Ġ* ĠTHE ĠSOFTWARE ĠIS ĠPROVIDED Ġ" AS ĠIS ", ĠWITHOUT ĠWARRANTY ĠOF ĠANY ĠKIND , ĠEXPRESS ĠOR ĠIMPLIED , ĠINCLUDING ĠBUT ĠNOT ĠLIMITED ĠTO ĠTHE Ċ Ġ* ĠWARRANTIES ĠOF ĠMERCHANTABILITY , ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE ĠAND ĠNONINFRINGEMENT . ĠIN ĠNO ĠEVENT ĠSHALL ĠTHE ĠAUTHORS ĠOR Ċ Ġ* ĠCOPYRIGHT ĠHOLDERS ĠBE ĠLIABLE ĠFOR ĠANY ĠCLAIM , ĠDAMAGES ĠOR ĠOTHER ĠLIABILITY , ĠWHETHER ĠIN ĠAN ĠACTION ĠOF ĠCONTRACT , ĠTORT ĠOR Ċ Ġ* ĠOTHERWISE , ĠARISING ĠFROM , ĠOUT ĠOF ĠOR ĠIN ĠCONNECTION ĠWITH ĠTHE ĠSOFTWARE ĠOR ĠTHE ĠUSE ĠOR ĠOTHER ĠDEALINGS ĠIN ĠTHE ĠSOFTWARE . Ċ Ġ*/ Ċ Ċ package Ġorg . ten k iv . ku ant ify . networking . communication Ċ Ċ import Ġkotlinx . coroutines .* Ċ import Ġkotlinx . coroutines . channels .* Ċ import Ġmu .* Ċ import Ġorg . ten k iv . ku ant ify . hardware . device .* Ċ import Ġjava . util . concurrent . atomic .* Ċ import Ġkotlin . coroutines .* Ċ Ċ public Ġtype alias ĠUpdate Receiver < ST > Ġ= Ġsuspend Ġ( update : ĠST ) Ġ-> ĠUnit Ċ public Ġtype alias ĠMessage Serializer < MT , ĠST > Ġ= Ġ( update : ĠMT ) Ġ-> ĠST Ċ Ċ private Ġval Ġlogger Ġ= ĠKotlin Logging . logger Ġ{} Ċ Ċ public Ġabstract Ġclass ĠNetwork Route Binding < MT , ĠST >( ĊĠĠĠ Ġprotected Ġval Ġnetwork Com municator : ĠNetwork Com municator < ST >, ĊĠĠĠ Ġinternal Ġval Ġnetwork Update Channel : ĠChannel < ST >? Ċ ) Ġ: ĠCor outine Scope Ġ{ ĊĊĠĠĠ Ġpublic Ġfinal Ġoverride Ġval Ġcoroutine Context : ĠCor outine Context ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġnetwork Com municator . coroutine Context ĊĊĠĠĠ Ġpublic Ġabstract Ġfun Ġstart () ĊĊĠĠĠ Ġpublic Ġcompanion Ġobject Ġ{ ĊĊĠĠĠĠĠĠĠ Ġinternal Ġfun Ġthrow Illegal State Send ( route : ĠString , Ġdevice : ĠDevice ): ĠNothing Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Network Ġbinding Ġfor Ġroute : Ġ$ route Ġon Ġdevice ${ device . uid }" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Ġis Ġconfigured Ġto Ġsend Ġbut Ġhas Ġno Ġlocal Ġupdate Ġchannel ." ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġinternal Ġfun Ġthrow Illegal State Receive ( route : ĠString , Ġdevice : ĠDevice ): ĠNothing Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Network Ġbinding Ġfor Ġroute : Ġ$ route Ġon Ġdevice ${ device . uid }" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Ġis Ġconfigured Ġto Ġreceive Ġbut Ġhas Ġno Ġnetwork Ġupdate Ġchannel ." ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} Ċ Ċ } Ċ Ċ public Ġclass ĠRe cur sion Prevent ing Route Binding < MT , ĠST >( ĊĠĠĠ Ġnetwork Com municator : ĠNetwork Com municator < ST >, ĊĠĠĠ Ġprivate Ġval Ġroute : ĠString , ĊĠĠĠ Ġprivate Ġval Ġlocal Update Channel : ĠReceive Channel < MT > ?, ĊĠĠĠ Ġnetwork Update Channel : ĠChannel < ST > ?, ĊĠĠĠ Ġprivate Ġval Ġserialize Message : ĠMessage Serializer < MT , ĠST > ?, ĊĠĠĠ Ġprivate Ġval Ġsend Updates : ĠBoolean , ĊĠĠĠ Ġprivate Ġval Ġreceive Update : ĠUpdate Receiver < ST > ?, ĊĠĠĠ Ġprivate Ġval Ġserialized Ping : ĠST Ċ ) Ġ: ĠNetwork Route Binding < MT , ĠST >( network Com municator , Ġnetwork Update Channel ) Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġignore Next Update Ġ= ĠAtomic Boolean ( false ) ĊĊĠĠĠ Ġpublic Ġoverride Ġfun Ġstart () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠSend ĊĠĠĠĠĠĠĠ Ġif Ġ( send Updates ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlaunch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlocal Update Channel ?. consume Each Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! ignore Next Update . get ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= Ġserialize Message ?. invoke ( it ) Ġ?: Ġserialized Ping ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnetwork Com municator ._ sendMessage ( route , Ġmessage ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġignore Next Update . set ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ?: Ġthrow Illegal State Send ( route , Ġnetwork Com municator . device ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠReceive ĊĠĠĠĠĠĠĠ Ġif Ġ( receive Update Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlaunch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnetwork Update Channel ?. consume Each Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġignore Next Update . set ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreceive Update . invoke ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ?: Ġthrow Illegal State Receive ( route , Ġnetwork Com municator . device ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġpublic Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġ""" ĊĠĠĠĠĠĠĠ ĠRe cur sion Prevent ing Network Com municator ( route =$ route , Ġserialized Ping =$ serialized Ping ) ĊĠĠĠ Ġ""" . trim Indent () Ċ } Ċ Ċ public Ġclass ĠStandard Route Binding < MT , ĠST >( ĊĠĠĠ Ġnetwork Com municator : ĠNetwork Com municator < ST >, ĊĠĠĠ Ġprivate Ġval Ġroute : ĠString , ĊĠĠĠ Ġprivate Ġval Ġlocal Update Channel : ĠReceive Channel < MT > ?, ĊĠĠĠ Ġnetwork Update Channel : ĠChannel < ST > ?, ĊĠĠĠ Ġprivate Ġval Ġserialize Message : ĠMessage Serializer < MT , ĠST > ?, ĊĠĠĠ Ġprivate Ġval Ġsend Updates : ĠBoolean , ĊĠĠĠ Ġprivate Ġval Ġreceive Update : ĠUpdate Receiver < ST > ?, ĊĠĠĠ Ġprivate Ġval Ġserialized Ping : ĠST Ċ ) Ġ: ĠNetwork Route Binding < MT , ĠST >( network Com municator , Ġnetwork Update Channel ) Ġ{ ĊĊĠĠĠ Ġpublic Ġoverride Ġfun Ġstart () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠSend ĊĠĠĠĠĠĠĠ Ġif Ġ( send Updates ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlaunch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlocal Update Channel ?. consume Each Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= Ġserialize Message ?. invoke ( it ) Ġ?: Ġserialized Ping ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnetwork Com municator ._ sendMessage ( route , Ġmessage ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ?: Ġthrow Illegal State Send ( route , Ġnetwork Com municator . device ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠReceive ĊĠĠĠĠĠĠĠ Ġif Ġ( receive Update Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlaunch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnetwork Update Channel ?. consume Each Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreceive Update . invoke ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ?: Ġthrow Illegal State Receive ( route , Ġnetwork Com municator . device ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġpublic Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġ""" ĊĠĠĠĠĠĠĠ ĠStandard Route Binding ( route =$ route , Ġserialized Ping =$ serialized Ping ) ĊĠĠĠ Ġ""" . trim Indent () Ċ Ċ }