kv::Store von bladeink entkoppeln
Der Kern-KV war HashMap<String, bladeink::ValueType> — jedes Modul, das eine Spielvariable las, hing damit an der öffentlichen API der Story-Crate. "Konvertierung gratis" war der Grund, aber der Preis war eine Dependency-Kante quer durch engine/. Neuer eigener kv::Value (Bool/Int/Float/Str). Die Umrechnung auf Inks ValueType passiert jetzt allein in ink.rs (to_ink/from_ink) — die einzige Stelle im Kern, die bladeink überhaupt kennt. from_ink verwirft Ink-eigene Typen (Listen, Divert-Referenzen), die im KV nichts verloren haben. - format_value → Display für Value - coerce_to_int → Value::as_int (gleiche Semantik); coerce_to_bool hatte außer Tests keinen Aufrufer und entfällt, die Tests prüfen jetzt die gespeicherte Variante direkt - bladeink bleibt Dependency (ink.rs braucht es), nur nicht mehr im KV-Vertrag Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0196AM4UyAJEXVtPvp5DdKr8
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
247f7ef9fe
commit
236a643d04
+7
-6
@@ -4,7 +4,7 @@ use crate::engine::game::{Action, Game, ModeTarget};
|
||||
use crate::engine::ink::StoryState;
|
||||
use crate::engine::player::{self, Player};
|
||||
use crate::engine::trigger::Triggers;
|
||||
use crate::engine::{kv, model, signals, story_ctrl};
|
||||
use crate::engine::{model, signals, story_ctrl};
|
||||
|
||||
/// Maus-Empfindlichkeit der Sicht (Radiant/Pixel).
|
||||
const LOOK_SENS: f32 = 0.0025;
|
||||
@@ -393,7 +393,7 @@ impl Session {
|
||||
let mut keys: Vec<&String> = self.game.kv.keys().collect();
|
||||
keys.sort();
|
||||
keys.into_iter()
|
||||
.map(|k| format!(" {k} = {}", kv::format_value(&self.game.kv[k])))
|
||||
.map(|k| format!(" {k} = {}", self.game.kv[k]))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
@@ -416,6 +416,7 @@ fn help() -> Vec<String> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::engine::kv::Value;
|
||||
|
||||
// Fehlender Pfad → leere Signal-Table (load_signals schluckt den Fehler),
|
||||
// also keine Asset-Abhängigkeit für diese Tests. Der Konstruktor startet
|
||||
@@ -440,7 +441,7 @@ mod tests {
|
||||
// Unbekanntes Signal fällt auf den Builtin-Pfad durch → `set`.
|
||||
let r = s.exec("signal set has_key true");
|
||||
assert!(!r.quit);
|
||||
assert!(s.game.kv["has_key"].coerce_to_bool().unwrap());
|
||||
assert!(matches!(s.game.kv["has_key"], Value::Bool(true)));
|
||||
assert!(matches!(s.mode, Mode::Free));
|
||||
}
|
||||
|
||||
@@ -456,7 +457,7 @@ mod tests {
|
||||
assert!(matches!(s.mode, Mode::Menu));
|
||||
// Im Menü laufen Engine-Befehle weiter (gleiche Route wie Play/Free).
|
||||
s.exec("signal set in_menu true");
|
||||
assert!(s.game.kv["in_menu"].coerce_to_bool().unwrap());
|
||||
assert!(matches!(s.game.kv["in_menu"], Value::Bool(true)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -571,7 +572,7 @@ mod tests {
|
||||
// Vorwärts (−Z, yaw=0) in die Zone laufen; irgendwann feuert die
|
||||
// Flanke genau einmal (danach: drin = still).
|
||||
for _ in 0..120 { s.tick(&FrameInput { fwd: 1.0, ..Default::default() }, FIXED_DT); }
|
||||
assert!(s.game.kv["zone_hit"].coerce_to_bool().unwrap(), "Zone sollte gefeuert haben");
|
||||
assert!(matches!(s.game.kv["zone_hit"], Value::Bool(true)), "Zone sollte gefeuert haben");
|
||||
|
||||
// Weiterlaufen in der Zone darf nicht erneut feuern.
|
||||
s.game.kv.remove("zone_hit");
|
||||
@@ -586,7 +587,7 @@ mod tests {
|
||||
s.mode = Mode::FirstPerson;
|
||||
// Klick-Ziel: feuert den Property-Wert, nicht signal_key("Kiste").
|
||||
s.exec("use Kiste");
|
||||
assert!(s.game.kv["kiste_geklickt"].coerce_to_bool().unwrap());
|
||||
assert!(matches!(s.game.kv["kiste_geklickt"], Value::Bool(true)));
|
||||
// Ohne Property wie gehabt: Name (suffix-gestrippt) als Signal — hier
|
||||
// unbekannt und ohne Table ein stilles No-Op, aber kein Fehler.
|
||||
let r = s.exec("use Irgendwas.003");
|
||||
|
||||
Reference in New Issue
Block a user