diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5fb651f..b27cc4e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,8 +13,9 @@ Additions
Improvements
- Improved NinePatch memory performance
- Moved sound-related classes into Sound namespace
-- Added customizable overloads for Keybind, Combination and GenericInput ToString methods
+- Added customizable overloads for Keybind, Combination and GenericInput ToString methods
- Added ColorExtensions.Invert and made ColorHelper.Invert obsolete
+- Removed LINQ Any and All usage in various methods to improve memory usage
Fixes
- Set default values for InputHandler held and pressed keys to avoid an exception if buttons are held in the very first frame
@@ -23,6 +24,9 @@ Fixes
Additions
- Added a masking character to TextField to allow for password-style text fields
+Improvements
+- Removed LINQ Any and All usage in various methods to improve memory usage
+
Fixes
- Fixed a crash if a paragraph has a link formatting code, but no font
diff --git a/MLEM.Data/DynamicEnum.cs b/MLEM.Data/DynamicEnum.cs
index 6fbd7bb..2ad9811 100644
--- a/MLEM.Data/DynamicEnum.cs
+++ b/MLEM.Data/DynamicEnum.cs
@@ -118,8 +118,10 @@ namespace MLEM.Data {
if (dict.ContainsKey(value))
throw new ArgumentException($"Duplicate value {value}", nameof(value));
- if (dict.Values.Any(v => v.name == name))
- throw new ArgumentException($"Duplicate name {name}", nameof(name));
+ foreach (var v in dict.Values) {
+ if (v.name == name)
+ throw new ArgumentException($"Duplicate name {name}", nameof(name));
+ }
var ret = Construct(typeof(T), name, value);
dict.Add(value, ret);
diff --git a/MLEM.Extended/Tiled/TiledMapCollisions.cs b/MLEM.Extended/Tiled/TiledMapCollisions.cs
index 67b3ff4..59a349b 100644
--- a/MLEM.Extended/Tiled/TiledMapCollisions.cs
+++ b/MLEM.Extended/Tiled/TiledMapCollisions.cs
@@ -72,7 +72,15 @@ namespace MLEM.Extended.Tiled {
/// A function that determines if a certain info should be included or not
/// An enumerable of collision infos for that area
public IEnumerable GetCollidingTiles(RectangleF area, Func included = null) {
- var inclusionFunc = included ?? (tile => tile.Collisions.Any(c => c.Intersects(area)));
+ bool DefaultInclusion(TileCollisionInfo tile) {
+ foreach (var c in tile.Collisions) {
+ if (c.Intersects(area))
+ return true;
+ }
+ return false;
+ }
+
+ var inclusionFunc = included ?? DefaultInclusion;
var minX = Math.Max(0, area.Left.Floor());
var maxX = Math.Min(this.map.Width - 1, area.Right.Floor());
var minY = Math.Max(0, area.Top.Floor());
diff --git a/MLEM.Ui/Elements/TextField.cs b/MLEM.Ui/Elements/TextField.cs
index d9785f1..34af66a 100644
--- a/MLEM.Ui/Elements/TextField.cs
+++ b/MLEM.Ui/Elements/TextField.cs
@@ -24,19 +24,43 @@ namespace MLEM.Ui.Elements {
///
/// A that allows any visible character and spaces
///
- public static readonly Rule DefaultRule = (field, add) => !add.Any(char.IsControl);
+ public static readonly Rule DefaultRule = (field, add) => {
+ foreach (var c in add) {
+ if (char.IsControl(c))
+ return false;
+ }
+ return true;
+ };
///
/// A that only allows letters
///
- public static readonly Rule OnlyLetters = (field, add) => add.All(char.IsLetter);
+ public static readonly Rule OnlyLetters = (field, add) => {
+ foreach (var c in add) {
+ if (!char.IsLetter(c))
+ return false;
+ }
+ return true;
+ };
///
/// A that only allows numerals
///
- public static readonly Rule OnlyNumbers = (field, add) => add.All(char.IsNumber);
+ public static readonly Rule OnlyNumbers = (field, add) => {
+ foreach (var c in add) {
+ if (!char.IsNumber(c))
+ return false;
+ }
+ return true;
+ };
///
/// A that only allows letters and numerals
///
- public static readonly Rule LettersNumbers = (field, add) => add.All(c => char.IsLetter(c) || char.IsNumber(c));
+ public static readonly Rule LettersNumbers = (field, add) => {
+ foreach (var c in add) {
+ if (!char.IsLetter(c) || !char.IsNumber(c))
+ return false;
+ }
+ return true;
+ };
///
/// A that only allows characters not contained in
///
diff --git a/MLEM.Ui/Elements/Tooltip.cs b/MLEM.Ui/Elements/Tooltip.cs
index 0282368..1c5335e 100644
--- a/MLEM.Ui/Elements/Tooltip.cs
+++ b/MLEM.Ui/Elements/Tooltip.cs
@@ -129,8 +129,12 @@ namespace MLEM.Ui.Elements {
public void AddToElement(Element elementToHover) {
elementToHover.OnMouseEnter += element => {
// only display the tooltip if there is anything in it
- if (this.Children.Any(c => !c.IsHidden))
- this.Display(element.System, element.GetType().Name + "Tooltip");
+ foreach (var c in this.Children) {
+ if (!c.IsHidden) {
+ this.Display(element.System, element.GetType().Name + "Tooltip");
+ break;
+ }
+ }
};
elementToHover.OnMouseExit += element => this.Remove();
}
diff --git a/MLEM.Ui/UiSystem.cs b/MLEM.Ui/UiSystem.cs
index ff07df1..71a378f 100644
--- a/MLEM.Ui/UiSystem.cs
+++ b/MLEM.Ui/UiSystem.cs
@@ -465,8 +465,14 @@ namespace MLEM.Ui {
this.CanSelectContent = true;
};
this.OnElementRemoved += e => {
- if (e.CanBeSelected && !this.Element.GetChildren(regardGrandchildren: true).Any(c => c.CanBeSelected))
+ if (e.CanBeSelected) {
+ // check if removing this element removed all other selectable elements
+ foreach (var c in this.Element.GetChildren(regardGrandchildren: true)) {
+ if (c.CanBeSelected)
+ return;
+ }
this.CanSelectContent = false;
+ }
};
}
diff --git a/MLEM/Formatting/TokenizedString.cs b/MLEM/Formatting/TokenizedString.cs
index d02f1d9..9d60731 100644
--- a/MLEM/Formatting/TokenizedString.cs
+++ b/MLEM/Formatting/TokenizedString.cs
@@ -100,7 +100,13 @@ namespace MLEM.Formatting {
/// The scale that the string is drawn at
/// The token under the target position
public Token GetTokenUnderPos(Vector2 stringPos, Vector2 target, float scale) {
- return this.Tokens.FirstOrDefault(t => t.GetArea(stringPos, scale).Any(r => r.Contains(target)));
+ foreach (var token in this.Tokens) {
+ foreach (var rect in token.GetArea(stringPos, scale)) {
+ if (rect.Contains(target))
+ return token;
+ }
+ }
+ return null;
}
///
diff --git a/MLEM/Input/InputHandler.cs b/MLEM/Input/InputHandler.cs
index 3122fee..1f239ce 100644
--- a/MLEM/Input/InputHandler.cs
+++ b/MLEM/Input/InputHandler.cs
@@ -363,7 +363,11 @@ namespace MLEM.Input {
/// The modifier key
/// If the modifier key is down
public bool IsModifierKeyDown(ModifierKey modifier) {
- return modifier.GetKeys().Any(this.IsKeyDown);
+ foreach (var key in modifier.GetKeys()) {
+ if (this.IsKeyDown(key))
+ return true;
+ }
+ return false;
}
///
@@ -570,18 +574,30 @@ namespace MLEM.Input {
}
///
- public bool IsAnyDown(params GenericInput[] control) {
- return control.Any(c => this.IsDown(c));
+ public bool IsAnyDown(params GenericInput[] controls) {
+ foreach (var control in controls) {
+ if (this.IsDown(control))
+ return true;
+ }
+ return false;
}
///
- public bool IsAnyUp(params GenericInput[] control) {
- return control.Any(c => this.IsUp(c));
+ public bool IsAnyUp(params GenericInput[] controls) {
+ foreach (var control in controls) {
+ if (this.IsUp(control))
+ return true;
+ }
+ return false;
}
///
- public bool IsAnyPressed(params GenericInput[] control) {
- return control.Any(c => this.IsPressed(c));
+ public bool IsAnyPressed(params GenericInput[] controls) {
+ foreach (var control in controls) {
+ if (this.IsPressed(control))
+ return true;
+ }
+ return false;
}
///
diff --git a/MLEM/Input/Keybind.cs b/MLEM/Input/Keybind.cs
index 7d6d8a2..d1a61e9 100644
--- a/MLEM/Input/Keybind.cs
+++ b/MLEM/Input/Keybind.cs
@@ -89,7 +89,11 @@ namespace MLEM.Input {
/// The index of the gamepad to query, or -1 to query all gamepads
/// Whether this keybind is considered to be down
public bool IsDown(InputHandler handler, int gamepadIndex = -1) {
- return this.combinations.Any(c => c.IsDown(handler, gamepadIndex));
+ foreach (var combination in this.combinations) {
+ if (combination.IsDown(handler, gamepadIndex))
+ return true;
+ }
+ return false;
}
///
@@ -100,7 +104,11 @@ namespace MLEM.Input {
/// The index of the gamepad to query, or -1 to query all gamepads
/// Whether this keybind is considered to be pressed
public bool IsPressed(InputHandler handler, int gamepadIndex = -1) {
- return this.combinations.Any(c => c.IsPressed(handler, gamepadIndex));
+ foreach (var combination in this.combinations) {
+ if (combination.IsPressed(handler, gamepadIndex))
+ return true;
+ }
+ return false;
}
///
@@ -111,7 +119,11 @@ namespace MLEM.Input {
/// The index of the gamepad to query, or -1 to query all gamepads
/// Whether any of this keyboard's modifier keys are down
public bool IsModifierDown(InputHandler handler, int gamepadIndex = -1) {
- return this.combinations.Any(c => c.IsModifierDown(handler, gamepadIndex));
+ foreach (var combination in this.combinations) {
+ if (combination.IsModifierDown(handler, gamepadIndex))
+ return true;
+ }
+ return false;
}
///
@@ -198,7 +210,13 @@ namespace MLEM.Input {
/// The index of the gamepad to query, or -1 to query all gamepads
/// Whether this combination's modifiers are down
public bool IsModifierDown(InputHandler handler, int gamepadIndex = -1) {
- return this.Modifiers.Length <= 0 || this.Modifiers.Any(m => handler.IsDown(m, gamepadIndex));
+ if (this.Modifiers.Length <= 0)
+ return true;
+ foreach (var modifier in this.Modifiers) {
+ if (handler.IsDown(modifier, gamepadIndex))
+ return true;
+ }
+ return false;
}
///