public void NativeMultiHashMap_CountValuesForKey() { var hashMap = new NativeMultiHashMap <int, int> (1, Allocator.Temp); hashMap.Add(5, 7); hashMap.Add(6, 9); hashMap.Add(6, 10); Assert.AreEqual(1, hashMap.CountValuesForKey(5)); Assert.AreEqual(2, hashMap.CountValuesForKey(6)); Assert.AreEqual(0, hashMap.CountValuesForKey(7)); hashMap.Dispose(); }
/// <summary> /// Update the store with the recorded BlobAsset/UnityObject associations. /// </summary> /// <remarks> /// User don't have to call this method because <see cref="Dispose"/> will do it. /// This method can be called multiple times, on the first one will matter. /// </remarks> public void UpdateBlobStore() { var keys = m_BlobPerUnityObject.GetUniqueKeyArray(Allocator.Temp); using (keys.Item1) { for (var k = 0; k < keys.Item2; ++k) { var key = keys.Item1[k]; var valueCount = m_BlobPerUnityObject.CountValuesForKey(key); var valueArray = new NativeArray <Hash128>(valueCount, Allocator.Temp); var i = 0; if (m_BlobPerUnityObject.TryGetFirstValue(key, out var value, out var iterator)) { do { valueArray[i++] = value; }while (m_BlobPerUnityObject.TryGetNextValue(out value, ref iterator)); valueArray.Sort(); } m_BlobAssetStore.UpdateBlobAssetForUnityObject <TB>(key, valueArray); valueArray.Dispose(); } } m_BlobPerUnityObject.Clear(); }
public bool HasVehicleInSegment( NativeMultiHashMap <Entity, VehicleSegmentData> vehicleSegmentMap, Entity segmentEntity ) { return(vehicleSegmentMap.CountValuesForKey(segmentEntity) > 0); }
public static NativeArray <CollisionTriggerData>?CollectCollisionTriggerData(int frame, ref NativeMultiHashMap <Entity, CollisionTriggerData> nativeMultiHashMap, Entity e) { var count = nativeMultiHashMap.CountValuesForKey(e); NativeArray <CollisionTriggerData> collisions = new NativeArray <CollisionTriggerData>(count, Allocator.Temp); int idx = 0; if (nativeMultiHashMap.TryGetFirstValue(e, out var collInfo1, out var it)) { do { if (collInfo1.Frame < frame) { collInfo1.State = CollisionState.Exit; nativeMultiHashMap.Remove(it); } else if (collInfo1.Frame == frame) { // MBRIAU: What are we trying to clean up here? collInfo1.State = collInfo1.State == CollisionState.Stay ? CollisionState.Stay : CollisionState.Enter; } collisions[idx++] = collInfo1; }while (nativeMultiHashMap.TryGetNextValue(out collInfo1, ref it)); } return(collisions); }
private static int GetSubSceneCount(Scene gameObjectScene) { if (!SubSceneLookup.IsCreated) { return(0); } return(SubSceneLookup.CountValuesForKey(gameObjectScene.handle)); }
internal void CreateCollider(Entity rigidbodyEntity) { var colliderCount = RigidbodyToColliderMapping.CountValuesForKey(rigidbodyEntity); if (colliderCount == 0) { return; } // Single collider doesn't require a compound collider. if (colliderCount == 1) { var foundColliderBlob = RigidbodyToColliderMapping.TryGetFirstValue(rigidbodyEntity, out BlobAssetReference <Collider> colliderBlob, out NativeMultiHashMapIterator <Entity> ignore); SafetyChecks.IsTrue(foundColliderBlob); // Add the single collider to the rigidbody entity. DstEntityManager.AddComponentData(rigidbodyEntity, new PhysicsColliderBlob { Collider = colliderBlob }); return; } // Multiple colliders required a compound collider. var childrenArray = new NativeArray <PhysicsCompoundCollider.ColliderBlobInstance>(colliderCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory); var childIndex = 0; foreach (var colliderBlob in RigidbodyToColliderMapping.GetValuesForKey(rigidbodyEntity)) { childrenArray[childIndex++] = new PhysicsCompoundCollider.ColliderBlobInstance { Collider = colliderBlob, // NOTE: Right now the relative pose of the collider with respect to the rigidbody is baked into the shape. // Later, we'll want to remove that and only have its offset (if any) baked into it and use this transform instead. CompoundFromChild = PhysicsTransform.Identity }; } // Create the compound collider. DstEntityManager.AddComponentData(rigidbodyEntity, new PhysicsColliderBlob { Collider = PhysicsCompoundCollider.Create(childrenArray) }); // We've finished with the children blobs and array. for (var i = 0; i < colliderCount; ++i) { childrenArray[i].Collider.Dispose(); } childrenArray.Dispose(); }
public void Execute() { for (int i = 0; i < meshSlices.Length; i++) { var meshData = meshes[i]; var vertexData = meshData.GetVertexData <TVertex>(); vertexData.CopyFrom(vertices.GetSubArray(meshSlices[i].startVertex, meshSlices[i].vertexLength)); var indexData = meshData.GetIndexData <int>(); indexData.CopyFrom(indices.GetSubArray(meshSlices[i].startIndex, meshSlices[i].indexLength)); meshData.subMeshCount = subMeshes.CountValuesForKey(i) + 1; foreach (var subMesh in subMeshes.GetValuesForKey(i)) { meshes[i].SetSubMesh(subMesh.index, new SubMeshDescriptor(subMesh.start, subMesh.length, subMesh.topology)); } } }
// パーティクル連動頂点ごと public void Execute(int index) { int vindex = vertexToParticleList[index]; if (vindex < 0) { return; } int pindex; //#if !UNITY_2018_4 #if false // v1.5.2 // こちらのクォータニオン補間の方が安全 int cnt = vertexToParticleMap.CountValuesForKey(vindex); if (cnt > 0) { if (vertexToParticleMap.TryGetFirstValue(vindex, out pindex, out iterator)) { float3 pos = particlePosList[pindex]; quaternion rot = particleRotList[pindex]; var flag = particleFlagList[pindex]; int fixcnt = flag.IsKinematic() ? 1 : 0; float ratio = 1.0f / cnt; while (vertexToParticleMap.TryGetNextValue(out pindex, ref iterator)) { float3 ppos = particlePosList[pindex]; quaternion prot = particleRotList[pindex]; flag = particleFlagList[pindex]; pos += ppos; rot = math.slerp(rot, prot, ratio); fixcnt += flag.IsKinematic() ? 1 : 0; } pos = pos / cnt; virtualPosList[vindex] = pos; virtualRotList[vindex] = rot; // 仮想メッシュの法線/接線計算フラグ //virtualVertexFlagList[vindex] = 1; byte vflag = (byte)(PhysicsManagerMeshData.VirtualVertexFlag_Use | (fixcnt > 0 ? PhysicsManagerMeshData.VirtualVertexFlag_Fix : 0x0)); //virtualVertexFlagList[vindex] = (byte)(fixcnt == cnt ? 0 : 1); virtualVertexFlagList[vindex] = vflag; } } #else if (vertexToParticleMap.TryGetFirstValue(vindex, out pindex, out iterator)) { float3 pos = 0; float3 nor = 0; float3 tan = 0; int cnt = 0; do { // particle var flag = particleFlagList[pindex]; // 固定パーティクルかつ固定は回転しない設定ならば打ち切る(v1.5.2) if (flag.IsKinematic()) { var team = teamDataList[teamIdList[pindex]]; if (team.IsFlag(PhysicsManagerTeamData.Flag_FixedNonRotation)) { // 1つでも当てはまれば打ち切る return; } } float3 ppos = particlePosList[pindex]; quaternion prot = particleRotList[pindex]; pos += ppos; nor += math.mul(prot, new float3(0, 0, 1)); tan += math.mul(prot, new float3(0, 1, 0)); cnt++; }while (vertexToParticleMap.TryGetNextValue(out pindex, ref iterator)); if (cnt > 0) { pos = pos / cnt; nor = math.normalize(nor); tan = math.normalize(tan); virtualPosList[vindex] = pos; virtualRotList[vindex] = quaternion.LookRotation(nor, tan); // 仮想メッシュの法線/接線計算フラグ virtualVertexFlagList[vindex] = PhysicsManagerMeshData.VirtualVertexFlag_Use; } } #endif }
internal void UpdateBlobAssetForGameObject <TB>(int ownerId, NativeArray <Hash128> newBlobHashes) where TB : struct { var leftLength = newBlobHashes.Length; var toInc = new NativeArray <Hash128>(leftLength, Allocator.Temp); var toDec = new NativeArray <Hash128>(m_HashByOwner.CountValuesForKey(ownerId), Allocator.Temp); var curLeftIndex = 0; var curIncIndex = 0; var curDecIndex = 0; var leftRes = curLeftIndex < leftLength; var rightRes = m_HashByOwner.TryGetFirstValue(ownerId, out var rightHash, out var it); var maxHash = new Hash128(UInt32.MaxValue, UInt32.MaxValue, UInt32.MaxValue, UInt32.MaxValue); // We will parse newBlobHashes, considered the left part and the store hashes for this ownerId, considered the right part // in order to build a list of BlobAssets to increment (the ones only present in left part) and the ones to decrement // (only present in the right part). If a hash is present on both side, we do not change its RefCounter do { var leftHash = leftRes ? newBlobHashes[curLeftIndex] : maxHash; rightHash = rightRes ? rightHash : maxHash; // Both side equal? We are synchronized, step next for both sides if (rightHash == leftHash) { leftRes = ++curLeftIndex < leftLength; rightRes = m_HashByOwner.TryGetNextValue(out rightHash, ref it); continue; } // More items on the left, add them to the "toAdd" list if (leftHash < rightHash) { do { // Get left hash leftHash = newBlobHashes[curLeftIndex++]; // Add to "toInc" toInc[curIncIndex++] = leftHash; // Check if there's more left item leftRes = curLeftIndex < leftLength; } while (leftRes && (leftHash < rightHash)); } // More items on the right, add them to the "toRemove" list else { do { // Add to "toDec" toDec[curDecIndex++] = rightHash; // Get next right item rightRes = m_HashByOwner.TryGetNextValue(out rightHash, ref it); } while (rightRes && leftHash > rightHash); } } while (leftRes || rightRes); // Increment each hash in "toInc" if they exist, add them to the RefCounter hash if they are new for (int i = 0; i < curIncIndex; i++) { var hash = toInc[i]; if (m_RefCounterPerBlobHash.TryGetValue(hash, out var counter)) { m_RefCounterPerBlobHash[hash] = counter + 1; } else { m_RefCounterPerBlobHash.Add(hash, 1); } } // Decrement each hash in "toDec", remove the BlobAsset if it reaches 0 for (int i = 0; i < curDecIndex; i++) { // Decrement the hash of the previously assigned Blob Asset var hash = toDec[i]; var oldHashCount = --m_RefCounterPerBlobHash[hash]; // If it reaches 0, we dispose the Blob Asset and remove the counter if (oldHashCount == 0) { Remove <TB>(hash, true); m_RefCounterPerBlobHash.Remove(hash); } } // Clear the former list of BlobAsset hashes and replace by the new one m_HashByOwner.Remove(ownerId); for (int i = 0; i < leftLength; i++) { m_HashByOwner.Add(ownerId, newBlobHashes[i]); } }
protected override unsafe void OnUpdate() { var preSpawnsAlreadyProcessed = EntityManager.CreateEntityQuery(ComponentType.ReadOnly <PreSpawnsInitialized>()) .CalculateEntityCount(); if (preSpawnsAlreadyProcessed > 0) { // Check if an uninitialized scene has appeared with no ghosts present inside, then just mark it as initialized and continue var prespawns = m_Prespawns.ToEntityArray(Allocator.TempJob); var newScenes = m_UninitializedScenes.ToEntityArray(Allocator.TempJob); for (int j = 0; j < newScenes.Length; ++j) { for (int i = 0; i < prespawns.Length; ++i) { var scenes = EntityManager.GetSharedComponentData <SceneSection>(prespawns[i]); var sceneSystem = World.GetExistingSystem <SceneSystem>(); var sceneEntity = sceneSystem.GetSceneEntity(scenes.SceneGUID); if (sceneEntity == newScenes[j]) { UnityEngine.Debug.LogError("[" + World.Name + "] Prespawned ghosts have already been initialized, this needs to happen for all subscenes at the same time."); return; } } EntityManager.AddComponent <PreSpawnsInitialized>(newScenes[j]); } newScenes.Dispose(); prespawns.Dispose(); return; } // Handle the chunk for an entity type, then handle each entity in the chunk (prespawned entities) var prespawnChunk = m_Prespawns.CreateArchetypeChunkArray(Allocator.TempJob); var entityType = GetEntityTypeHandle(); var preSpawnedIds = GetComponentDataFromEntity <PreSpawnedGhostId>(); var subsceneMap = new NativeMultiHashMap <ulong, Entity>(32, Allocator.Temp); var subscenePadding = new NativeHashMap <ulong, int>(32, Allocator.Temp); var ghostComponents = GetComponentDataFromEntity <GhostComponent>(); // Put all known subscene hashes tracked by the prespawned ghosts into a map for sorting for (int i = 0; i < prespawnChunk.Length; ++i) { var chunk = prespawnChunk[i]; var entities = chunk.GetNativeArray(entityType); for (int j = 0; j < entities.Length; ++j) { var entity = entities[j]; var subsceneHash = EntityManager.GetSharedComponentData <SubSceneGhostComponentHash>(entity).Value; subsceneMap.Add(subsceneHash, entity); } } var subsceneArray = subsceneMap.GetUniqueKeyArray(Allocator.Temp); // Figure out scene id padding or how many IDs were used by the previous scenes in the sorted list, continue // where it left off so each ghost in a scene starts of at the ID+1 of last ghost in the previous scene var scenePadding = 0; for (int i = 0; i < subsceneArray.Item2; ++i) { subscenePadding.Add(subsceneArray.Item1[i], scenePadding); scenePadding += subsceneMap.CountValuesForKey(subsceneArray.Item1[i]); } var PostUpdateCommands = new EntityCommandBuffer(Allocator.Temp); var serverSystems = World.GetExistingSystem <ServerSimulationSystemGroup>(); var ghostTypes = GetComponentDataFromEntity <GhostTypeComponent>(); var ghostPrefabBufferFromEntity = GetBufferFromEntity <GhostPrefabBuffer>(true); var prefabEntity = GetSingletonEntity <GhostPrefabCollectionComponent>(); var ghostReceiveSystem = World.GetExistingSystem <GhostReceiveSystem>(); var ghostSendSystem = World.GetExistingSystem <GhostSendSystem>(); var ghostCollectionSystem = World.GetExistingSystem <GhostCollectionSystem>(); DynamicBuffer <GhostPrefabBuffer> prefabList = ghostPrefabBufferFromEntity[prefabEntity]; int highestPrespawnId = -1; var spawnedGhosts = new NativeList <SpawnedGhostMapping>(1024, Allocator.Temp); for (int i = 0; i < prespawnChunk.Length; ++i) { var chunk = prespawnChunk[i]; var entities = chunk.GetNativeArray(entityType); for (int j = 0; j < entities.Length; ++j) { var entity = entities[j]; var ghostTypeComponent = ghostTypes[entity]; int ghostType; for (ghostType = 0; ghostType < prefabList.Length; ++ghostType) { if (ghostTypes[prefabList[ghostType].Value] == ghostTypeComponent) { break; } } if (ghostType >= prefabList.Length) { UnityEngine.Debug.LogError("Failed to look up ghost type for entity"); return; } // Check if this entity has already been handled if (ghostComponents[entity].ghostId != 0) { UnityEngine.Debug.LogWarning(entity + " already has ghostId=" + ghostComponents[entity].ghostId + " prespawn=" + preSpawnedIds[entity].Value); continue; } // Modfy the entity to its proper version if (EntityManager.HasComponent <GhostPrefabMetaDataComponent>(prefabList[ghostType].Value)) { ref var ghostMetaData = ref EntityManager.GetComponentData <GhostPrefabMetaDataComponent>(prefabList[ghostType].Value).Value.Value; if (serverSystems != null) { for (int rm = 0; rm < ghostMetaData.RemoveOnServer.Length; ++rm) { var rmCompType = ComponentType.ReadWrite(TypeManager.GetTypeIndexFromStableTypeHash(ghostMetaData.RemoveOnServer[rm])); PostUpdateCommands.RemoveComponent(entity, rmCompType); } } else { for (int rm = 0; rm < ghostMetaData.RemoveOnClient.Length; ++rm) { var rmCompType = ComponentType.ReadWrite(TypeManager.GetTypeIndexFromStableTypeHash(ghostMetaData.RemoveOnClient[rm])); PostUpdateCommands.RemoveComponent(entity, rmCompType); } // FIXME: should disable instead of removing once we have a way of doing that without structural changes if (ghostMetaData.DefaultMode == GhostPrefabMetaData.GhostMode.Predicted) { for (int rm = 0; rm < ghostMetaData.DisableOnPredictedClient.Length; ++rm) { var rmCompType = ComponentType.ReadWrite(TypeManager.GetTypeIndexFromStableTypeHash(ghostMetaData.DisableOnPredictedClient[rm])); PostUpdateCommands.RemoveComponent(entity, rmCompType); } } else if (ghostMetaData.DefaultMode == GhostPrefabMetaData.GhostMode.Interpolated) { for (int rm = 0; rm < ghostMetaData.DisableOnInterpolatedClient.Length; ++rm) { var rmCompType = ComponentType.ReadWrite(TypeManager.GetTypeIndexFromStableTypeHash(ghostMetaData.DisableOnInterpolatedClient[rm])); PostUpdateCommands.RemoveComponent(entity, rmCompType); } } } } var subsceneHash = EntityManager.GetSharedComponentData <SubSceneGhostComponentHash>(entity).Value; var newId = preSpawnedIds[entity].Value + subscenePadding[subsceneHash]; if (newId > highestPrespawnId) { highestPrespawnId = newId; } // If on a server we need to allocate the ghost ID for the pre-spawned entity so runtime spawns // will happen from the right start index if (serverSystems != null) { spawnedGhosts.Add(new SpawnedGhostMapping { ghost = new SpawnedGhost { ghostId = newId, spawnTick = 0 }, entity = entity }); var ghostSystemStateComponent = new GhostSystemStateComponent { ghostId = newId, despawnTick = 0, spawnTick = 0 }; PostUpdateCommands.AddComponent(entity, ghostSystemStateComponent); } else if (ghostReceiveSystem != null) { var snapshotSize = ghostCollectionSystem.m_GhostTypeCollection[ghostType].SnapshotSize; spawnedGhosts.Add(new SpawnedGhostMapping { ghost = new SpawnedGhost { ghostId = newId, spawnTick = 0 }, entity = entity }); var newBuffer = PostUpdateCommands.SetBuffer <SnapshotDataBuffer>(entity); newBuffer.ResizeUninitialized(snapshotSize * GhostSystemConstants.SnapshotHistorySize); UnsafeUtility.MemClear(newBuffer.GetUnsafePtr(), snapshotSize * GhostSystemConstants.SnapshotHistorySize); PostUpdateCommands.SetComponent(entity, new SnapshotData { SnapshotSize = snapshotSize, LatestIndex = 0 }); } // Pre-spawned uses spawnTick = 0, if there is a reference to a ghost and it has spawnTick 0 the ref is always resolved // This works because there despawns are high priority and we never create pre-spawned ghosts after connection var ghostComponent = new GhostComponent { ghostId = newId, ghostType = ghostType, spawnTick = 0 }; PostUpdateCommands.SetComponent(entity, ghostComponent); // Mark scene as processed, as whole scene will have been loaded when this entity appeared var sceneSection = EntityManager.GetSharedComponentData <SceneSection>(entity); var sceneSystem = World.GetExistingSystem <SceneSystem>(); var sceneEntity = sceneSystem.GetSceneEntity(sceneSection.SceneGUID); PostUpdateCommands.AddComponent <PreSpawnsInitialized>(sceneEntity); } }
protected override unsafe void OnUpdate() { var preSpawnsAlreadyProcessed = EntityManager.CreateEntityQuery(ComponentType.ReadOnly <PreSpawnsInitialized>()) .CalculateEntityCount(); if (preSpawnsAlreadyProcessed > 0) { // Check if an uninitialized scene has appeared with no ghosts present inside, then just mark it as initialized and continue var prespawns = m_Prespawns.ToEntityArray(Allocator.TempJob); var newScenes = m_UninitializedScenes.ToEntityArray(Allocator.TempJob); for (int j = 0; j < newScenes.Length; ++j) { for (int i = 0; i < prespawns.Length; ++i) { var scenes = EntityManager.GetSharedComponentData <SceneSection>(prespawns[i]); var sceneSystem = World.GetExistingSystem <SceneSystem>(); var sceneEntity = sceneSystem.GetSceneEntity(scenes.SceneGUID); if (sceneEntity == newScenes[j]) { UnityEngine.Debug.LogError("[" + World.Name + "] Prespawned ghosts have already been initialized, this needs to happen for all subscenes at the same time."); return; } } EntityManager.AddComponent <PreSpawnsInitialized>(newScenes[j]); } newScenes.Dispose(); prespawns.Dispose(); return; } // Handle the chunk for an entity type, then handle each entity in the chunk (prespawned entities) var prespawnChunk = m_Prespawns.CreateArchetypeChunkArray(Allocator.TempJob); var entityType = GetEntityTypeHandle(); var preSpawnedIds = GetComponentDataFromEntity <PreSpawnedGhostId>(); var subsceneMap = new NativeMultiHashMap <ulong, Entity>(32, Allocator.Temp); var subscenePadding = new NativeHashMap <ulong, int>(32, Allocator.Temp); var ghostComponents = GetComponentDataFromEntity <GhostComponent>(); // Put all known subscene hashes tracked by the prespawned ghosts into a map for sorting for (int i = 0; i < prespawnChunk.Length; ++i) { var chunk = prespawnChunk[i]; var entities = chunk.GetNativeArray(entityType); for (int j = 0; j < entities.Length; ++j) { var entity = entities[j]; var subsceneHash = EntityManager.GetSharedComponentData <SubSceneGhostComponentHash>(entity).Value; subsceneMap.Add(subsceneHash, entity); } } var subsceneArray = subsceneMap.GetUniqueKeyArray(Allocator.Temp); // Figure out scene id padding or how many IDs were used by the previous scenes in the sorted list, continue // where it left off so each ghost in a scene starts of at the ID+1 of last ghost in the previous scene var scenePadding = 0; for (int i = 0; i < subsceneArray.Item2; ++i) { subscenePadding.Add(subsceneArray.Item1[i], scenePadding); scenePadding += subsceneMap.CountValuesForKey(subsceneArray.Item1[i]); } var PostUpdateCommands = new EntityCommandBuffer(Allocator.Temp); var serverSystems = World.GetExistingSystem <ServerSimulationSystemGroup>(); var ghostTypes = GetComponentDataFromEntity <GhostTypeComponent>(); var ghostReceiveSystem = World.GetExistingSystem <GhostReceiveSystem>(); var ghostSendSystem = World.GetExistingSystem <GhostSendSystem>(); var ghostTypeCollection = EntityManager.GetBuffer <GhostCollectionPrefabSerializer>(GetSingletonEntity <GhostCollection>()); int highestPrespawnId = -1; var spawnedGhosts = new NativeList <SpawnedGhostMapping>(1024, Allocator.Temp); // Create a lookup from ghost type component to prefab entity, used to figure out how to strip components on the client var prefabFromType = new NativeHashMap <GhostTypeComponent, Entity>(1024, Allocator.Temp); Entities.WithNone <GhostPrefabRuntimeStrip>().WithAll <Prefab>().ForEach((Entity ent, in GhostTypeComponent ghostType) => { prefabFromType.TryAdd(ghostType, ent); }).Run(); for (int i = 0; i < prespawnChunk.Length; ++i) { var chunk = prespawnChunk[i]; var entities = chunk.GetNativeArray(entityType); for (int j = 0; j < entities.Length; ++j) { var entity = entities[j]; var ghostTypeComponent = ghostTypes[entity]; if (!prefabFromType.TryGetValue(ghostTypeComponent, out var ghostPrefabEntity)) { UnityEngine.Debug.LogError("Failed to look up ghost type for entity"); return; } // Check if this entity has already been handled if (ghostComponents[entity].ghostId != 0) { UnityEngine.Debug.LogWarning(entity + " already has ghostId=" + ghostComponents[entity].ghostId + " prespawn=" + preSpawnedIds[entity].Value); continue; } // Modfy the entity to its proper version if (EntityManager.HasComponent <GhostPrefabMetaDataComponent>(ghostPrefabEntity)) { ref var ghostMetaData = ref EntityManager.GetComponentData <GhostPrefabMetaDataComponent>(ghostPrefabEntity).Value.Value; var linkedEntityGroup = EntityManager.GetBuffer <LinkedEntityGroup>(entity); if (serverSystems != null) { for (int rm = 0; rm < ghostMetaData.RemoveOnServer.Length; ++rm) { var childIndexCompHashPair = ghostMetaData.RemoveOnServer[rm]; var rmCompType = ComponentType.ReadWrite(TypeManager.GetTypeIndexFromStableTypeHash(childIndexCompHashPair.StableHash)); PostUpdateCommands.RemoveComponent(linkedEntityGroup[childIndexCompHashPair.EntityIndex].Value, rmCompType); } } else { for (int rm = 0; rm < ghostMetaData.RemoveOnClient.Length; ++rm) { var childIndexCompHashPair = ghostMetaData.RemoveOnClient[rm]; var rmCompType = ComponentType.ReadWrite(TypeManager.GetTypeIndexFromStableTypeHash(childIndexCompHashPair.StableHash)); PostUpdateCommands.RemoveComponent(linkedEntityGroup[childIndexCompHashPair.EntityIndex].Value, rmCompType); } // FIXME: should disable instead of removing once we have a way of doing that without structural changes if (ghostMetaData.DefaultMode == GhostPrefabMetaData.GhostMode.Predicted) { for (int rm = 0; rm < ghostMetaData.DisableOnPredictedClient.Length; ++rm) { var childIndexCompHashPair = ghostMetaData.DisableOnPredictedClient[rm]; var rmCompType = ComponentType.ReadWrite(TypeManager.GetTypeIndexFromStableTypeHash(childIndexCompHashPair.StableHash)); PostUpdateCommands.RemoveComponent(linkedEntityGroup[childIndexCompHashPair.EntityIndex].Value, rmCompType); } } else if (ghostMetaData.DefaultMode == GhostPrefabMetaData.GhostMode.Interpolated) { for (int rm = 0; rm < ghostMetaData.DisableOnInterpolatedClient.Length; ++rm) { var childIndexCompHashPair = ghostMetaData.DisableOnInterpolatedClient[rm]; var rmCompType = ComponentType.ReadWrite(TypeManager.GetTypeIndexFromStableTypeHash(childIndexCompHashPair.StableHash)); PostUpdateCommands.RemoveComponent(linkedEntityGroup[childIndexCompHashPair.EntityIndex].Value, rmCompType); } } } }
private static int GetEntityCountInHashMap(NativeMultiHashMap <int, MyData> map, int key) { return(map.CountValuesForKey(key)); }
public void Execute(ref MapTile tile, [ReadOnly] ref Sector sector) { tile.agents = (byte)hashMap.CountValuesForKey(sector.coordinates); }
public void Execute(int jobIndex) { var stateKey = StatesToUpdate[jobIndex]; StateInfo updatedStateInfo; var actionCount = ActionLookup.CountValuesForKey(stateKey); if (actionCount == 0) { if (UpdateStateValueNoActions(stateKey, out updatedStateInfo)) { // Queue for write job StateInfoLookup[stateKey] = updatedStateInfo; // If a change has occured, queue predecessors for update if (PredecessorGraph.TryGetFirstValue(stateKey, out var predecessorStateKey, out var predecessorIterator)) { do { PredecessorStatesToUpdate.TryAdd(predecessorStateKey, default); }while (PredecessorGraph.TryGetNextValue(out predecessorStateKey, ref predecessorIterator)); } } return; } // Allocate local container if (!m_ActionInfoForState.IsCreated) { m_ActionInfoForState = new NativeList <ActionInfo>(actionCount, Allocator.Temp); } else { m_ActionInfoForState.Clear(); } // Expanded state. Only update if one or more actions have updated. var updateState = false; // Update all actions ActionLookup.TryGetFirstValue(stateKey, out var actionKey, out var stateActionIterator); do { var stateActionPair = new StateActionPair <TStateKey, TActionKey>(stateKey, actionKey); if (UpdateCumulativeReward(stateActionPair, out var actionInfo)) { // Queue for write job ActionInfoLookup[stateActionPair] = actionInfo; updateState = true; } m_ActionInfoForState.Add(actionInfo); }while (ActionLookup.TryGetNextValue(out actionKey, ref stateActionIterator)); // If no actions have changed info, the state info will not change, so check before updating state. if (updateState && UpdateStateValueFromActions(stateKey, m_ActionInfoForState, out updatedStateInfo)) { // Queue for write job StateInfoLookup[stateKey] = updatedStateInfo; // If a change has occured, queue predecessors for update if (PredecessorGraph.TryGetFirstValue(stateKey, out var predecessorStateKey, out var predecessorIterator)) { do { PredecessorStatesToUpdate.TryAdd(predecessorStateKey, default); }while (PredecessorGraph.TryGetNextValue(out predecessorStateKey, ref predecessorIterator)); } } }