using System; using System.Collections.Generic; using UnityEngine; namespace UnityAtoms.Extensions { // Create an Action delegates that takes 5 parameters. Not included in the standard lib. public delegate void Action(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5); public static class IListExtensions { public static void ForEach(this IList list, Action action, P1 param1) { for (int i = 0; list != null && i < list.Count; ++i) { action(list[i], param1); } } public static void ForEach(this IList list, Action action, P1 param1, P2 param2) { for (int i = 0; list != null && i < list.Count; ++i) { action(list[i], param1, param2); } } public static void ForEach(this IList list, Action action, P1 param1, P2 param2, P3 param3) { for (int i = 0; list != null && i < list.Count; ++i) { action(list[i], param1, param2, param3); } } public static void ForEach(this IList list, Func selector, Action action, P1 param1) { for (int i = 0; list != null && i < list.Count; ++i) { action(selector(list[i]), param1); } } public static void ForEach(this IList list, Func selector, Action action, P1 param1, P2 param2) { for (int i = 0; list != null && i < list.Count; ++i) { action(selector(list[i]), param1, param2); } } public static void ForEach(this IList list, Func selector, Action action, P1 param1, P2 param2, P3 param3) { for (int i = 0; list != null && i < list.Count; ++i) { action(selector(list[i]), param1, param2, param3); } } public static void ForEach(this IList list, Action action) { for (int i = 0; list != null && i < list.Count; ++i) { action(list[i], i); } } public static void ForEach(this IList list, Action action, P1 param1) { for (int i = 0; list != null && i < list.Count; ++i) { action(list[i], i, param1); } } public static void ForEach(this IList list, Action action, P1 param1, P2 param2) { for (int i = 0; list != null && i < list.Count; ++i) { action(list[i], i, param1, param2); } } public static void ForEach(this IList list, Action action, P1 param1, P2 param2, P3 param3) { for (int i = 0; list != null && i < list.Count; ++i) { action(list[i], i, param1, param2, param3); } } public static R Reduce(this IList list, Func reducer, Func getValue, R initialValue, Func skip = null) { R accumulator = initialValue; for (int i = 0; list != null && i < list.Count; ++i) { if (skip != null && skip(list[i])) { continue; } accumulator = reducer(accumulator, getValue(list[i])); } return accumulator; } public static R Reduce(this IList list, Func reducer, Func getValue, R initialValue, A reducerArg1, Func skip = null) { R accumulator = initialValue; for (int i = 0; list != null && i < list.Count; ++i) { if (skip != null && skip(list[i])) { continue; } accumulator = reducer(accumulator, getValue(list[i]), reducerArg1); } return accumulator; } public static float ReturnMaxFloat(float acc, float cur) { return Mathf.Max(acc, cur); } public static float ReturnMinFloat(float acc, float cur) { return Mathf.Min(acc, cur); } public static T First(this IList list, Func func) { for (int i = 0; list != null && i < list.Count; ++i) { if (func(list[i])) return list[i]; } return default(T); } public static T First(this IList list, Func func, P1 param1) { for (int i = 0; list != null && i < list.Count; ++i) { if (func(list[i], param1)) return list[i]; } return default(T); } public static bool Some(this IList list, Func func) { return !EqualityComparer.Default.Equals(list.First(func), default(T)); } public static bool Some(this IList list, Func func, P1 param1) { return !EqualityComparer.Default.Equals(list.First(func, param1), default(T)); } public static bool Every(this List list, Func func) { for (int i = 0; list != null && i < list.Count; ++i) { if (!func(list[i])) return false; } return true; } public static bool AddIfNotExists(this IList list, T item) { if (!list.Contains(item)) { list.Add(item); return true; } return false; } public static IList ChainableAdd(this IList list, T item) { list.Add(item); return list; } public static T GetOrInstantiate(this IList list, UnityEngine.Object prefab, Vector3 position, Quaternion quaternion, Func condition) where T : UnityEngine.Component { var component = list.First(condition); if (component != null) { component.transform.position = position; component.transform.rotation = quaternion; return component; } var newComponent = GameObject.Instantiate(prefab, position, quaternion) as T; list.Add(newComponent); return newComponent; } public static GameObject GetOrInstantiate(this IList list, UnityEngine.Object prefab, Vector3 position, Quaternion quaternion, Func condition) { var component = list.First(condition); if (component != null) { component.transform.position = position; component.transform.rotation = quaternion; return component; } var newGameObject = GameObject.Instantiate(prefab, position, quaternion) as GameObject; list.Add(newGameObject); return newGameObject; } public static T InstantiateAndAdd(this IList list, UnityEngine.Object prefab, Vector3 position, Quaternion quaternion) where T : UnityEngine.Component { var component = GameObject.Instantiate(prefab, position, quaternion) as T; list.Add(component); return component; } public static Func Pipe(this IList> list) { // OPEN POINT: Is it possible to make Reduce more flexible and use it here instead of this custom implementation return x => { T accumulator = x; for (int i = 0; list != null && i < list.Count; ++i) { accumulator = list[i](accumulator); } return accumulator; }; } public static Func Pipe(this IList list) where GF : GameFunction { // OPEN POINT: Is it possible to make Reduce more flexible and use it here instead of this custom implementation return x => { T accumulator = x; for (int i = 0; list != null && i < list.Count; ++i) { accumulator = list[i].Call(accumulator); } return accumulator; }; } } }