Skip to content

Make I:R character attribute parsing thread-safe #2006

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 33 additions & 33 deletions ImperatorToCK3/Imperator/Characters/Character.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,49 +111,49 @@ public string AgeSex {

public CK3.Characters.Character? CK3Character { get; set; }
public static ConcurrentIgnoredKeywordsSet IgnoredTokens { get; } = [];
public static void RegisterCharacterKeywords(Parser parser, Character parsedCharacter) {
public static void RegisterCharacterKeywords(Parser parser, Character character) {
parser.RegisterKeyword("first_name_loc", reader => {
var characterName = new CharacterName(reader);
parsedCharacter.Name = characterName.Name;
parsedCharacter.CustomName = characterName.CustomName;
character.Name = characterName.Name;
character.CustomName = characterName.CustomName;
});
parser.RegisterKeyword("family_name", reader => parsedCharacter.FamilyName = reader.GetString());
parser.RegisterKeyword("country", reader => parsedCharacter.parsedCountryId = reader.GetULong());
parser.RegisterKeyword("home_country", reader => parsedCharacter.parsedHomeCountryId = reader.GetULong());
parser.RegisterKeyword("province", reader => parsedCharacter.ProvinceId = reader.GetULong());
parser.RegisterKeyword("culture", reader => parsedCharacter.culture = reader.GetString());
parser.RegisterKeyword("religion", reader => parsedCharacter.Religion = reader.GetString());
parser.RegisterKeyword("fertility", reader => parsedCharacter.Fertility = reader.GetDouble());
parser.RegisterKeyword("health", reader => parsedCharacter.Health = reader.GetDouble());
parser.RegisterKeyword("family", reader => parsedCharacter.parsedFamilyId = reader.GetULong());
parser.RegisterKeyword("traits", reader => parsedCharacter.Traits = reader.GetStrings());
parser.RegisterKeyword("female", reader => parsedCharacter.Female = reader.GetBool());
parser.RegisterKeyword("children", reader => parsedCharacter.parsedChildrenIds = reader.GetULongs().ToHashSet());
parser.RegisterKeyword("spouse", reader => parsedCharacter.parsedSpouseIds = reader.GetULongs().ToHashSet());
parser.RegisterKeyword("family_name", reader => character.FamilyName = reader.GetString());
parser.RegisterKeyword("country", reader => character.parsedCountryId = reader.GetULong());
parser.RegisterKeyword("home_country", reader => character.parsedHomeCountryId = reader.GetULong());
parser.RegisterKeyword("province", reader => character.ProvinceId = reader.GetULong());
parser.RegisterKeyword("culture", reader => character.culture = reader.GetString());
parser.RegisterKeyword("religion", reader => character.Religion = reader.GetString());
parser.RegisterKeyword("fertility", reader => character.Fertility = reader.GetDouble());
parser.RegisterKeyword("health", reader => character.Health = reader.GetDouble());
parser.RegisterKeyword("family", reader => character.parsedFamilyId = reader.GetULong());
parser.RegisterKeyword("traits", reader => character.Traits = reader.GetStrings());
parser.RegisterKeyword("female", reader => character.Female = reader.GetBool());
parser.RegisterKeyword("children", reader => character.parsedChildrenIds = [.. reader.GetULongs()]);
parser.RegisterKeyword("spouse", reader => character.parsedSpouseIds = [.. reader.GetULongs()]);
parser.RegisterKeyword("friends", reader => {
parsedCharacter.FriendIds.Clear();
parsedCharacter.FriendIds.AddRange(reader.GetULongs());
character.FriendIds.Clear();
character.FriendIds.AddRange(reader.GetULongs());
});
parser.RegisterKeyword("rivals", reader => {
parsedCharacter.RivalIds.Clear();
parsedCharacter.RivalIds.AddRange(reader.GetULongs());
character.RivalIds.Clear();
character.RivalIds.AddRange(reader.GetULongs());
});
parser.RegisterKeyword("age", reader => parsedCharacter.Age = (uint)reader.GetInt());
parser.RegisterKeyword("age", reader => character.Age = (uint)reader.GetInt());
parser.RegisterKeyword("birth_date", reader => {
var dateStr = reader.GetString();
parsedCharacter.BirthDate = new Date(dateStr, true); // converted to AD
character.BirthDate = new Date(dateStr, true); // converted to AD
});
parser.RegisterKeyword("death_date", reader => {
var dateStr = reader.GetString();
parsedCharacter.DeathDate = new Date(dateStr, true); // converted to AD
character.DeathDate = new Date(dateStr, true); // converted to AD
});
parser.RegisterKeyword("death", reader => parsedCharacter.DeathReason = reader.GetString());
parser.RegisterKeyword("attributes", reader => parsedCharacter.Attributes = CharacterAttributes.Parse(reader));
parser.RegisterKeyword("nickname", reader => parsedCharacter.Nickname = reader.GetString());
parser.RegisterKeyword("dna", reader => parsedCharacter.DNA = reader.GetString());
parser.RegisterKeyword("mother", reader => parsedCharacter.parsedMotherId = reader.GetULong());
parser.RegisterKeyword("father", reader => parsedCharacter.parsedFatherId = reader.GetULong());
parser.RegisterKeyword("wealth", reader => parsedCharacter.Wealth = reader.GetDouble());
parser.RegisterKeyword("death", reader => character.DeathReason = reader.GetString());
parser.RegisterKeyword("attributes", reader => character.Attributes = CharacterAttributes.Parse(reader));
parser.RegisterKeyword("nickname", reader => character.Nickname = reader.GetString());
parser.RegisterKeyword("dna", reader => character.DNA = reader.GetString());
parser.RegisterKeyword("mother", reader => character.parsedMotherId = reader.GetULong());
parser.RegisterKeyword("father", reader => character.parsedFatherId = reader.GetULong());
parser.RegisterKeyword("wealth", reader => character.Wealth = reader.GetDouble());
parser.RegisterKeyword("unborn", reader => {
var unborns = new List<Unborn>();
foreach (var blob in new BlobList(reader).Blobs) {
Expand All @@ -164,9 +164,9 @@ public static void RegisterCharacterKeywords(Parser parser, Character parsedChar
}
unborns.Add(unborn);
}
parsedCharacter.Unborns = unborns.ToImmutableList();
character.Unborns = unborns.ToImmutableList();
});
parser.RegisterKeyword("prisoner_home", reader => parsedCharacter.parsedPrisonerHomeId = reader.GetULong());
parser.RegisterKeyword("prisoner_home", reader => character.parsedPrisonerHomeId = reader.GetULong());
parser.RegisterKeyword("variables", reader => {
var variables = new HashSet<string>();
var variablesParser = new Parser();
Expand All @@ -183,7 +183,7 @@ public static void RegisterCharacterKeywords(Parser parser, Character parsedChar
variablesParser.RegisterKeyword("list", ParserHelpers.IgnoreItem);
variablesParser.IgnoreAndLogUnregisteredItems();
variablesParser.ParseStream(reader);
parsedCharacter.Variables = variables.ToImmutableHashSet();
character.Variables = variables.ToImmutableHashSet();
});
parser.IgnoreAndStoreUnregisteredItems(IgnoredTokens);
}
Expand Down
21 changes: 10 additions & 11 deletions ImperatorToCK3/Imperator/Characters/CharacterAttributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,17 @@ public class CharacterAttributes {
public int Charisma { get; set; } = 0;
public int Zeal { get; set; } = 0;

private static CharacterAttributes parsedAttributes = new();
private static readonly Parser parser = new();
static CharacterAttributes() {
parser.RegisterKeyword("martial", reader => parsedAttributes.Martial = reader.GetInt());
parser.RegisterKeyword("finesse", reader => parsedAttributes.Finesse = reader.GetInt());
parser.RegisterKeyword("charisma", reader => parsedAttributes.Charisma = reader.GetInt());
parser.RegisterKeyword("zeal", reader => parsedAttributes.Zeal = reader.GetInt());
parser.IgnoreAndLogUnregisteredItems();
}
public static CharacterAttributes Parse(BufferedReader reader) {
parsedAttributes = new CharacterAttributes();
var attributes = new CharacterAttributes();

var parser = new Parser();
parser.RegisterKeyword("martial", r => attributes.Martial = r.GetInt());
parser.RegisterKeyword("finesse", r => attributes.Finesse = r.GetInt());
parser.RegisterKeyword("charisma", r => attributes.Charisma = r.GetInt());
parser.RegisterKeyword("zeal", r => attributes.Zeal = r.GetInt());
parser.IgnoreAndLogUnregisteredItems();
parser.ParseStream(reader);
return parsedAttributes;

return attributes;
}
}
6 changes: 4 additions & 2 deletions ImperatorToCK3/Outputter/CharactersOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ public static void OutputCharacters(string outputModName, CharacterCollection ch
.ToImmutableList();
OutputPortraitModifiers(outputModName, charactersWithDNA, conversionDate);

var charactersFromIR = characters.Where(c => c.FromImperator).ToImmutableList();
var charactersFromCK3 = characters.Except(charactersFromIR).ToImmutableList();
var charactersFromIR = characters.Where(c => c.FromImperator)
.OrderBy(c => c.Id).ToImmutableList();
var charactersFromCK3 = characters.Except(charactersFromIR)
.OrderBy(c => c.Id).ToImmutableList();

var pathForCharactersFromIR = $"output/{outputModName}/history/characters/IRToCK3_fromImperator.txt";
using var output = FileOpeningHelper.OpenWriteWithRetries(pathForCharactersFromIR);
Expand Down
Loading