protected override void OnUpdate() { Entities.With(m_Group).ForEach((Entity e, ActionGraphAsset asset) => { ref ActionStateContainer container = ref ActionStateMapToAsset.Instance.GetContainer(asset.Asset); var index = container.AddChunk(); #if UNITY_EDITOR var eName = EntityManager.GetName(e); RunningGraphAsset.Instance.Add(asset.Asset, eName, container, index); #endif //var stateData = ActionStateData.Create(asset.Asset); //stateData.SetNodeCycle(asset.Asset.Entry, NodeCycle.Active); //TODO: 把入口入在启动逻辑中,而不是通过设置为active来处理 var entity = PostUpdateCommands.CreateEntity(); //var entity = EntityManager.CreateEntity(); var stateIndex = new ActionStateIndex(index, asset.Asset.Entry); container.SetNodeCycle(stateIndex, NodeCycle.Active); PostUpdateCommands.AddComponent(e, new ActionRunState() { InstanceID = asset.Asset.GetInstanceID(), ChunkIndex = index }); //PostUpdateCommands.AddComponent(e, new ActionGraphCreated() { }); });
protected override void OnUpdate() { var chunkArray = m_Group.CreateArchetypeChunkArray(Allocator.TempJob); var sComponentType = GetArchetypeChunkSharedComponentType <ActionGraphAsset>(); var stateComponentType = GetArchetypeChunkComponentType <ActionRunState>(true); var entityType = GetArchetypeChunkEntityType(); NativeArray <int> actives = new NativeArray <int>(1000, Allocator.Temp); NativeArray <int> wakingArray = new NativeArray <int>(1000, Allocator.Temp); var context = new Context(); for (int i = 0; i < chunkArray.Length; i++) { var asset = chunkArray[i].GetSharedComponentData(sComponentType, EntityManager); ref ActionStateContainer container = ref ActionStateMapToAsset.Instance.GetContainer(asset.Asset.GetInstanceID()); var runStateArray = chunkArray[i].GetNativeArray(stateComponentType); var entityArray = chunkArray[i].GetNativeArray(entityType); var nodeList = asset.Asset.RuntimeNodes; context.Graph = asset.Asset; context.EntityManager = EntityManager; context.PostUpdateCommands = PostUpdateCommands; context.StateData = container; for (int j = 0; j < runStateArray.Length; j++) { var chunkIndex = runStateArray[j].ChunkIndex; if (container.AnyActive(chunkIndex) == false && container.AnyWaking(chunkIndex) == false) { continue; } context.CurrentEntity = entityArray[j]; context.TargetEntity = entityArray[j]; //Profiler.BeginSample("lipi_C"); //TODO: 需要优化,节点越多性能越差 var(activeCount, wakingCount) = container.GetAllActiveOrWakingIndex(chunkIndex, ref actives, ref wakingArray); //Profiler.EndSample(); for (int k = 0; k < activeCount; k++) { context.Index = new ActionStateIndex(chunkIndex, actives[k]); var node = nodeList[actives[k]] as IStatusNode; //Profiler.BeginSample("lipi_V"); node.OnTick(ref context); //TODO:需要优化 //Profiler.EndSample(); } for (int k = 0; k < wakingCount; k++) { var wakingIndex = wakingArray[k]; context.Index = new ActionStateIndex(chunkIndex, wakingIndex); container.RemoveNodeCycle(context.Index, NodeCycle.Waking); ((ISleepable)nodeList[wakingIndex]).Wake(ref context); } } }
public void Add(GraphAsset graphAsset, string name, ActionStateContainer container, int index) { if (Map.TryGetValue(graphAsset, out var list) == false) { list = new InfoList(); Map.Add(graphAsset, list); } list.Version++; list.Infos.Add(new Info() { Name = (name == string.Empty)?"Entity":name, container = container, Index = index }); }
public static ActionStateContainer Create(GraphAsset graph, int chunkCapacity = 5) { var container = new ActionStateContainer(); // var builder = NativeStructMap.CreateBuilder(); var builder = NativeStaticMapHead.CreateBuilder(); var count = graph.RuntimeNodes.Length; container._containerInfo = new NativeArray <Info>(1, Allocator.Persistent); var info = new Info { NodeCount = count }; container._chunks = new NativeList <ActionStateChunk>(Allocator.Persistent); // container.Chunks.Add(new ActionStateChunk()); container._nodes = new NativeArray <ActionStateNode>(count * chunkCapacity, Allocator.Persistent); info.ChunkCount = 0; var capacity = 1000; var statePtr = (byte *)UnsafeUtility.Malloc(capacity, 4, Allocator.Temp); var offset = 0; for (var i = 0; i < count; i++) { var inode = graph.m_Nodes[i];// as INodeAsset; var node = new ActionStateNode() { Cycle = NodeCycle.Inactive, offset = offset }; container._nodes[i] = node; if (inode is IStatusNode nodeObject) { var t = nodeObject.NodeDataType(); var size = UnsafeUtility.SizeOf(t); if (offset + size > capacity) { capacity = capacity * 2; var ptr = (byte *)UnsafeUtility.Malloc(capacity, 4, Allocator.Temp); UnsafeUtility.MemCpy(ptr, statePtr, offset); UnsafeUtility.Free(ptr, Allocator.Temp); statePtr = ptr; } nodeObject.CreateNodeDataTo(statePtr + offset); offset += size; } if (inode is IAccessBlackboard accessBlackboard) { accessBlackboard.ToBuilder(builder); } } container._states = (byte *)UnsafeUtility.Malloc(offset * chunkCapacity, 4, Allocator.Persistent); UnsafeUtility.MemCpy(container._states, statePtr, offset); UnsafeUtility.Free(statePtr, Allocator.Temp); //var array = builder.ToNativeStructMapArray(chunkCapacity, Allocator.Persistent); var head = builder.ToHead(); var blackboard = NativeStaticMap.Create(ref head, chunkCapacity); //container.BlackboardArray = array; container._blackboard = blackboard; info.StatesSize = offset; info.NodeCount = count; info.ChunkCapacity = chunkCapacity; container._containerInfo[0] = info; return(container); }