When handling the Nodes collection in MiniYaml, individual nodes are located via one of two methods:
// Lookup a single key with linear search.
var node = yaml.Nodes.FirstOrDefault(n => n.Key == "SomeKey");
// Convert to dictionary, expecting many key lookups.
var dict = nodes.ToDictionary();
// Lookup a single key in the dictionary.
var node = dict["SomeKey"];
To simplify lookup of individual keys via linear search, provide helper methods NodeWithKeyOrDefault and NodeWithKey. These helpers do the equivalent of Single{OrDefault} searches. Whilst this requires checking the whole list, it provides a useful correctness check. Two duplicated keys in TS yaml are fixed as a result. We can also optimize the helpers to not use LINQ, avoiding allocation of the delegate to search for a key.
Adjust existing code to use either lnear searches or dictionary lookups based on whether it will be resolving many keys. Resolving few keys can be done with linear searches to avoid building a dictionary. Resolving many keys should be done with a dictionary to avoid quaradtic runtime from repeated linear searches.
73 lines
1.7 KiB
C#
73 lines
1.7 KiB
C#
#region Copyright & License Information
|
|
/*
|
|
* Copyright (c) The OpenRA Developers and Contributors
|
|
* This file is part of OpenRA, which is free software. It is made
|
|
* available to you under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation, either version 3 of
|
|
* the License, or (at your option) any later version. For more
|
|
* information, see COPYING.
|
|
*/
|
|
#endregion
|
|
|
|
using System.Collections.Generic;
|
|
|
|
namespace OpenRA
|
|
{
|
|
public class PlayerProfile
|
|
{
|
|
public readonly string Fingerprint;
|
|
public readonly string PublicKey;
|
|
public readonly bool KeyRevoked;
|
|
|
|
public readonly int ProfileID;
|
|
public readonly string ProfileName;
|
|
public readonly string ProfileRank = "Registered Player";
|
|
|
|
[FieldLoader.LoadUsing(nameof(LoadBadges))]
|
|
public readonly List<PlayerBadge> Badges;
|
|
|
|
static object LoadBadges(MiniYaml yaml)
|
|
{
|
|
var badges = new List<PlayerBadge>();
|
|
|
|
var badgesNode = yaml.NodeWithKeyOrDefault("Badges");
|
|
if (badgesNode != null)
|
|
{
|
|
var playerDatabase = Game.ModData.Manifest.Get<PlayerDatabase>();
|
|
foreach (var badgeNode in badgesNode.Value.Nodes)
|
|
{
|
|
Game.RunAfterTick(() =>
|
|
{
|
|
// Discard badge on error
|
|
try
|
|
{
|
|
var badge = playerDatabase.LoadBadge(badgeNode.Value);
|
|
if (badge != null)
|
|
badges.Add(badge);
|
|
}
|
|
catch { }
|
|
});
|
|
}
|
|
}
|
|
|
|
return badges;
|
|
}
|
|
}
|
|
|
|
public class PlayerBadge
|
|
{
|
|
public readonly string Label;
|
|
public readonly string Icon;
|
|
public readonly string Icon2x;
|
|
public readonly string Icon3x;
|
|
|
|
public PlayerBadge(string label, string icon, string icon2x, string icon3x)
|
|
{
|
|
Label = label;
|
|
Icon = icon;
|
|
Icon2x = icon2x;
|
|
Icon3x = icon3x;
|
|
}
|
|
}
|
|
}
|