Decode real packed event compact control
This commit is contained in:
parent
45f258cf5d
commit
4ff6d65774
12 changed files with 483 additions and 41 deletions
|
|
@ -6,6 +6,7 @@ use serde::{Deserialize, Serialize};
|
|||
use crate::persistence::{load_runtime_snapshot_document, validate_runtime_snapshot_document};
|
||||
use crate::{
|
||||
CalendarPoint, RuntimeEffect, RuntimeEventRecord, RuntimeEventRecordTemplate,
|
||||
RuntimePackedEventCompactControlSummary,
|
||||
RuntimePackedEventConditionRowSummary, RuntimePackedEventGroupedEffectRowSummary,
|
||||
RuntimePackedEventCollectionSummary, RuntimePackedEventRecordSummary,
|
||||
RuntimePackedEventTextBandSummary, RuntimeSaveProfileState, RuntimeServiceState, RuntimeState,
|
||||
|
|
@ -564,6 +565,10 @@ fn runtime_packed_event_record_summary_from_smp(
|
|||
active: record.active,
|
||||
marks_collection_dirty: record.marks_collection_dirty,
|
||||
one_shot: record.one_shot,
|
||||
compact_control: record
|
||||
.compact_control
|
||||
.as_ref()
|
||||
.map(runtime_packed_event_compact_control_summary_from_smp),
|
||||
text_bands: record
|
||||
.text_bands
|
||||
.iter()
|
||||
|
|
@ -592,6 +597,23 @@ fn runtime_packed_event_record_summary_from_smp(
|
|||
}
|
||||
}
|
||||
|
||||
fn runtime_packed_event_compact_control_summary_from_smp(
|
||||
control: &crate::SmpLoadedPackedEventCompactControlSummary,
|
||||
) -> RuntimePackedEventCompactControlSummary {
|
||||
RuntimePackedEventCompactControlSummary {
|
||||
mode_byte_0x7ef: control.mode_byte_0x7ef,
|
||||
primary_selector_0x7f0: control.primary_selector_0x7f0,
|
||||
grouped_mode_0x7f4: control.grouped_mode_0x7f4,
|
||||
one_shot_header_0x7f5: control.one_shot_header_0x7f5,
|
||||
modifier_flag_0x7f9: control.modifier_flag_0x7f9,
|
||||
modifier_flag_0x7fa: control.modifier_flag_0x7fa,
|
||||
grouped_target_scope_ordinals_0x7fb: control.grouped_target_scope_ordinals_0x7fb.clone(),
|
||||
grouped_scope_checkboxes_0x7ff: control.grouped_scope_checkboxes_0x7ff.clone(),
|
||||
summary_toggle_0x800: control.summary_toggle_0x800,
|
||||
grouped_territory_selectors_0x80f: control.grouped_territory_selectors_0x80f.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn runtime_packed_event_text_band_summary_from_smp(
|
||||
band: &SmpLoadedPackedEventTextBandSummary,
|
||||
) -> RuntimePackedEventTextBandSummary {
|
||||
|
|
@ -803,7 +825,10 @@ fn determine_packed_event_import_outcome(
|
|||
return "blocked_unsupported_decode".to_string();
|
||||
}
|
||||
if record.payload_family == "real_packed_v1" {
|
||||
return "blocked_structural_only".to_string();
|
||||
if record.compact_control.is_none() {
|
||||
return "blocked_missing_compact_control".to_string();
|
||||
}
|
||||
return "blocked_unmapped_real_descriptor".to_string();
|
||||
}
|
||||
if packed_record_requires_missing_company_context(record, known_company_ids) {
|
||||
return "blocked_missing_company_context".to_string();
|
||||
|
|
@ -1208,6 +1233,21 @@ mod tests {
|
|||
}]
|
||||
}
|
||||
|
||||
fn real_compact_control() -> crate::SmpLoadedPackedEventCompactControlSummary {
|
||||
crate::SmpLoadedPackedEventCompactControlSummary {
|
||||
mode_byte_0x7ef: 6,
|
||||
primary_selector_0x7f0: 0x63,
|
||||
grouped_mode_0x7f4: 2,
|
||||
one_shot_header_0x7f5: 1,
|
||||
modifier_flag_0x7f9: 1,
|
||||
modifier_flag_0x7fa: 0,
|
||||
grouped_target_scope_ordinals_0x7fb: vec![0, 1, 2, 3],
|
||||
grouped_scope_checkboxes_0x7ff: vec![1, 0, 1, 0],
|
||||
summary_toggle_0x800: 1,
|
||||
grouped_territory_selectors_0x80f: vec![-1, 10, -1, 22],
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn loads_dump_document() {
|
||||
let text = serde_json::to_string(&RuntimeStateDumpDocument {
|
||||
|
|
@ -1429,6 +1469,7 @@ mod tests {
|
|||
active: None,
|
||||
marks_collection_dirty: None,
|
||||
one_shot: None,
|
||||
compact_control: None,
|
||||
text_bands: Vec::new(),
|
||||
standalone_condition_row_count: 0,
|
||||
standalone_condition_rows: Vec::new(),
|
||||
|
|
@ -1449,6 +1490,7 @@ mod tests {
|
|||
active: None,
|
||||
marks_collection_dirty: None,
|
||||
one_shot: None,
|
||||
compact_control: None,
|
||||
text_bands: Vec::new(),
|
||||
standalone_condition_row_count: 0,
|
||||
standalone_condition_rows: Vec::new(),
|
||||
|
|
@ -1469,6 +1511,7 @@ mod tests {
|
|||
active: None,
|
||||
marks_collection_dirty: None,
|
||||
one_shot: None,
|
||||
compact_control: None,
|
||||
text_bands: Vec::new(),
|
||||
standalone_condition_row_count: 0,
|
||||
standalone_condition_rows: Vec::new(),
|
||||
|
|
@ -1679,6 +1722,7 @@ mod tests {
|
|||
active: Some(true),
|
||||
marks_collection_dirty: Some(true),
|
||||
one_shot: Some(false),
|
||||
compact_control: None,
|
||||
text_bands: packed_text_bands(),
|
||||
standalone_condition_row_count: 1,
|
||||
standalone_condition_rows: vec![],
|
||||
|
|
@ -1788,6 +1832,7 @@ mod tests {
|
|||
active: Some(true),
|
||||
marks_collection_dirty: Some(false),
|
||||
one_shot: Some(false),
|
||||
compact_control: None,
|
||||
text_bands: packed_text_bands(),
|
||||
standalone_condition_row_count: 0,
|
||||
standalone_condition_rows: vec![],
|
||||
|
|
@ -1839,7 +1884,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn leaves_real_structural_records_blocked_structural_only() {
|
||||
fn leaves_real_records_without_compact_control_blocked_missing_compact_control() {
|
||||
let save_slice = SmpLoadedSaveSlice {
|
||||
file_extension_hint: Some("gms".to_string()),
|
||||
container_profile_family: Some("rt3-classic-save-container-v1".to_string()),
|
||||
|
|
@ -1876,6 +1921,7 @@ mod tests {
|
|||
active: None,
|
||||
marks_collection_dirty: None,
|
||||
one_shot: None,
|
||||
compact_control: None,
|
||||
text_bands: packed_text_bands(),
|
||||
standalone_condition_row_count: 1,
|
||||
standalone_condition_rows: real_condition_rows(),
|
||||
|
|
@ -1903,7 +1949,7 @@ mod tests {
|
|||
.packed_event_collection
|
||||
.as_ref()
|
||||
.and_then(|summary| summary.records[0].import_outcome.as_deref()),
|
||||
Some("blocked_structural_only")
|
||||
Some("blocked_missing_compact_control")
|
||||
);
|
||||
assert_eq!(
|
||||
import
|
||||
|
|
@ -1923,6 +1969,85 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn leaves_real_records_with_compact_control_blocked_unmapped_real_descriptor() {
|
||||
let save_slice = SmpLoadedSaveSlice {
|
||||
file_extension_hint: Some("gms".to_string()),
|
||||
container_profile_family: Some("rt3-classic-save-container-v1".to_string()),
|
||||
mechanism_family: "classic-save-rehydrate-v1".to_string(),
|
||||
mechanism_confidence: "grounded".to_string(),
|
||||
trailer_family: None,
|
||||
bridge_family: None,
|
||||
profile: None,
|
||||
candidate_availability_table: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
mechanism_family: "classic-save-rehydrate-v1".to_string(),
|
||||
mechanism_confidence: "grounded".to_string(),
|
||||
container_profile_family: Some("rt3-classic-save-container-v1".to_string()),
|
||||
metadata_tag_offset: 0x7100,
|
||||
records_tag_offset: 0x7200,
|
||||
close_tag_offset: 0x7600,
|
||||
packed_state_version: 0x3e9,
|
||||
packed_state_version_hex: "0x000003e9".to_string(),
|
||||
live_id_bound: 7,
|
||||
live_record_count: 1,
|
||||
live_entry_ids: vec![7],
|
||||
decoded_record_count: 1,
|
||||
imported_runtime_record_count: 0,
|
||||
records: vec![crate::SmpLoadedPackedEventRecordSummary {
|
||||
record_index: 0,
|
||||
live_entry_id: 7,
|
||||
payload_offset: Some(0x7202),
|
||||
payload_len: Some(133),
|
||||
decode_status: "parity_only".to_string(),
|
||||
payload_family: "real_packed_v1".to_string(),
|
||||
trigger_kind: Some(6),
|
||||
active: None,
|
||||
marks_collection_dirty: None,
|
||||
one_shot: Some(true),
|
||||
compact_control: Some(real_compact_control()),
|
||||
text_bands: packed_text_bands(),
|
||||
standalone_condition_row_count: 1,
|
||||
standalone_condition_rows: real_condition_rows(),
|
||||
grouped_effect_row_counts: vec![1, 0, 0, 0],
|
||||
grouped_effect_rows: real_grouped_rows(),
|
||||
decoded_actions: vec![],
|
||||
executable_import_ready: false,
|
||||
notes: vec!["decoded from grounded real 0x4e9a row framing".to_string()],
|
||||
}],
|
||||
}),
|
||||
notes: vec![],
|
||||
};
|
||||
|
||||
let import = project_save_slice_to_runtime_state_import(
|
||||
&save_slice,
|
||||
"packed-events-real-descriptor-frontier",
|
||||
None,
|
||||
)
|
||||
.expect("save slice should project");
|
||||
|
||||
assert!(import.state.event_runtime_records.is_empty());
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.packed_event_collection
|
||||
.as_ref()
|
||||
.and_then(|summary| summary.records[0].compact_control.as_ref())
|
||||
.map(|control| control.mode_byte_0x7ef),
|
||||
Some(6)
|
||||
);
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.packed_event_collection
|
||||
.as_ref()
|
||||
.and_then(|summary| summary.records[0].import_outcome.as_deref()),
|
||||
Some("blocked_unmapped_real_descriptor")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn overlays_save_slice_events_onto_base_company_context() {
|
||||
let base_state = RuntimeState {
|
||||
|
|
@ -1997,6 +2122,7 @@ mod tests {
|
|||
active: Some(true),
|
||||
marks_collection_dirty: Some(false),
|
||||
one_shot: Some(false),
|
||||
compact_control: None,
|
||||
text_bands: packed_text_bands(),
|
||||
standalone_condition_row_count: 0,
|
||||
standalone_condition_rows: vec![],
|
||||
|
|
@ -2150,6 +2276,7 @@ mod tests {
|
|||
active: Some(true),
|
||||
marks_collection_dirty: Some(false),
|
||||
one_shot: Some(false),
|
||||
compact_control: None,
|
||||
text_bands: packed_text_bands(),
|
||||
standalone_condition_row_count: 0,
|
||||
standalone_condition_rows: vec![],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue