fix(core): Removes some uses of Linq (#421)
- [X] Removes some uses of linq - [X] Creates struct based enumerator for Skills - [X] Creates a struct based enumerator for TypeCache - [X] Changes HarvestDefinition to an init array instead of List - [X] Changes HeritageTokenGump Response from List to Array
This commit is contained in:
parent
52356866ed
commit
b921c38879
50 changed files with 1006 additions and 507 deletions
|
|
@ -14,6 +14,7 @@
|
|||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
|
@ -89,40 +90,41 @@ namespace Server
|
|||
return m_TypeCaches[asm] = new TypeCache(asm);
|
||||
}
|
||||
|
||||
public static Type FindFirstTypeForName(string name, bool ignoreCase = false, Func<Type, bool> predicate = null)
|
||||
private static bool IgnoreCaseTypeComparer(string name, Type type) =>
|
||||
type.FullName.InsensitiveEquals(name) || type.Name.InsensitiveEquals(name);
|
||||
|
||||
private static bool CaseTypeComparer(string name, Type type) =>
|
||||
type.FullName.EqualsOrdinal(name) || type.Name.EqualsOrdinal(name);
|
||||
|
||||
public static Type FindFirstTypeForName(string name, bool ignoreCase = false, Func<string, Type, bool> predicate = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var types = FindTypesByName(name, ignoreCase).ToList();
|
||||
var types = FindTypesByName(name, ignoreCase);
|
||||
|
||||
if (types.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (predicate != null)
|
||||
{
|
||||
return types.FirstOrDefault(predicate);
|
||||
}
|
||||
|
||||
if (types.Count == 1)
|
||||
{
|
||||
return types[0];
|
||||
}
|
||||
|
||||
// Try to find the closest match if there is no predicate.
|
||||
// Check for exact match of the FullName or Name
|
||||
// Then check for case-insensitive match of FullName or Name
|
||||
// Otherwise just return the first entry
|
||||
var stringComparer = ignoreCase ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal;
|
||||
predicate ??= ignoreCase ? IgnoreCaseTypeComparer : CaseTypeComparer;
|
||||
|
||||
return types.FirstOrDefault(
|
||||
x =>
|
||||
stringComparer.Equals(x.FullName, name) || stringComparer.Equals(x.Name, name)
|
||||
) ??
|
||||
types[0];
|
||||
foreach (var type in types)
|
||||
{
|
||||
if (predicate(name, type))
|
||||
{
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<Type> FindTypesByName(string name, bool ignoreCase = false)
|
||||
|
|
@ -136,12 +138,18 @@ namespace Server
|
|||
|
||||
for (var i = 0; i < Assemblies.Length; i++)
|
||||
{
|
||||
types.AddRange(GetTypeCache(Assemblies[i])[name]);
|
||||
foreach (var type in GetTypeCache(Assemblies[i])[name])
|
||||
{
|
||||
types.Add(type);
|
||||
}
|
||||
}
|
||||
|
||||
if (types.Count == 0)
|
||||
{
|
||||
types.AddRange(GetTypeCache(Core.Assembly)[name]);
|
||||
foreach(var type in GetTypeCache(Core.Assembly)[name])
|
||||
{
|
||||
types.Add(type);
|
||||
}
|
||||
}
|
||||
|
||||
return types;
|
||||
|
|
@ -159,11 +167,10 @@ namespace Server
|
|||
public class TypeCache
|
||||
{
|
||||
private readonly Dictionary<string, int[]> m_NameMap = new();
|
||||
private readonly Type[] m_Types;
|
||||
|
||||
public TypeCache(Assembly asm)
|
||||
{
|
||||
m_Types = asm?.GetTypes() ?? Type.EmptyTypes;
|
||||
Types = asm?.GetTypes() ?? Type.EmptyTypes;
|
||||
|
||||
var nameMap = new Dictionary<string, HashSet<int>>();
|
||||
HashSet<int> refs;
|
||||
|
|
@ -181,9 +188,9 @@ namespace Server
|
|||
};
|
||||
|
||||
var aliasType = typeof(TypeAliasAttribute);
|
||||
for (var i = 0; i < m_Types.Length; i++)
|
||||
for (var i = 0; i < Types.Length; i++)
|
||||
{
|
||||
var current = m_Types[i];
|
||||
var current = Types[i];
|
||||
addToRefs(i, current.Name);
|
||||
addToRefs(i, current.Name.ToLower());
|
||||
addToRefs(i, current.FullName);
|
||||
|
|
@ -204,10 +211,70 @@ namespace Server
|
|||
}
|
||||
}
|
||||
|
||||
public IEnumerable<Type> Types => m_Types;
|
||||
public IEnumerable<string> Names => m_NameMap.Keys;
|
||||
public Enumerator this[string name] => new(name, this);
|
||||
|
||||
public IEnumerable<Type> this[string name] =>
|
||||
m_NameMap.TryGetValue(name, out var value) ? value.Select(x => m_Types[x]) : Array.Empty<Type>();
|
||||
public Type[] Types { get; }
|
||||
|
||||
public struct Enumerator : IEnumerable<Type>, IEnumerator<Type>
|
||||
{
|
||||
private readonly TypeCache _cache;
|
||||
private readonly int[] _values;
|
||||
private int _index;
|
||||
private Type _current;
|
||||
|
||||
internal Enumerator(string name, TypeCache cache)
|
||||
{
|
||||
_cache = cache;
|
||||
_values = !cache.m_NameMap.TryGetValue(name, out var values) ? Array.Empty<int>() : values;
|
||||
_index = 0;
|
||||
_current = default;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
int[] localList = _values;
|
||||
|
||||
while ((uint)_index < (uint)localList.Length)
|
||||
{
|
||||
_current = _cache.Types[_values[_index++]];
|
||||
|
||||
if (_current != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public Type Current => _current!;
|
||||
|
||||
object IEnumerator.Current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_index == 0 || _index == _values.Length + 1)
|
||||
{
|
||||
throw new InvalidOperationException(nameof(_index));
|
||||
}
|
||||
|
||||
return Current;
|
||||
}
|
||||
}
|
||||
|
||||
void IEnumerator.Reset()
|
||||
{
|
||||
_index = 0;
|
||||
_current = default;
|
||||
}
|
||||
|
||||
public IEnumerator<Type> GetEnumerator() => this;
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Server.ContextMenus
|
||||
{
|
||||
|
|
@ -64,7 +63,21 @@ namespace Server.ContextMenus
|
|||
/// <summary>
|
||||
/// Returns true if this ContextMenu requires packet version 2.
|
||||
/// </summary>
|
||||
public bool RequiresNewPacket =>
|
||||
Entries.Any(t => t.Number < 3000000 || t.Number > 3032767);
|
||||
public bool RequiresNewPacket
|
||||
{
|
||||
get
|
||||
{
|
||||
for (var i = 0; i < Entries.Length; ++i)
|
||||
{
|
||||
var number = Entries[i].Number;
|
||||
if (number < 3000000 || number > 3032767)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Server.Guilds
|
||||
{
|
||||
|
|
@ -43,11 +42,31 @@ namespace Server.Guilds
|
|||
public abstract void Deserialize(IGenericReader reader);
|
||||
public abstract void OnDelete(Mobile mob);
|
||||
|
||||
public static BaseGuild FindByName(string name) =>
|
||||
World.Guilds.Values.FirstOrDefault(g => g.Name == name);
|
||||
public static BaseGuild FindByName(string name)
|
||||
{
|
||||
foreach (var g in World.Guilds.Values)
|
||||
{
|
||||
if (g.Name == name)
|
||||
{
|
||||
return g;
|
||||
}
|
||||
}
|
||||
|
||||
public static BaseGuild FindByAbbrev(string abbr) =>
|
||||
World.Guilds.Values.FirstOrDefault(g => g.Abbreviation == abbr);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static BaseGuild FindByAbbrev(string abbr)
|
||||
{
|
||||
foreach (var g in World.Guilds.Values)
|
||||
{
|
||||
if (g.Abbreviation == abbr)
|
||||
{
|
||||
return g;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static HashSet<BaseGuild> Search(string find)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Server.Network;
|
||||
using Server.Utilities;
|
||||
using QueuePool = Server.Utilities.RefPool<Server.Utilities.QueueRef<Server.Items.Container>>;
|
||||
|
|
@ -1457,7 +1456,11 @@ namespace Server.Items
|
|||
for (var j = 0; j < groups.Count; ++j)
|
||||
{
|
||||
var items = groups[j].ToArray();
|
||||
var total = items.Sum(t => t.Amount);
|
||||
var total = 0;
|
||||
foreach (var item in items)
|
||||
{
|
||||
total += item.Amount;
|
||||
}
|
||||
|
||||
if (total >= best)
|
||||
{
|
||||
|
|
@ -1531,9 +1534,27 @@ namespace Server.Items
|
|||
return best;
|
||||
}
|
||||
|
||||
public int GetAmount(Type type, bool recurse = true) => FindItemsByType(type, recurse).Sum(t => t.Amount);
|
||||
public int GetAmount(Type type, bool recurse = true)
|
||||
{
|
||||
var total = 0;
|
||||
foreach (var item in FindItemsByType(type, recurse))
|
||||
{
|
||||
total += item.Amount;
|
||||
}
|
||||
|
||||
public int GetAmount(Type[] types, bool recurse = true) => FindItemsByType(types, recurse).Sum(t => t.Amount);
|
||||
return total;
|
||||
}
|
||||
|
||||
public int GetAmount(Type[] types, bool recurse = true)
|
||||
{
|
||||
var total = 0;
|
||||
foreach (var item in FindItemsByType(types, recurse))
|
||||
{
|
||||
total += item.Amount;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
public Item[] FindItemsByType(Type type, bool recurse = true)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Server.ContextMenus;
|
||||
using Server.Items;
|
||||
|
|
@ -3619,28 +3618,27 @@ namespace Server
|
|||
|
||||
var eable = map.GetItemsInRange(p, 0);
|
||||
|
||||
var items = eable.Where(
|
||||
item =>
|
||||
var items = new List<Item>();
|
||||
foreach (var item in eable)
|
||||
{
|
||||
if (item is BaseMulti || item.ItemID > TileData.MaxItemValue)
|
||||
{
|
||||
if (item is BaseMulti || item.ItemID > TileData.MaxItemValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var id = item.ItemData;
|
||||
|
||||
if (id.Surface)
|
||||
{
|
||||
var top = item.Z + id.CalcHeight;
|
||||
if (top <= maxZ && top >= z)
|
||||
{
|
||||
z = top;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
continue;
|
||||
}
|
||||
).ToList();
|
||||
|
||||
var id = item.ItemData;
|
||||
|
||||
if (id.Surface)
|
||||
{
|
||||
var top = item.Z + id.CalcHeight;
|
||||
if (top <= maxZ && top >= z)
|
||||
{
|
||||
z = top;
|
||||
}
|
||||
}
|
||||
|
||||
items.Add(item);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime;
|
||||
using System.Runtime.InteropServices;
|
||||
|
|
@ -38,7 +37,9 @@ namespace Server
|
|||
private static bool m_Profiling;
|
||||
private static DateTime m_ProfileStart;
|
||||
private static TimeSpan m_ProfileTime;
|
||||
private static bool? m_IsRunningFromXUnit;
|
||||
#nullable enable
|
||||
private static bool? _isRunningFromXUnit;
|
||||
#nullable disable
|
||||
|
||||
private static long m_CycleIndex;
|
||||
private static readonly float[] m_CyclesPerSecond = new float[127]; // Divisible by long.MaxValue
|
||||
|
|
@ -58,11 +59,31 @@ namespace Server
|
|||
|
||||
private const string assembliesConfiguration = "Data/assemblies.json";
|
||||
|
||||
public static bool IsRunningFromXUnit =>
|
||||
m_IsRunningFromXUnit ??= AppDomain.CurrentDomain.GetAssemblies()
|
||||
.Any(
|
||||
a => a.FullName.InsensitiveStartsWith("XUNIT")
|
||||
);
|
||||
#nullable enable
|
||||
// TODO: Find a way to get rid of this
|
||||
public static bool IsRunningFromXUnit
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_isRunningFromXUnit != null)
|
||||
{
|
||||
return _isRunningFromXUnit.Value;
|
||||
}
|
||||
|
||||
foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
if (a.FullName.InsensitiveStartsWith("xunit"))
|
||||
{
|
||||
_isRunningFromXUnit = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
_isRunningFromXUnit = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#nullable disable
|
||||
|
||||
public static bool Profiling
|
||||
{
|
||||
|
|
@ -440,9 +461,11 @@ namespace Server
|
|||
var assemblyPath = Path.Join(BaseDirectory, assembliesConfiguration);
|
||||
|
||||
// Load UOContent.dll
|
||||
var assemblyFiles = JsonConfig.Deserialize<List<string>>(assemblyPath)
|
||||
.Select(t => Path.Join(BaseDirectory, "Assemblies", t))
|
||||
.ToArray();
|
||||
var assemblyFiles = JsonConfig.Deserialize<List<string>>(assemblyPath).ToArray();
|
||||
for (var i = 0; i < assemblyFiles.Length; i++)
|
||||
{
|
||||
assemblyFiles[i] = Path.Join(BaseDirectory, "Assemblies", assemblyFiles[i]);
|
||||
}
|
||||
|
||||
AssemblyHandler.LoadScripts(assemblyFiles);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.Serialization;
|
||||
using Microsoft.Toolkit.HighPerformance.Extensions;
|
||||
|
|
@ -6012,7 +6011,15 @@ namespace Server
|
|||
de.Responsible = list = new List<DamageEntry>();
|
||||
}
|
||||
|
||||
var resp = list.FirstOrDefault(check => check.Damager == master);
|
||||
DamageEntry resp = null;
|
||||
foreach (var check in list)
|
||||
{
|
||||
if (check.Damager == master)
|
||||
{
|
||||
resp = check;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (resp == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server
|
||||
|
|
@ -806,15 +805,9 @@ namespace Server
|
|||
[CommandProperty(AccessLevel.Counselor)]
|
||||
public Skill Throwing => this[SkillName.Throwing];
|
||||
|
||||
public IEnumerator<Skill> GetEnumerator()
|
||||
{
|
||||
return m_Skills.Where(s => s != null).GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return m_Skills.Where(s => s != null).GetEnumerator();
|
||||
}
|
||||
public Enumerator GetEnumerator() => new(this);
|
||||
IEnumerator<Skill> IEnumerable<Skill>.GetEnumerator() => new Enumerator(this);
|
||||
IEnumerator IEnumerable.GetEnumerator() => new Enumerator(this);
|
||||
|
||||
public override string ToString() => "...";
|
||||
|
||||
|
|
@ -902,5 +895,60 @@ namespace Server
|
|||
Owner.OnSkillInvalidated(skill);
|
||||
Owner.NetState.SendSkillChange(skill);
|
||||
}
|
||||
|
||||
public struct Enumerator : IEnumerator<Skill>
|
||||
{
|
||||
private readonly Skills _skills;
|
||||
private int _index;
|
||||
private Skill _current;
|
||||
|
||||
internal Enumerator(Skills skills)
|
||||
{
|
||||
_skills = skills;
|
||||
_index = 0;
|
||||
_current = default;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
Skills localList = _skills;
|
||||
|
||||
while ((uint)_index < (uint)localList.Length)
|
||||
{
|
||||
_current = localList.m_Skills[_index++];
|
||||
if (_current != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public Skill Current => _current!;
|
||||
|
||||
object IEnumerator.Current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_index == 0 || _index == _skills.Length + 1)
|
||||
{
|
||||
throw new InvalidOperationException(nameof(_index));
|
||||
}
|
||||
|
||||
return Current;
|
||||
}
|
||||
}
|
||||
|
||||
void IEnumerator.Reset()
|
||||
{
|
||||
_index = 0;
|
||||
_current = default;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
|
@ -224,16 +223,11 @@ namespace Server
|
|||
|
||||
var any = false;
|
||||
|
||||
m_TilesList.AddRange(
|
||||
eable.SelectMany(
|
||||
t =>
|
||||
{
|
||||
any = true;
|
||||
return t;
|
||||
}
|
||||
)
|
||||
.ToArray()
|
||||
);
|
||||
foreach (StaticTile[] multiTiles in eable)
|
||||
{
|
||||
any = true;
|
||||
m_TilesList.AddRange(multiTiles);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ using System.Buffers.Binary;
|
|||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
|
@ -742,7 +741,12 @@ namespace Server
|
|||
|
||||
var byteIndex = 0;
|
||||
|
||||
var length = mems.Sum(mem => mem.Length);
|
||||
var length = 0;
|
||||
for (var i = 0; i < mems.Length; i++)
|
||||
{
|
||||
length += mems[i].Length;
|
||||
}
|
||||
|
||||
var position = 0;
|
||||
var memIndex = 0;
|
||||
var span = mems[memIndex].Span;
|
||||
|
|
@ -1386,5 +1390,7 @@ namespace Server
|
|||
i = (i & 0x3333333333333333UL) + ((i >> 2) & 0x3333333333333333UL);
|
||||
return (int)(unchecked(((i + (i >> 4)) & 0xF0F0F0F0F0F0F0FUL) * 0x101010101010101UL) >> 56);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue