1234567891011121314151617181920212223242526272829303132333435363738394041424344open!Core(** The type of [q] guarantees that all reads and writes happen in the order that they are
pushed to [q] *)letq:(unit->(unit->unit))Reversed_list.tref=refReversed_list.[]letread_then_write~read~write=letf()=letvalue=read()infun()->writevalueinq:=f::!q;;letread~f=read_then_write~read:f~write:Fn.idletwrite~f=read_then_write~read:Fn.id~write:fletrunf=f()moduleExpert=structletrun_reads()=letwrites=(* We aren't using [Reversed_list.rev_map] because that would execute the reads in
the reverse order in which they were pushed to the list. While this shouldn't
matter if the user didn't push a DOM mutation into a read, it is still
technically possible that they did. In that case, running the methods in the
reverse order may cause an unexpected interactions if the user was depending on
the order of writes
*)Reversed_list.rev!q|>List.map~f:runinlet((* Clear the queue *))=q:=Reversed_list.[]inletrun_writes()=List.iterwrites~f:runin`Run_writesrun_writes;;letrun_actions()=let(`Run_writesrun_writes)=run_reads()inrun_writes();;endmoduleFor_testing=structletnum_elements_in_queue()=Reversed_list.length!qend