// ============================================================
// Application scenario harness
//
// A Scenario gives a project an explicit, repeatable way to exercise a tree
// with a named blackboard fixture. This is intentionally backend-neutral and
// is useful for acceptance demos, performance regressions, and examples.
// ============================================================
///|
/// A named tree workload with a fixed frame budget.
pub struct Scenario {
name : String
root : Node
bb : Blackboard
frames : Int
}
///|
/// Construct a scenario.
pub fn Scenario::new(
name : String,
root : Node,
bb : Blackboard,
frames : Int,
) -> Scenario {
{ name, root, bb, frames: if frames > 0 { frames } else { 0 } }
}
///|
/// Execute a scenario and return its deterministic outcome report.
pub fn Scenario::run(self : Scenario) -> BenchmarkResult {
benchmark_node(self.name, self.root, self.bb, self.frames)
}
///|
/// Execute several scenarios in declaration order.
pub fn run_scenarios(scenarios : Array[Scenario]) -> Array[BenchmarkResult] {
let results : Array[BenchmarkResult] = []
for scenario in scenarios {
results.push(scenario.run())
}
results
}
///|
/// Format results as a CSV document with a stable header.
pub fn benchmark_csv(results : Array[BenchmarkResult]) -> String {
let output = StringBuilder::new()
output.write_string("scenario,frames,successes,failures,running\n")
for result in results {
output.write_string(result.to_csv())
output.write_string("\n")
}
output.to_string()
}
///|
/// Build a small but representative workload matrix for local regression.
pub fn standard_scenarios() -> Array[Scenario] {
let patrol_bb = Blackboard::new()
patrol_bb.set_bool("enabled", true)
patrol_bb.set_int("work", 0)
let combat_bb = Blackboard::new()
combat_bb.set_bool("enabled", false)
combat_bb.set_int("work", 0)
[
Scenario::new("enabled-workload", benchmark_workload(), patrol_bb, 12),
Scenario::new("disabled-workload", benchmark_workload(), combat_bb, 12),
Scenario::new(
"budgeted-running",
execution_budget_node(create_always_running(), 4),
Blackboard::new(),
8,
),
]
}
///|
/// Return a one-line health summary for a benchmark result.
pub fn benchmark_health(result : BenchmarkResult) -> String {
if result.frames() == 0 {
"empty"
} else if result.running > 0 {
"running"
} else if result.failures > 0 {
"failure-observed"
} else {
"complete"
}
}
///|
/// Run the standard matrix and return portable CSV output.
pub fn standard_benchmark_csv() -> String {
benchmark_csv(run_scenarios(standard_scenarios()))
}