using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using EcsRx.Blueprints; using EcsRx.Components; using EcsRx.Entities; using EcsRx.Groups; using UnityEngine; using UniRx; namespace EcsRx.Extensions { public static class IEntityExtensions { public static async Task WaitForPredicateMet(this IEntity entity, Predicate predicate) { while (!predicate(entity)) { await Task.Delay(1000); } return entity; } public static bool MatchesGroup(this IEntity entity, IGroup group) { return group.Matches(entity); } public static IEntity ApplyBlueprint(this IEntity entity, IBlueprint blueprint) { blueprint.Apply(entity); return entity; } public static IEntity ApplyBlueprints(this IEntity entity, params IBlueprint[] blueprints) { for (var i = 0; i < blueprints.Length; i++) { blueprints[i].Apply(entity); } return entity; } public static IEntity ApplyBlueprints(this IEntity entity, IEnumerable blueprints) { foreach (var blueprint in blueprints) { blueprint.Apply(entity); } return entity; } public static T AddComponentSafe(this IEntity entity, T component) where T : class, IComponent, new() { if (entity.HasComponent()) return component; entity.AddComponents(component); return component; } /// /// Adds a component to the entity based on its type with default setup /// /// The type of component to apply /// entity to use /// The component to add /// The created component public static T AddComponent(this IEntity entity, T component) where T : class, IComponent, new() { entity.AddComponents(component); return component; } /// /// Adds a component to the entity based on its type with default setup /// /// The type of component to apply /// entity to use /// The created component public static T AddComponent(this IEntity entity) where T : class, IComponent, new() { var component = new T(); entity.AddComponents(component); return component; } /// /// Removes a component from the entity by its type /// /// The type of entity to remove /// entity to use /// /// It is recommended if you can to batch component removals together /// public static void RemoveComponent(this IEntity entity) where T : class, IComponent { entity.RemoveComponents(typeof(T)); } /// /// Checks to see if the entity contains a given component /// /// Type of component to check for /// entity to use /// true if the component was found, false if it was not public static bool HasComponent(this IEntity entity) where T : IComponent { return entity.HasComponent(typeof(T)); } /// /// Removes many component instances from the entity /// /// entity to use /// The components to remove public static void RemoveComponents(this IEntity entity, params IComponent[] components) { var componentTypes = components.Select(x => x.GetType()).ToArray(); entity.RemoveComponents(componentTypes); } /// /// Gets a component from the entity based upon its type or null if one cannot be found /// /// The type of component to retrieve /// entity to use /// The component instance if found, or null if not public static T GetComponent(this IEntity entity) where T : class, IComponent { var componentType = typeof(T); return (T)entity.GetComponent(componentType); } /// /// Checks to see if the entity contains all of the given components /// /// The entity to action on /// Types of components to check for /// true if all the component was found, false if one or more is missing public static bool HasAllComponents(this IEntity entity, params Type[] componentTypes) { for (var index = componentTypes.Length - 1; index >= 0; index--) { if(!entity.HasComponent(componentTypes[index])) { return false; } } return true; } /// /// Checks to see if the entity contains all of the given components /// /// The entity to action on /// Type ids of components to check for /// true if all the component was found, false if one or more is missing public static bool HasAllComponents(this IEntity entity, params int[] componentTypeIds) { for (var index = componentTypeIds.Length - 1; index >= 0; index--) { if(!entity.HasComponent(componentTypeIds[index])) { return false; } } return true; } /// /// Checks to see if the entity contains any of the given components /// /// The entity to action on /// Types of the components to check for /// true if any components were found, false if no matching components were found public static bool HasAnyComponents(this IEntity entity, params Type[] componentTypes) { for (var index = componentTypes.Length - 1; index >= 0; index--) { if(entity.HasComponent(componentTypes[index])) { return true; } } return false; } /// /// Checks to see if the entity contains any of the given components /// /// The entity to action on /// Type ids of the components to check for /// true if any components were found, false if no matching components were found public static bool HasAnyComponents(this IEntity entity, params int[] componentTypeIds) { for (var index = componentTypeIds.Length - 1; index >= 0; index--) { if(entity.HasComponent(componentTypeIds[index])) { return true; } } return false; } public static void AddComponents(this IEntity entity, params IComponent[] components) { entity.AddComponents(components); } public static void RemoveComponents(this IEntity entity, params int[] componentsTypeIds) { entity.RemoveComponents(componentsTypeIds); } } }