#if GRAPH_DESIGNER /// --------------------------------------------- /// Behavior Designer /// Copyright (c) Opsive. All Rights Reserved. /// https://www.opsive.com /// --------------------------------------------- namespace Opsive.BehaviorDesigner.Runtime.Tasks.Actions { using Opsive.BehaviorDesigner.Runtime.Components; using Opsive.GraphDesigner.Runtime; using Unity.Entities; using Unity.Burst; using UnityEngine; /// /// A node representation of the idle task. /// [NodeIcon("fc4d1b83384913b4abfbd8455db6df5b", "79a6985a753bb244fb5b32dc0f26addb")] [NodeDescription("Returns a TaskStatus of running. The task will only stop when interrupted or a conditional abort is triggered.")] public struct Idle : ILogicNode, ITaskComponentData, IAction { [Tooltip("The index of the node.")] [SerializeField] ushort m_Index; [Tooltip("The parent index of the node. ushort.MaxValue indicates no parent.")] [SerializeField] ushort m_ParentIndex; [Tooltip("The sibling index of the node. ushort.MaxValue indicates no sibling.")] [SerializeField] ushort m_SiblingIndex; public ushort Index { get => m_Index; set => m_Index = value; } public ushort ParentIndex { get => m_ParentIndex; set => m_ParentIndex = value; } public ushort SiblingIndex { get => m_SiblingIndex; set => m_SiblingIndex = value; } public ushort RuntimeIndex { get; set; } public ComponentType Tag { get => typeof(IdleTag); } public System.Type SystemType { get => typeof(IdleTaskSystem); } /// /// Adds the IBufferElementData to the entity. /// /// The world that the entity exists. /// The entity that the IBufferElementData should be assigned to. public void AddBufferElement(World world, Entity entity) { DynamicBuffer buffer; if (world.EntityManager.HasBuffer(entity)) { buffer = world.EntityManager.GetBuffer(entity); } else { buffer = world.EntityManager.AddBuffer(entity); } buffer.Add(new IdleComponent() { Index = RuntimeIndex }); } /// /// Clears the IBufferElementData from the entity. /// /// The world that the entity exists. /// The entity that the IBufferElementData should be cleared from. public void ClearBufferElement(World world, Entity entity) { DynamicBuffer buffer; if (world.EntityManager.HasBuffer(entity)) { buffer = world.EntityManager.GetBuffer(entity); buffer.Clear(); } } } /// /// The DOTS data structure for the Idle class. /// public struct IdleComponent : IBufferElementData { [Tooltip("The index of the node.")] public ushort Index; } /// /// A DOTS tag indicating when a Idle node is active. /// public struct IdleTag : IComponentData, IEnableableComponent { } /// /// Runs the Idle logic. /// [DisableAutoCreation] public partial struct IdleTaskSystem : ISystem { /// /// Creates the job. /// /// The current state of the system. [BurstCompile] private void OnUpdate(ref SystemState state) { var query = SystemAPI.QueryBuilder().WithAllRW().WithAll().Build(); state.Dependency = new IdleJob().ScheduleParallel(query, state.Dependency); } /// /// Job which executes the task logic. /// [BurstCompile] private partial struct IdleJob : IJobEntity { /// /// Executes the idle logic. /// An array of TaskComponents. /// An array of IdleComponents. [BurstCompile] public void Execute(ref DynamicBuffer taskComponents, ref DynamicBuffer idleComponents) { for (int i = 0; i < idleComponents.Length; ++i) { var idleComponent = idleComponents[i]; var taskComponent = taskComponents[idleComponent.Index]; if (taskComponent.Status == TaskStatus.Queued) { taskComponent.Status = TaskStatus.Running; taskComponents[idleComponent.Index] = taskComponent; } } } } } } #endif