Fix tail rows in portrait generation

This commit is contained in:
2026-05-25 10:06:40 +02:00
parent 01ddcf8735
commit e6fffdf041
4 changed files with 24 additions and 7 deletions
+1 -1
View File
@@ -876,7 +876,7 @@ func write2DAFile(data parsed2DA, path string) error {
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil && filepath.Dir(path) != "." { if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil && filepath.Dir(path) != "." {
return err return err
} }
return write2DA(table, path, false) return write2DA(table, path, false, -1)
} }
func cloneStringMap(in map[string]string) map[string]string { func cloneStringMap(in map[string]string) map[string]string {
+1 -1
View File
@@ -106,7 +106,7 @@ func buildGenerated2DAAssetGroup(p *project.Project, cfg project.GeneratedTopDat
outputPath := filepath.Join(outputDir, dataset.Dataset.OutputName) outputPath := filepath.Join(outputDir, dataset.Dataset.OutputName)
denseRows := dataset.Dataset.Kind == nativeDatasetBase || denseRows := dataset.Dataset.Kind == nativeDatasetBase ||
(consumer.Mode == "parts_rows" && isPartsDataset(dataset.Dataset.Name)) (consumer.Mode == "parts_rows" && isPartsDataset(dataset.Dataset.Name))
if err := write2DA(compiled, outputPath, denseRows); err != nil { if err := write2DA(compiled, outputPath, denseRows, -1); err != nil {
return nil, err return nil, err
} }
results = append(results, Generated2DAAsset{ results = append(results, Generated2DAAsset{
+15 -2
View File
@@ -48,6 +48,7 @@ type nativeCollectedDataset struct {
LockData map[string]int LockData map[string]int
RetiredKeys map[string]struct{} RetiredKeys map[string]struct{}
TableKey string TableKey string
DenseRowMax int
LockAdded int LockAdded int
LockPruned int LockPruned int
LockModified bool LockModified bool
@@ -370,7 +371,7 @@ func buildNativeUnchecked(p *project.Project, opts NativeBuildOptions, progress
if err != nil { if err != nil {
return BuildResult{}, err return BuildResult{}, err
} }
if err := write2DA(compiled, filepath.Join(output2DA, dataset.Dataset.OutputName), dataset.Dataset.Kind == nativeDatasetBase); err != nil { if err := write2DA(compiled, filepath.Join(output2DA, dataset.Dataset.OutputName), dataset.Dataset.Kind == nativeDatasetBase, dataset.DenseRowMax); err != nil {
return BuildResult{}, err return BuildResult{}, err
} }
} }
@@ -1228,6 +1229,7 @@ func collectBaseDataset(dataset nativeDataset) (nativeCollectedDataset, error) {
Rows: rows, Rows: rows,
LockData: lockData, LockData: lockData,
RetiredKeys: retiredKeys, RetiredKeys: retiredKeys,
DenseRowMax: baseBoundaryID,
LockAdded: lockAdded, LockAdded: lockAdded,
LockPruned: lockPruned, LockPruned: lockPruned,
LockModified: lockModified, LockModified: lockModified,
@@ -5181,7 +5183,7 @@ func normalizeCollectedSpellImpactScripts(rows []map[string]any, baseRowKeys map
} }
} }
func write2DA(data map[string]any, path string, denseRows bool) error { func write2DA(data map[string]any, path string, denseRows bool, denseRowMax int) error {
columns, ok := data["columns"].([]string) columns, ok := data["columns"].([]string)
if !ok { if !ok {
return fmt.Errorf("2da columns must be []string") return fmt.Errorf("2da columns must be []string")
@@ -5223,6 +5225,17 @@ func write2DA(data map[string]any, path string, denseRows bool) error {
nextID = rowID + 1 nextID = rowID + 1
} }
} }
if denseRows {
for nextID <= denseRowMax {
builder.WriteString(strconv.Itoa(nextID))
for range columns {
builder.WriteByte('\t')
builder.WriteString(nullValue)
}
builder.WriteByte('\n')
nextID++
}
}
return os.WriteFile(path, []byte(builder.String()), 0o644) return os.WriteFile(path, []byte(builder.String()), 0o644)
} }
+7 -3
View File
@@ -657,14 +657,16 @@ func TestBuildNativeAllocatesConfiguredDatasetsIntoFirstNullBaseRows(t *testing.
{"id": 0, "key": "portraits:none", "BaseResRef": "****", "Sex": 4}, {"id": 0, "key": "portraits:none", "BaseResRef": "****", "Sex": 4},
{"id": 1, "BaseResRef": "****", "Sex": "****"}, {"id": 1, "BaseResRef": "****", "Sex": "****"},
{"id": 2, "BaseResRef": null, "Sex": null}, {"id": 2, "BaseResRef": null, "Sex": null},
{"id": 3, "key": "portraits:existing", "BaseResRef": "existing_", "Sex": 1} {"id": 3, "key": "portraits:existing", "BaseResRef": "existing_", "Sex": 1},
{"id": 4, "BaseResRef": "****", "Sex": "****"},
{"id": 5, "BaseResRef": "****", "Sex": "****"}
] ]
}`+"\n") }`+"\n")
writeFile(t, filepath.Join(root, "topdata", "data", "portraits", "lock.json"), `{ writeFile(t, filepath.Join(root, "topdata", "data", "portraits", "lock.json"), `{
"portraits:none": 0, "portraits:none": 0,
"portraits:existing": 3, "portraits:existing": 3,
"portraits:first": 4, "portraits:first": 6,
"portraits:second": 5 "portraits:second": 7
}`+"\n") }`+"\n")
writeFile(t, filepath.Join(root, "topdata", "data", "portraits", "modules", "custom.json"), `{ writeFile(t, filepath.Join(root, "topdata", "data", "portraits", "modules", "custom.json"), `{
"entries": { "entries": {
@@ -698,6 +700,8 @@ func TestBuildNativeAllocatesConfiguredDatasetsIntoFirstNullBaseRows(t *testing.
for _, want := range []string{ for _, want := range []string{
"1\tfirst_\t4", "1\tfirst_\t4",
"2\tsecond_\t4", "2\tsecond_\t4",
"4\t****\t****",
"5\t****\t****",
} { } {
if !strings.Contains(output, want) { if !strings.Contains(output, want) {
t.Fatalf("expected generated portraits row %q, got:\n%s", want, output) t.Fatalf("expected generated portraits row %q, got:\n%s", want, output)