void ForeachConnectedNode(AbstractMaterialNode node, PropagationDirection dir, Action <AbstractMaterialNode> action) { using (var tempEdges = PooledList <IEdge> .Get()) using (var tempSlots = PooledList <MaterialSlot> .Get()) { // Loop through all nodes that the node feeds into. if (dir == PropagationDirection.Downstream) { node.GetOutputSlots(tempSlots); } else { node.GetInputSlots(tempSlots); } foreach (var slot in tempSlots) { // get the edges out of each slot tempEdges.Clear(); // and here we serialize another list, ouch! m_Graph.GetEdges(slot.slotReference, tempEdges); foreach (var edge in tempEdges) { // We look at each node we feed into. var connectedSlot = (dir == PropagationDirection.Downstream) ? edge.inputSlot : edge.outputSlot; var connectedNode = connectedSlot.node; action(connectedNode); } } } }
void PropagateNodes(HashSet <AbstractMaterialNode> sources, PropagationDirection dir, HashSet <AbstractMaterialNode> result) { using (PropagateNodesMarker.Auto()) { // NodeWave represents the list of nodes we still have to process and add to result m_TempNodeWave.Clear(); m_TempAddedToNodeWave.Clear(); foreach (var node in sources) { m_TempNodeWave.Push(node); m_TempAddedToNodeWave.Add(node); } while (m_TempNodeWave.Count > 0) { var node = m_TempNodeWave.Pop(); if (node == null) { continue; } result.Add(node); // grab connected nodes in propagation direction, add them to the node wave ForeachConnectedNode(node, dir, AddNextLevelNodesToWave); } // clean up any temp data m_TempNodeWave.Clear(); m_TempAddedToNodeWave.Clear(); } }
void GetConnectedNodes <T>(AbstractMaterialNode node, PropagationDirection dir, T connections) where T : ICollection <AbstractMaterialNode> { // Loop through all nodes that the node feeds into. m_Slots.Clear(); if (dir == PropagationDirection.Downstream) { node.GetOutputSlots(m_Slots); } else { node.GetInputSlots(m_Slots); } foreach (var slot in m_Slots) { m_Edges.Clear(); m_Graph.GetEdges(slot.slotReference, m_Edges); foreach (var edge in m_Edges) { // We look at each node we feed into. var connectedSlot = (dir == PropagationDirection.Downstream) ? edge.inputSlot : edge.outputSlot; var connectedNodeGuid = connectedSlot.nodeGuid; var connectedNode = m_Graph.GetNodeFromGuid(connectedNodeGuid); // If the input node is already in the set, we don't need to process it. if (connections.Contains(connectedNode)) { continue; } // Add the node to the set, and to the wavefront such that we can process the nodes that it feeds into. connections.Add(connectedNode); } } }
void PropagateNodeList <T>(T nodes, PropagationDirection dir) where T : ICollection <AbstractMaterialNode> { m_NodeWave.Clear(); foreach (var node in nodes) { m_NodeWave.Push(node); } while (m_NodeWave.Count > 0) { var node = m_NodeWave.Pop(); if (node == null) { continue; } m_NextLevelNodes.Clear(); GetConnectedNodes(node, dir, m_NextLevelNodes); foreach (var nextNode in m_NextLevelNodes) { nodes.Add(nextNode); m_NodeWave.Push(nextNode); } } }
public void Deserialize(BinaryReader reader) { IsPassThrough = reader.ReadBoolean(); IsHardPassThrough = reader.ReadBoolean(); Range = reader.ReadInt32(); PropagationDirection = (PropagationDirection)reader.ReadInt32(); }
private void PropagateExplosions(List <int> templateIds, List <Explosion> propagateList, List <Placement> propagateListPlacement) { for (int explosionIndex = 0; explosionIndex < propagateList.Count; explosionIndex++) { Explosion explosion = propagateList[explosionIndex]; Placement placement = propagateListPlacement[explosionIndex]; Vector3 currentPosition = placement.Position; // Consider all directions for (int considerIndex = 0; considerIndex < propagationOffsets.Length; considerIndex++) { PropagationDirection consideredDirection = (PropagationDirection)(0x1 << considerIndex); if ((explosion.State.PropagationDirection & consideredDirection) == consideredDirection) { Point offset = propagationOffsets[considerIndex]; Vector3 newPosition = new Vector3(currentPosition.X + offset.X, currentPosition.Y + offset.Y, 0f); // We need to check that there aren't any hard barriers here. Explosions shouldn't go there (unless we have hard pass-through) ExplosionBarrier barrier = GetBarrierAtLocation(newPosition.ToInteger()); bool shouldGoHere = (barrier != ExplosionBarrier.Hard) || explosion.State.IsHardPassThrough; if (shouldGoHere) { // When creating the new wexplosion, use the same template as the previous. Entity newEntity = EntityManager.AllocateForGeneratedContent(EntityTemplateManager.GetTemplateById(templateIds[explosionIndex]), Universe.TopLevelGroupUniqueIdBase); Explosion newExplosion = (Explosion)EntityManager.GetComponent(newEntity, ComponentTypeIds.Explosion); newExplosion.State = explosion.State; newExplosion.State.Range--; // Reduce the range of course... // If we explode into a soft block, we don't propagate (unless we're passthrough) if (!ShouldExplosionPropagateThroughBarrier(barrier, explosion)) { newExplosion.State.Range = 0; } newExplosion.State.PropagationDirection = inheritedPropagationDirections[considerIndex]; // Assign its position Placement newPlacement = (Placement)EntityManager.GetComponent(newEntity, ComponentTypeIds.Placement); newPlacement.Position = newPosition; newPlacement.OrientationAngle = (float)(random.NextDouble() * 360.0); } } } explosion.State.PropagationDirection = PropagationDirection.None; // Mark this explosion so it doesn't propagate anymore! } }