/** Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 1 8 - 2 0 1 9 ĠDr . ĠFl orian ĠSch mid t Ċ Ġ* Ċ Ġ* Ġ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 Ġorg . dr x . e vo leq . dsl Ċ Ċ import Ġjavafx . beans . property . Property Ċ import Ġjavafx . beans . property . Simple Boolean Property Ċ import Ġjavafx . beans . property . Simple ObjectProperty Ċ import Ġjavafx . beans . value . ChangeListener Ċ import Ġkotlinx . coroutines . Coroutine Scope Ċ import Ġkotlinx . coroutines . launch Ċ import Ġorg . dr x . e vo leq . conditions . once Ċ import Ġorg . dr x . e vo leq . coroutines . sus pended Ċ import Ġorg . dr x . e vo leq . e vol ving . E vol ving Ċ import Ġorg . dr x . e vo leq . e vol ving . Parallel Ċ import Ġorg . dr x . e vo leq . flow . enter Ċ import Ġorg . dr x . e vo leq . gap . Gap Ċ import Ġorg . dr x . e vo leq . gap . fill Ċ import Ġorg . dr x . e vo leq . message . Message Ċ import Ġorg . dr x . e vo leq . stub . Stub Ċ import Ġorg . dr x . e vo leq . time . WaitFor Property Ċ Ċ class ĠOb serve Property Stub Ċ sealed Ġclass ĠOb serve Property Message Ġ: ĠMessage Ġ{ ĊĠĠĠ Ġobject ĠOb serve Ġ: ĠOb serve Property Message () ĊĠĠĠ Ġobject ĠPause Ġ: ĠOb serve Property Message () Ċ } Ċ open Ġclass ĠOb serving Stub Configuration < D , P >() Ġ: ĠStub Configuration < D >() Ġ{ ĊĊĊĠĠĠ Ġconstructor ( scope : ĠCor outine Scope ) Ġ: Ġthis (){ ĊĠĠĠĠĠĠĠ Ġthis . scope Ġ= Ġscope ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// var Ġscope : ĠCor outine Scope Ġ= ĠGlobal Scope ĊĊĠĠĠ Ġprivate Ġvar Ġpre Ev olve : Ġsuspend Ġ( D )-> ĠE vol ving < D > Ġ= Ġsus pended { Ġd : ĠD Ġ-> ĠParallel { d } Ġ} ĊĠĠĠ Ġprivate Ġval Ġstack : ĠArrayList < P > Ġby Ġlazy { Ġarray ListOf < P >() Ġ} ĊĠĠĠ Ġprivate Ġval Ġstack Empty : ĠSimple ObjectProperty < Boolean > Ġby Ġlazy Ġ{ ĠSimple ObjectProperty < Boolean >( true ) Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġgap : ĠG ap < D , ĠP >? Ġ= Ġnull ĊĊĊĠĠĠ Ġprivate Ġvar Ġobserved Property : ĠProperty < P >? Ġ= Ġnull ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠOb serve Ġa Ġproperty ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġobserve ( property : ĠProperty < P >) Ġ{ ĊĠĠĠĠĠĠĠ Ġobserved Property Ġ= Ġproperty ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġgap Ġto Ġclose ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġgap ( configuration : ĠG ap Configuration < D , ĠP >. ()-> Unit ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . gap Ġ= Ġconfigure ( configuration ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠDefine Ġthe Ġpre - ev olve Ġfunction Ġof Ġthe Ġstub . ĊĠĠĠĠ Ġ* ĠIn Ġprinciple Ġit Ġis Ġnot Ġnecessary Ġto Ġuse Ġthis Ġfunction Ġduring Ġusage ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġev olve ( Ġflow : suspend Ġ( D )-> ĠE vol ving < D >) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . pre Ev olve Ġ= Ġflow ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġconfigure (): ĠStub < D > Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġadd Ġnew Ġvalues Ġto Ġstack ĊĠĠĠĠĠĠĠ Ġval Ġob serving Ġ= ĠSimple Boolean Property ( true ) ĊĠĠĠĠĠĠĠ Ġval Ġlistener Ġ= ĠChange Listener < P >{ Ġ_, Ġ_, ĠnewValue Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( ob serving . value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// println (" adding Ġ$ newValue Ġto Ġstack ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstack . add ( newValue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstack Empty . value Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse { ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// println (" ob serving Ġ= Ġfalse ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġobserved Property !!. addListener ( listener ) ĊĊĠĠĠĠĠĠĠ Ġsuper . stubs [ Ob serve Property Stub :: class ] Ġ= Ġstub < Ob serve Property Message >{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġev olve Ġ{ Ġmessage Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( message ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠOb serve Property Message . Ob serve Ġ-> Ġscope . parallel Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġob serving . value Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠOb serve Property Message . Pause Ġ-> Ġscope . parallel Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġob serving . value Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĊĠĠĠĠĠĠĠ Ġ// Ġconfigure Ġevolution Ġfunction ĊĠĠĠĠĠĠĠ Ġvar Ġsetup Done : ĠBoolean Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġscope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġview Ġevolution Ġfunction Ġas ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġflow Ġand Ġmake Ġit Ġenter Ġthe Ġgap ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġflow Gap Ġ= Ġsus pended Flow < D , Boolean > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconditions ( once ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflow Ġ{ Ġd : D Ġ-> pre Ev olve ( d ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. enter ( gap !! ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġdefine Ġthe Ġside - effect . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠHave Ġto Ġdistinguish Ġthe Ġcases Ġof Ġempty Ġand Ġnon - empty Ġstack ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġside Effect Ġ= Ġsus pended Ġ{ Ġp : P Ġ-> ĠParallel < P > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// println ( stack . size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( stack . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġx Ġ= ĠWaitFor Property ( stack Empty ). to Change (). get () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfirst Ġ= Ġstack . first () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstack . remove At ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( stack . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstack Empty . value Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfirst ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfirst Ġ= Ġstack . first () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstack . remove At ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( stack . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstack Empty . value Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfirst ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . ev olve Ġ= Ġsus pended ( Ġflow Gap . fill ( Ġside Effect Ġ)) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsetup Done Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// Ġawait Ġconfiguration Ġto Ġbe Ġdone ĊĠĠĠĠĠĠĠ Ġwhile (! setup Done ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠThread . sleep ( 0 , 1 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġ Ġsuper . configure () ĊĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠConfigure Ġan Ġob serving Ġstub Ċ Ġ* ĠImport ant : ĠThe Ġstub Ġwill Ġnot Ġwork Ġunless Ġa Ġgap Ġis Ġdefined Ċ Ġ*/ Ċ fun Ġ< D , P > Ġob serving Stub ( configuration : ĠOb serving Stub Configuration < D , P >. ()-> Unit ) Ġ: ĠStub < D > Ġ= Ġconfigure ( configuration ) Ċ fun Ġ< D , P > ĠCor outine Scope . ob serving Stub ( configuration : ĠOb serving Stub Configuration < D , P >. ()-> Unit ) Ġ: ĠStub < D > Ġ= Ġconfigure ( this , configuration ) Ċ