12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667openEio.Stdtypet=<Eio.Time.clock;advance:unit;set_time:float->unit;>moduleKey=structtypet=<>letcompare=compareendmoduleJob=structtypet={time:float;resolver:unitPromise.u;}letcompareab=Float.comparea.timeb.timeendmoduleQ=Psq.Make(Key)(Job)letmake()=object(self)inheritEio.Time.clockvalmutablenow=0.0valmutableq=Q.emptymethodnow=nowmethodsleep_untiltime=iftime<=nowthenFiber.yield()else(letp,r=Promise.create()inletk=objectendinq<-Q.addk{time;resolver=r}q;tryPromise.awaitpwithEio.Cancel.Cancelled_asex->q<-Q.removekq;raiseex)methodset_timetime=letrecdrain()=matchQ.minqwith|Some(_,v)whenv.time<=time->Promise.resolvev.resolver();q<-Option.get(Q.restq);drain()|_->()indrain();now<-time;traceln"mock time is now %g"nowmethodadvance=matchQ.minqwith|None->invalid_arg"No further events scheduled on mock clock"|Some(_,v)->self#set_timev.timeendletset_time(t:t)time=t#set_timetimeletadvance(t:t)=t#advance