123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172open!Coreopen!Bonsaiopen!Bonsai_testmoduleDriver=Arrow.Drivertypet=Core_bench_js.Test.tletrecflatten_to_list=function|Interaction.Manynested->List.concat_mapnested~f:flatten_to_list|_ast->[t];;letdedupe_stabilizesinteractions=letboth_stabilizett'=matcht,t'with|Interaction.Stabilize,Interaction.Stabilize->true|_->falseinList.remove_consecutive_duplicatesinteractions~equal:both_stabilize;;(* [handle_interaction] needn't handle [Many]s, since we flatten the whole structure prior
to running the benchmark. *)lethandle_interaction~driver~clock~inject_actioninteraction=match(interaction:_Interaction.t)with|Stabilize->Driver.flushdriver|Reset_model->Driver.reset_model_to_defaultdriver|Change_input(var,value)->Var.setvarvalue|Injectaction->Driver.schedule_eventdriver(inject_actionaction)|Advance_clock_byspan->Incr.Clock.advance_clock_byclockspan|Many_->assertfalse;;letcreate?(clock=Incr.Clock.create~start:Time_ns.epoch())~name~component~get_injectinteraction=letrun_test`init=letcomponent(_:_Value.t)=componentinletdriver=Driver.create~clock~initial_input:()componentinCleanup.register_driverdriver;letinject_actionaction=(* Calling Driver.result every time that inject_action is called
is important because the value can change during stabilization *)letresult=Driver.resultdriverin(get_injectresult)actionin(* We perform two optimizations in this step: flattening the interactions and deduping
stabilizations. Flattening the structure ensures that there's no additional
overhead to nesting lots of [Many]s when creating benchmarks. Consecutive
[Stabilize]s don't add anything to benchmarks and would add a function call of
overhead. *)letinteractions=Interaction.many[Interaction.Stabilize;interaction;Interaction.Stabilize]|>flatten_to_list|>dedupe_stabilizes|>Array.of_listinfun()->Array.iterinteractions~f:(handle_interaction~driver~clock~inject_action)inCore_bench_js.Test.create_with_initialization~namerun_test;;letcreate_with_resetter?clock~name~component~get_injectinteraction=[interaction;Interaction.Reset_model;Interaction.Stabilize]|>Interaction.many|>create?clock~name~component~get_inject;;