// 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);
}
}
}
}
}