// Copyright 2018 RED Software, LLC. All Rights Reserved. using System; using System.Collections.Generic; using System.Linq; namespace IgniteEngine { /// /// Class that extends the use of the List class. /// public static class ListExtensions { /// /// The object to lock for list access. /// private static readonly object lockObject = new object(); /// /// Adds an object to the list in a thread-safe, exception-safe /// manner. /// /// The source list. /// The value to add. public static void AddSafe(this List source, T value) { if (value == null) { return; } lock (lockObject) { if (!source.Contains(value)) { source.Add(value); } } } /// /// Copies the elements from the source list to the output list. /// /// The source list. /// The output list. public static void Copy(this List source, out List output) { lock (lockObject) { output = new List(source); } } /// /// Returns a new list filtered using the predicate provided. /// public static List Filter(this List source, Func predicate) { lock (lockObject) { return new List(source.Where(predicate)); } } /// /// Performs an action on the filtered list of items in the list. /// /// The source list. /// The filter specifications. /// The action to perform on the filtered items. public static void FilteredAction(this List source, Func predicate, Action action) { lock (lockObject) { source.Filter(predicate).ForEach(action); } } /// /// Returns the first matching element in the list. /// /// The source list. /// The filter specifications. public static T First(this List source, Func predicate) { lock (lockObject) { var list = source.Filter(predicate); return list.Count <= 0 ? default(T) : list[0]; } } /// /// Runs a for loop on list in a thread-safe manner. /// /// The source list. /// The action to perform on the item. public static void For(this List source, Action action) { lock (lockObject) { for (var i = 0; i < source.Count; i++) { action(source[i]); } } } /// /// Runs a for loop on list, backwards, in a thread-safe manner. /// /// The source list. /// The action to perform on the item. public static void ForBackwards(this List source, Action action) { lock (lockObject) { for (var i = source.Count - 1; i >= 0; i--) { action(source[i]); } } } /// /// Removes an object from a list in a thread-safe, exception-safe /// manner. /// /// The source list. /// The value to remove. public static void RemoveSafe(this List source, T value) { if (value == null) { return; } lock (lockObject) { if (source.Contains(value)) { source.Remove(value); } } } } }