wowlab_engine_application/simulate_intent/
entry.rs1use wowlab_engine_ports::{
2 ChunkAssignment, ChunkReport, ContentCatalog, DataResolver, DynDataResolver, ProgressSink,
3};
4use wowlab_types::game::SpecId;
5
6use super::handler::{bootstrap, handler_factory};
7use crate::{
8 chunk_executor::{run_chunk, run_chunk_with_trace},
9 error::{ApplicationError, ApplicationStage, EngineResultExt as _},
10 intent_builder::{IntentOverrides, SimRequest},
11};
12
13#[must_use]
15pub fn assisted_rotation_id(spec: SpecId) -> String {
16 format!("{}_assisted", spec.slug())
17}
18
19pub async fn resolve_assisted_rotation_script(
21 spec: SpecId,
22 resolver: &DynDataResolver<'_>,
23) -> Result<String, ApplicationError> {
24 let id = assisted_rotation_id(spec);
25
26 resolver
27 .get_rotation_script(&id)
28 .await
29 .in_application_stage(ApplicationStage::AssistedRotationResolution)
30}
31
32async fn bootstrap_chunk(
33 catalog: &ContentCatalog,
34 sim_config: &str,
35 chunk: &ChunkAssignment,
36 seed_base: u64,
37 resolver: &DynDataResolver<'_>,
38 overrides: &IntentOverrides,
39) -> Result<(super::handler::BootstrapResult, u64), ApplicationError> {
40 let bootstrapped = bootstrap(catalog, sim_config, resolver, overrides).await?;
41 let effective_seed = seed_base.wrapping_add(chunk.seed_offset);
42
43 Ok((bootstrapped, effective_seed))
44}
45
46pub async fn simulate_intent_request(
48 catalog: &ContentCatalog,
49 request: SimRequest<'_>,
50 resolver: &DynDataResolver<'_>,
51 progress: &dyn ProgressSink,
52) -> Result<ChunkReport, ApplicationError> {
53 let (bootstrapped, effective_seed) = bootstrap_chunk(
54 catalog,
55 request.sim_config,
56 request.chunk,
57 request.seed_base,
58 resolver,
59 &request.overrides,
60 )
61 .await?;
62
63 run_chunk(
64 crate::ChunkRun {
65 assignment: request.chunk,
66 duration_s: bootstrapped.duration_s,
67 seed_base: effective_seed,
68 },
69 progress,
70 handler_factory(bootstrapped.handler),
71 )
72}
73
74pub async fn simulate_intent(
77 catalog: &ContentCatalog,
78 sim_config: &str,
79 chunk: &ChunkAssignment,
80 seed_base: u64,
81 resolver: &DynDataResolver<'_>,
82 progress: &dyn ProgressSink,
83) -> Result<ChunkReport, ApplicationError> {
84 let request = SimRequest {
86 sim_config,
87 chunk,
88 seed_base,
89 overrides: IntentOverrides::default(),
90 };
91
92 simulate_intent_request(catalog, request, resolver, progress).await
93}
94
95pub async fn simulate_intent_with_trace<T>(
97 catalog: &ContentCatalog,
98 request: SimRequest<'_>,
99 resolver: &DynDataResolver<'_>,
100 progress: &dyn ProgressSink,
101 trace_sink: T,
102) -> Result<ChunkReport, ApplicationError>
103where
104 T: wowlab_engine_ports::DecisionTraceSink + 'static,
105{
106 let (bootstrapped, effective_seed) = bootstrap_chunk(
107 catalog,
108 request.sim_config,
109 request.chunk,
110 request.seed_base,
111 resolver,
112 &request.overrides,
113 )
114 .await?;
115
116 run_chunk_with_trace(
117 crate::ChunkRun {
118 assignment: request.chunk,
119 duration_s: bootstrapped.duration_s,
120 seed_base: effective_seed,
121 },
122 progress,
123 trace_sink,
124 handler_factory(bootstrapped.handler),
125 )
126}