Skip to content

Commit

Permalink
Optimize the loading of CK3 cultures (#2192)
Browse files Browse the repository at this point in the history
This avoids validating a culture twice if it's defined in two or more
places. Should also reduce the number of warnings, if the first
occurrence is from vanilla, and the following ones are added by mods to
modify it.
  • Loading branch information
IhateTrains authored Sep 16, 2024
1 parent f8762d2 commit 70bff92
Showing 1 changed file with 47 additions and 28 deletions.
75 changes: 47 additions & 28 deletions ImperatorToCK3/CK3/Cultures/CultureCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,60 +87,79 @@ private void LoadInvalidatingCultureIds(ICollection<string> ck3ModFlags, Buffere

public void LoadCultures(ModFilesystem ck3ModFS) {
Logger.Info("Loading cultures...");

OrderedDictionary<string, CultureData> culturesData = new(); // Preserves order of insertion.

var parser = new Parser();
parser.RegisterRegex(CommonRegexes.String, (reader, cultureId) => LoadCulture(cultureId, reader));
parser.RegisterRegex(CommonRegexes.String, (reader, cultureId) => culturesData[cultureId] = LoadCultureData(reader));
parser.IgnoreAndLogUnregisteredItems();
parser.ParseGameFolder("common/culture/cultures", ck3ModFS, "txt", recursive: true, logFilePaths: true);

// After we've load all cultures data, we can validate it and create cultures.
ValidateAndLoadCultures(culturesData);

ReplaceInvalidatedParents();
}

public void LoadConverterCultures(string converterCulturesPath) {
Logger.Info("Loading converter cultures...");

OrderedDictionary<string, CultureData> culturesData = new(); // Preserves order of insertion.

var parser = new Parser();
parser.RegisterRegex(CommonRegexes.String, (reader, cultureId) => LoadCulture(cultureId, reader));
parser.RegisterRegex(CommonRegexes.String, (reader, cultureId) => culturesData[cultureId] = LoadCultureData(reader));
parser.IgnoreAndLogUnregisteredItems();
parser.ParseFile(converterCulturesPath);

// After we've load all cultures data, we can validate it and create cultures.
ValidateAndLoadCultures(culturesData);

ReplaceInvalidatedParents();
}

private void LoadCulture(string cultureId, BufferedReader cultureReader) {
private CultureData LoadCultureData(BufferedReader cultureReader) {
cultureData = new CultureData();

cultureDataParser.ParseStream(cultureReader);
return cultureData;
}

if (cultureData.InvalidatingCultureIds.Any()) {
foreach (var existingCulture in this) {
if (!cultureData.InvalidatingCultureIds.Contains(existingCulture.Id)) {
private void ValidateAndLoadCultures(OrderedDictionary<string, CultureData> culturesData) {
foreach (var (cultureId, data) in culturesData) {
if (data.InvalidatingCultureIds.Any()) {
bool isInvalidated = false;
foreach (var existingCulture in this) {
if (!data.InvalidatingCultureIds.Contains(existingCulture.Id)) {
continue;
}
Logger.Debug($"Culture {cultureId} is invalidated by existing {existingCulture.Id}.");
cultureReplacements[cultureId] = existingCulture.Id;
isInvalidated = true;
}
if (isInvalidated) {
continue;
}
Logger.Debug($"Culture {cultureId} is invalidated by existing {existingCulture.Id}.");
cultureReplacements[cultureId] = existingCulture.Id;
return;
Logger.Debug($"Loading optional culture {cultureId}...");
}
Logger.Debug($"Loading optional culture {cultureId}...");
}
if (cultureData.Heritage is null) {
Logger.Warn($"Culture {cultureId} has no heritage defined! Skipping.");
return;
}
if (cultureData.Language is null) {
Logger.Warn($"Culture {cultureId} has no language defined! Skipping.");
return;
}
if (cultureData.NameLists.Count == 0) {
Logger.Warn($"Culture {cultureId} has no name list defined! Skipping.");
return;
}
if (cultureData.Color is null) {
Logger.Warn($"Culture {cultureId} has no color defined! Will use generated color.");
var color = new ColorHash().Rgb(cultureId);
cultureData.Color = new Color(color.R, color.G, color.B);
if (data.Heritage is null) {
Logger.Warn($"Culture {cultureId} has no heritage defined! Skipping.");
continue;
}
if (data.Language is null) {
Logger.Warn($"Culture {cultureId} has no language defined! Skipping.");
continue;
}
if (data.NameLists.Count == 0) {
Logger.Warn($"Culture {cultureId} has no name list defined! Skipping.");
continue;
}
if (data.Color is null) {
Logger.Warn($"Culture {cultureId} has no color defined! Will use generated color.");
var color = new ColorHash().Rgb(cultureId);
data.Color = new Color(color.R, color.G, color.B);
}
AddOrReplace(new Culture(cultureId, data));
}
AddOrReplace(new Culture(cultureId, cultureData));
}

private void ReplaceInvalidatedParents() {
Expand Down

0 comments on commit 70bff92

Please sign in to comment.