feat(prototype): trace unit component edges
This commit is contained in:
@@ -1627,6 +1627,7 @@ fn provenance_for_resource(
|
|||||||
PrototypeGraphProvenance {
|
PrototypeGraphProvenance {
|
||||||
root_index,
|
root_index,
|
||||||
parent_edge,
|
parent_edge,
|
||||||
|
unit_component_index: None,
|
||||||
archive: Some(resource.archive.display_lossy().to_string()),
|
archive: Some(resource.archive.display_lossy().to_string()),
|
||||||
resource: Some(resource.name.0.clone()),
|
resource: Some(resource.name.0.clone()),
|
||||||
span: None,
|
span: None,
|
||||||
@@ -2020,6 +2021,7 @@ fn push_visual_failure(
|
|||||||
provenance: Some(PrototypeGraphProvenance {
|
provenance: Some(PrototypeGraphProvenance {
|
||||||
root_index,
|
root_index,
|
||||||
parent_edge,
|
parent_edge,
|
||||||
|
unit_component_index: None,
|
||||||
archive: dependency.map(|resource| resource.archive.as_str().to_string()),
|
archive: dependency.map(|resource| resource.archive.as_str().to_string()),
|
||||||
resource: Some(resource_raw),
|
resource: Some(resource_raw),
|
||||||
span: None,
|
span: None,
|
||||||
|
|||||||
@@ -169,6 +169,12 @@ pub struct PrototypeGraphProvenance {
|
|||||||
pub root_index: usize,
|
pub root_index: usize,
|
||||||
/// Immediate parent edge that discovered this edge.
|
/// Immediate parent edge that discovered this edge.
|
||||||
pub parent_edge: Option<PrototypeGraphEdgeId>,
|
pub parent_edge: Option<PrototypeGraphEdgeId>,
|
||||||
|
/// Ordered Unit DAT record selected for this path, when the root is a
|
||||||
|
/// decoded multi-component unit.
|
||||||
|
///
|
||||||
|
/// The index identifies source provenance only; it does not classify the
|
||||||
|
/// component as physics, Control, animation, or any other subsystem.
|
||||||
|
pub unit_component_index: Option<usize>,
|
||||||
/// Source archive when available.
|
/// Source archive when available.
|
||||||
pub archive: Option<String>,
|
pub archive: Option<String>,
|
||||||
/// Source resource key when available.
|
/// Source resource key when available.
|
||||||
@@ -755,8 +761,12 @@ pub fn build_prototype_graph(
|
|||||||
graph
|
graph
|
||||||
.root_unit_components
|
.root_unit_components
|
||||||
.push(expansion.unit_components.clone());
|
.push(expansion.unit_components.clone());
|
||||||
let root_provenance = provenance_for_root(root_index, root);
|
let unit_component_count = expansion.unit_components.len();
|
||||||
for prototype in expansion.prototypes {
|
for (prototype_index, prototype) in expansion.prototypes.into_iter().enumerate() {
|
||||||
|
let unit_component_index = is_unit_dat_root
|
||||||
|
.then_some(prototype_index)
|
||||||
|
.filter(|index| *index < unit_component_count);
|
||||||
|
let root_provenance = provenance_for_root(root_index, root, unit_component_index);
|
||||||
let prototype_node = PrototypeGraphNode::prototype(
|
let prototype_node = PrototypeGraphNode::prototype(
|
||||||
prototype.key.clone(),
|
prototype.key.clone(),
|
||||||
PrototypeGraphNodeId(next_node),
|
PrototypeGraphNodeId(next_node),
|
||||||
@@ -795,6 +805,7 @@ pub fn build_prototype_graph(
|
|||||||
provenance: Some(provenance_for_mesh(
|
provenance: Some(provenance_for_mesh(
|
||||||
root_index,
|
root_index,
|
||||||
root_to_prototype_edge_id,
|
root_to_prototype_edge_id,
|
||||||
|
unit_component_index,
|
||||||
dependency,
|
dependency,
|
||||||
)),
|
)),
|
||||||
});
|
});
|
||||||
@@ -850,8 +861,6 @@ pub fn build_prototype_graph_report(
|
|||||||
root_node,
|
root_node,
|
||||||
));
|
));
|
||||||
let start = graph.prototype_requests.len();
|
let start = graph.prototype_requests.len();
|
||||||
let root_provenance = provenance_for_root(root_index, root);
|
|
||||||
|
|
||||||
match resolve_prototype_requests(repository, vfs, root) {
|
match resolve_prototype_requests(repository, vfs, root) {
|
||||||
Ok(expansion) => {
|
Ok(expansion) => {
|
||||||
let expected = expansion.expected_count;
|
let expected = expansion.expected_count;
|
||||||
@@ -862,7 +871,13 @@ pub fn build_prototype_graph_report(
|
|||||||
report.unit_component_count += expected;
|
report.unit_component_count += expected;
|
||||||
}
|
}
|
||||||
let actual = expansion.prototypes.len();
|
let actual = expansion.prototypes.len();
|
||||||
for prototype in expansion.prototypes {
|
let unit_component_count = expansion.unit_components.len();
|
||||||
|
for (prototype_index, prototype) in expansion.prototypes.into_iter().enumerate() {
|
||||||
|
let unit_component_index = is_unit_dat_root
|
||||||
|
.then_some(prototype_index)
|
||||||
|
.filter(|index| *index < unit_component_count);
|
||||||
|
let root_provenance =
|
||||||
|
provenance_for_root(root_index, root, unit_component_index);
|
||||||
let prototype_node = PrototypeGraphNode::prototype(
|
let prototype_node = PrototypeGraphNode::prototype(
|
||||||
prototype.key.clone(),
|
prototype.key.clone(),
|
||||||
PrototypeGraphNodeId(next_node),
|
PrototypeGraphNodeId(next_node),
|
||||||
@@ -903,6 +918,7 @@ pub fn build_prototype_graph_report(
|
|||||||
provenance: Some(provenance_for_mesh(
|
provenance: Some(provenance_for_mesh(
|
||||||
root_index,
|
root_index,
|
||||||
root_to_prototype_edge_id,
|
root_to_prototype_edge_id,
|
||||||
|
unit_component_index,
|
||||||
dependency,
|
dependency,
|
||||||
)),
|
)),
|
||||||
});
|
});
|
||||||
@@ -924,6 +940,7 @@ pub fn build_prototype_graph_report(
|
|||||||
provenance: Some(PrototypeGraphProvenance {
|
provenance: Some(PrototypeGraphProvenance {
|
||||||
root_index,
|
root_index,
|
||||||
parent_edge: None,
|
parent_edge: None,
|
||||||
|
unit_component_index: None,
|
||||||
archive: None,
|
archive: None,
|
||||||
resource: Some(root.0.clone()),
|
resource: Some(root.0.clone()),
|
||||||
span: None,
|
span: None,
|
||||||
@@ -940,6 +957,7 @@ pub fn build_prototype_graph_report(
|
|||||||
provenance: Some(PrototypeGraphProvenance {
|
provenance: Some(PrototypeGraphProvenance {
|
||||||
root_index,
|
root_index,
|
||||||
parent_edge: None,
|
parent_edge: None,
|
||||||
|
unit_component_index: None,
|
||||||
archive: None,
|
archive: None,
|
||||||
resource: Some(root.0.clone()),
|
resource: Some(root.0.clone()),
|
||||||
span: None,
|
span: None,
|
||||||
@@ -984,10 +1002,15 @@ fn graph_error_edge(edge: PrototypeGraphEdge, err: &PrototypeError) -> Prototype
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn provenance_for_root(root_index: usize, root: &ResourceName) -> PrototypeGraphProvenance {
|
fn provenance_for_root(
|
||||||
|
root_index: usize,
|
||||||
|
root: &ResourceName,
|
||||||
|
unit_component_index: Option<usize>,
|
||||||
|
) -> PrototypeGraphProvenance {
|
||||||
PrototypeGraphProvenance {
|
PrototypeGraphProvenance {
|
||||||
root_index,
|
root_index,
|
||||||
parent_edge: None,
|
parent_edge: None,
|
||||||
|
unit_component_index,
|
||||||
archive: None,
|
archive: None,
|
||||||
resource: Some(root.0.clone()),
|
resource: Some(root.0.clone()),
|
||||||
span: None,
|
span: None,
|
||||||
@@ -997,11 +1020,13 @@ fn provenance_for_root(root_index: usize, root: &ResourceName) -> PrototypeGraph
|
|||||||
fn provenance_for_mesh(
|
fn provenance_for_mesh(
|
||||||
root_index: usize,
|
root_index: usize,
|
||||||
parent_edge: PrototypeGraphEdgeId,
|
parent_edge: PrototypeGraphEdgeId,
|
||||||
|
unit_component_index: Option<usize>,
|
||||||
dependency: &ResourceKey,
|
dependency: &ResourceKey,
|
||||||
) -> PrototypeGraphProvenance {
|
) -> PrototypeGraphProvenance {
|
||||||
PrototypeGraphProvenance {
|
PrototypeGraphProvenance {
|
||||||
root_index,
|
root_index,
|
||||||
parent_edge: Some(parent_edge),
|
parent_edge: Some(parent_edge),
|
||||||
|
unit_component_index,
|
||||||
archive: Some(dependency.archive.as_str().to_string()),
|
archive: Some(dependency.archive.as_str().to_string()),
|
||||||
resource: Some(dependency.name.0.clone()),
|
resource: Some(dependency.name.0.clone()),
|
||||||
span: None,
|
span: None,
|
||||||
@@ -1800,6 +1825,35 @@ mod tests {
|
|||||||
cstr_bytes(&graph.root_unit_components[0][1].resource_raw),
|
cstr_bytes(&graph.root_unit_components[0][1].resource_raw),
|
||||||
b"component_b"
|
b"component_b"
|
||||||
);
|
);
|
||||||
|
let component_edges: Vec<_> = graph
|
||||||
|
.edges
|
||||||
|
.iter()
|
||||||
|
.filter(|edge| edge.kind == PrototypeGraphEdgeKind::UnitDatToComponent)
|
||||||
|
.collect();
|
||||||
|
assert_eq!(component_edges.len(), 2);
|
||||||
|
assert_eq!(
|
||||||
|
component_edges[0]
|
||||||
|
.provenance
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|provenance| provenance.unit_component_index),
|
||||||
|
Some(0)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
component_edges[1]
|
||||||
|
.provenance
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|provenance| provenance.unit_component_index),
|
||||||
|
Some(1)
|
||||||
|
);
|
||||||
|
assert!(graph
|
||||||
|
.edges
|
||||||
|
.iter()
|
||||||
|
.filter(|edge| edge.kind == PrototypeGraphEdgeKind::PrototypeToMesh)
|
||||||
|
.all(|edge| edge
|
||||||
|
.provenance
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|value| value.unit_component_index)
|
||||||
|
.is_some()));
|
||||||
assert_eq!(resolved.len(), 2);
|
assert_eq!(resolved.len(), 2);
|
||||||
assert_eq!(report.unit_reference_count, 1);
|
assert_eq!(report.unit_reference_count, 1);
|
||||||
assert_eq!(report.unit_component_count, 2);
|
assert_eq!(report.unit_component_count, 2);
|
||||||
|
|||||||
@@ -475,6 +475,11 @@ string длиной 32 байта. Требование обязательног
|
|||||||
составного unit для будущих Control/physics/AniMesh consumers, но не выдаёт
|
составного unit для будущих Control/physics/AniMesh consumers, но не выдаёт
|
||||||
структурное сходство за доказанную семантику.
|
структурное сходство за доказанную семантику.
|
||||||
|
|
||||||
|
Каждый graph edge от `UnitDatRoot` к effective component и далее к его MSH
|
||||||
|
dependency также несёт `unit_component_index`. Это индекс исходной записи в
|
||||||
|
порядке файла, а не тип компонента; по нему diagnostics и будущие consumers
|
||||||
|
могут однозначно вернуться к raw 112-byte record.
|
||||||
|
|
||||||
## Вспомогательные форматы
|
## Вспомогательные форматы
|
||||||
|
|
||||||
MSH, материал и текстура отвечают за видимую форму. Полноценный прототип
|
MSH, материал и текстура отвечают за видимую форму. Полноценный прототип
|
||||||
|
|||||||
Reference in New Issue
Block a user