// ============================================================
// Blackboard inspection and composition APIs
//
// These helpers keep integration code from reaching into the map directly.
// They are useful for save games, debugging panels, simulation isolation, and
// deterministic test fixtures.
// ============================================================
///|
/// Read a value without committing to a concrete value type.
pub fn Blackboard::get_value(self : Blackboard, key : String) -> Value? {
self.data.get(key)
}
///|
/// Store a previously captured value.
pub fn Blackboard::set_value(
self : Blackboard,
key : String,
value : Value,
) -> Unit {
self.data.set(key, value)
}
///|
/// Insert a value only when the key does not already exist.
pub fn Blackboard::set_if_absent(
self : Blackboard,
key : String,
value : Value,
) -> Bool {
if self.data.contains(key) {
false
} else {
self.data.set(key, value)
true
}
}
///|
/// Return keys in the map's stable insertion order.
pub fn Blackboard::keys(self : Blackboard) -> Array[String] {
let result : Array[String] = []
self.data.each(fn(key, _) { result.push(key) })
result
}
///|
/// Return the number of active nested snapshots.
pub fn Blackboard::snapshot_depth(self : Blackboard) -> Int {
self.snapshots.length()
}
///|
/// Copy all values from another blackboard into this one.
pub fn Blackboard::merge(self : Blackboard, other : Blackboard) -> Unit {
other.data.each(fn(key, value) { self.data.set(key, value) })
}
///|
/// Create an independent blackboard copy without copying snapshot history.
pub fn Blackboard::clone(self : Blackboard) -> Blackboard {
let copy = Blackboard::new()
copy.merge(self)
copy
}
///|
/// Convert a Value into a stable type label for diagnostics.
pub fn Value::type_name(self : Value) -> String {
match self {
Value::Bool(_) => "bool"
Value::Int(_) => "int"
Value::Double(_) => "double"
Value::Str(_) => "string"
}
}