#if GRAPH_DESIGNER /// --------------------------------------------- /// Behavior Designer /// Copyright (c) Opsive. All Rights Reserved. /// https://www.opsive.com /// --------------------------------------------- namespace Opsive.BehaviorDesigner.Runtime.Systems { using Opsive.BehaviorDesigner.Runtime.Components; using Opsive.BehaviorDesigner.Runtime.Groups; using Unity.Burst; using Unity.Burst.Intrinsics; using Unity.Collections; using Unity.Entities; /// /// Resets the evaluation status. /// [DisableAutoCreation] [UpdateInGroup(typeof(BehaviorTreeSystemGroup), OrderLast = true)] [BurstCompile] public partial struct EvaluationCleanupSystem : ISystem { private EntityQuery m_EvaluateCleanupQuery; private ComponentTypeHandle m_EnabledComponentHandle; private ComponentTypeHandle m_EvaluateComponentHandle; private BufferTypeHandle m_BranchComponentHandle; /// /// Creates the required objects for use within the job system. /// /// The current SystemState. [BurstCompile] private void OnCreate(ref SystemState state) { m_EvaluateCleanupQuery = new EntityQueryBuilder(Allocator.Temp) .WithAll() .WithAllRW() .WithOptions(EntityQueryOptions.IgnoreComponentEnabledState) .Build(ref state); m_EnabledComponentHandle = state.GetComponentTypeHandle(); m_EvaluateComponentHandle = state.GetComponentTypeHandle(); m_BranchComponentHandle = state.GetBufferTypeHandle(); } /// /// Updates the data object values for use within the job system. /// /// The current SystemState. [BurstCompile] private void OnUpdate(ref SystemState state) { state.Dependency.Complete(); // Reset the evaluation status. m_EnabledComponentHandle.Update(ref state); m_EvaluateComponentHandle.Update(ref state); m_BranchComponentHandle.Update(ref state); var evaluationCleanupJob = new EvaluationCleanupJob() { EnabledComponentHandle = m_EnabledComponentHandle, EvaluateComponentHandle = m_EvaluateComponentHandle, BranchComponentHandle = m_BranchComponentHandle, }; state.Dependency = evaluationCleanupJob.ScheduleParallel(m_EvaluateCleanupQuery, state.Dependency); } /// /// Job that resets the EvaluationComponent component value. /// [BurstCompile(CompileSynchronously = true)] public struct EvaluationCleanupJob : IJobChunk { [UnityEngine.Tooltip("A reference to the Enabled Component Handle.")] public ComponentTypeHandle EnabledComponentHandle; [UnityEngine.Tooltip("A reference to the Evaluate Component Handle.")] public ComponentTypeHandle EvaluateComponentHandle; [UnityEngine.Tooltip("A reference to the Branch Component Handle.")] public BufferTypeHandle BranchComponentHandle; /// /// Resets the EvaluationComponent component value. /// /// Block of memory that contains the entity and components. /// The index of the chunk. /// Should the enabled mask be used? /// The bitwise enabled mask. [BurstCompile] public void Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask) { var branchAccessor = chunk.GetBufferAccessor(ref BranchComponentHandle); for (int i = 0; i < chunk.Count; i++) { // If the chunk is enabled then it should be evaluated. if (chunk.IsComponentEnabled(ref EnabledComponentHandle, i)) { chunk.SetComponentEnabled(ref EvaluateComponentHandle, i, true); } // Reset CanExecute for all branches so they can execute in the next tick. var branchComponents = branchAccessor[i]; for (int j = 0; j < branchComponents.Length; j++) { var branchComponent = branchComponents[j]; branchComponent.CanExecute = true; branchComponent.LastActiveIndex = ushort.MaxValue; branchComponents[j] = branchComponent; } } } } } /// /// Resets the InterruptedFlag enabled value. /// [DisableAutoCreation] [UpdateInGroup(typeof(BehaviorTreeSystemGroup), OrderLast = true)] [BurstCompile] public partial struct InterruptedCleanupSystem : ISystem { private EntityQuery m_InterruptedCleanupQuery; private ComponentTypeHandle m_InterruptedComponentHandle; /// /// Creates the required objects for use within the job system. /// /// The current SystemState. [BurstCompile] private void OnCreate(ref SystemState state) { m_InterruptedCleanupQuery = new EntityQueryBuilder(Allocator.Temp) .WithAll() .Build(ref state); m_InterruptedComponentHandle = state.GetComponentTypeHandle(); } /// /// Updates the data object values for use within the job system. /// /// The current SystemState. [BurstCompile] private void OnUpdate(ref SystemState state) { // Clean up the interrupted tag. m_InterruptedComponentHandle.Update(ref state); var interruptedJob = new InterruptedCleanupJob() { InterruptedComponentHandle = m_InterruptedComponentHandle, }; state.Dependency = interruptedJob.ScheduleParallel(m_InterruptedCleanupQuery, state.Dependency); } /// /// Job that resets the InterruptedFlag value. /// [BurstCompile(CompileSynchronously = true)] public partial struct InterruptedCleanupJob : IJobChunk { [UnityEngine.Tooltip("A reference to the Interrupted Component Handle.")] public ComponentTypeHandle InterruptedComponentHandle; /// /// Resets the InterruptedFlag value. /// /// The entity that is being acted upon. /// The index of the entity. [BurstCompile] public void Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask) { for (int i = 0; i < chunk.Count; i++) { // Only chunks with the tag enabled will be returned so there's no need to check if the tag is enabled. chunk.SetComponentEnabled(ref InterruptedComponentHandle, i, false); } } } } } #endif