Introduce FirstOrDefault extensions method for Array.Find and List.Find.

This allows the LINQ spelling to be used, but benefits from the performance improvement of the specific methods for these classes that provide the same result.
This commit is contained in:
RoosterDragon
2023-11-17 09:49:27 +00:00
committed by Gustas
parent acca837142
commit e6914f707a
54 changed files with 83 additions and 89 deletions

View File

@@ -135,6 +135,16 @@ namespace OpenRA
return Array.IndexOf(array, value);
}
public static T FirstOrDefault<T>(this T[] array, Predicate<T> match)
{
return Array.Find(array, match);
}
public static T FirstOrDefault<T>(this List<T> list, Predicate<T> match)
{
return list.Find(match);
}
public static T Random<T>(this IEnumerable<T> ts, MersenneTwister r)
{
return Random(ts, r, true);

View File

@@ -328,7 +328,7 @@ namespace OpenRA.FileSystem
if (name == ".")
continue;
resolved = Array.Find(Directory.GetFileSystemEntries(resolved), e => e.Equals(Path.Combine(resolved, name), StringComparison.InvariantCultureIgnoreCase));
resolved = Directory.GetFileSystemEntries(resolved).FirstOrDefault(e => e.Equals(Path.Combine(resolved, name), StringComparison.InvariantCultureIgnoreCase));
if (resolved == null)
return null;

View File

@@ -9,7 +9,6 @@
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Server;
@@ -43,7 +42,7 @@ namespace OpenRA.Network
static Player FindPlayerByClient(this World world, Session.Client c)
{
return Array.Find(world.Players, p => p.ClientIndex == c.Index && p.PlayerReference.Playable);
return world.Players.FirstOrDefault(p => p.ClientIndex == c.Index && p.PlayerReference.Playable);
}
static bool OrderNotFromServerOrWorldIsReplay(int clientId, World world) => clientId != 0 || (world != null && world.IsReplay);
@@ -185,12 +184,12 @@ namespace OpenRA.Network
if (!string.IsNullOrEmpty(order.TargetString))
{
var data = MiniYaml.FromString(order.TargetString);
var saveLastOrdersFrame = data.Find(n => n.Key == "SaveLastOrdersFrame");
var saveLastOrdersFrame = data.FirstOrDefault(n => n.Key == "SaveLastOrdersFrame");
if (saveLastOrdersFrame != null)
orderManager.GameSaveLastFrame =
FieldLoader.GetValue<int>("saveLastOrdersFrame", saveLastOrdersFrame.Value.Value);
var saveSyncFrame = data.Find(n => n.Key == "SaveSyncFrame");
var saveSyncFrame = data.FirstOrDefault(n => n.Key == "SaveSyncFrame");
if (saveSyncFrame != null)
orderManager.GameSaveLastSyncFrame =
FieldLoader.GetValue<int>("SaveSyncFrame", saveSyncFrame.Value.Value);
@@ -375,7 +374,7 @@ namespace OpenRA.Network
var strings = node.Key.Split('@');
if (strings[0] == "ConnectionQuality")
{
var client = orderManager.LobbyInfo.Clients.Find(c => c.Index == Exts.ParseInt32Invariant(strings[1]));
var client = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.Index == Exts.ParseInt32Invariant(strings[1]));
if (client != null)
client.ConnectionQuality = FieldLoader.GetValue<Session.ConnectionQuality>("ConnectionQuality", node.Value.Value);
}

View File

@@ -109,14 +109,14 @@ namespace OpenRA
.Where(f => !requireSelectable || f.Selectable)
.ToList();
var selected = selectableFactions.Find(f => f.InternalName == factionName)
var selected = selectableFactions.FirstOrDefault(f => f.InternalName == factionName)
?? selectableFactions.Random(playerRandom);
// Don't loop infinite
for (var i = 0; i <= 10 && selected.RandomFactionMembers.Count > 0; i++)
{
var faction = selected.RandomFactionMembers.Random(playerRandom);
selected = selectableFactions.Find(f => f.InternalName == faction);
selected = selectableFactions.FirstOrDefault(f => f.InternalName == faction);
if (selected == null)
throw new YamlException($"Unknown faction: {faction}");
@@ -179,7 +179,7 @@ namespace OpenRA
else
{
// Map player
ClientIndex = world.LobbyInfo.Clients.Find(c => c.IsAdmin)?.Index ?? 0; // Owned by the host (TODO: fix this)
ClientIndex = world.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin)?.Index ?? 0; // Owned by the host (TODO: fix this)
Color = pr.Color;
PlayerName = pr.Name;
NonCombatant = pr.NonCombatant;

View File

@@ -211,7 +211,7 @@ namespace OpenRA.Scripting
var bindings = Game.ModData.ObjectCreator.GetTypesImplementing<ScriptGlobal>();
foreach (var b in bindings)
{
var ctor = Array.Find(b.GetConstructors(BindingFlags.Public | BindingFlags.Instance), c =>
var ctor = b.GetConstructors(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(c =>
{
var p = c.GetParameters();
return p.Length == 1 && p[0].ParameterType == typeof(ScriptContext);

View File

@@ -1160,7 +1160,7 @@ namespace OpenRA.Server
}
public bool HasClientWonOrLost(Session.Client client) =>
worldPlayers.Find(p => p?.ClientIndex == client.Index)?.Outcome != WinState.Undefined;
worldPlayers.FirstOrDefault(p => p?.ClientIndex == client.Index)?.Outcome != WinState.Undefined;
public void DropClient(Connection toDrop)
{
@@ -1169,7 +1169,7 @@ namespace OpenRA.Server
orderBuffer?.RemovePlayer(toDrop.PlayerIndex);
Conns.Remove(toDrop);
var dropClient = LobbyInfo.Clients.Find(c => c.Index == toDrop.PlayerIndex);
var dropClient = LobbyInfo.Clients.FirstOrDefault(c => c.Index == toDrop.PlayerIndex);
if (dropClient == null)
{
toDrop.Dispose();

View File

@@ -348,7 +348,7 @@ namespace OpenRA
LoadSectionYaml(yamlSection.Value, settingsSection);
}
var keysNode = yamlCache.Find(n => n.Key == "Keys");
var keysNode = yamlCache.FirstOrDefault(n => n.Key == "Keys");
if (keysNode != null)
foreach (var node in keysNode.Value.Nodes)
if (node.Key != null)
@@ -373,7 +373,7 @@ namespace OpenRA
var yamlCacheBuilder = yamlCache.ConvertAll(n => new MiniYamlNodeBuilder(n));
foreach (var kv in Sections)
{
var sectionYaml = yamlCacheBuilder.Find(x => x.Key == kv.Key);
var sectionYaml = yamlCacheBuilder.FirstOrDefault(x => x.Key == kv.Key);
if (sectionYaml == null)
{
sectionYaml = new MiniYamlNodeBuilder(kv.Key, new MiniYamlBuilder(""));
@@ -403,7 +403,7 @@ namespace OpenRA
}
}
var keysYaml = yamlCacheBuilder.Find(x => x.Key == "Keys");
var keysYaml = yamlCacheBuilder.FirstOrDefault(x => x.Key == "Keys");
if (keysYaml == null)
{
keysYaml = new MiniYamlNodeBuilder("Keys", new MiniYamlBuilder(""));