[Test] public void RemoveResetsReferenceTypesToDefault() { RawList <string> list = new RawList <string>( Enumerable.Range(0, 10) .Select(i => i.ToString()) .ToArray()); // Is the internal array empty if not assigned otherwise? if (list.Capacity > list.Count) { Assert.AreSame(null, list.Data[list.Count]); } // Adjusting the count shouldn't affect the internal array, just as documented list.Count = 0; for (int i = 0; i < 10; i++) { Assert.AreNotSame(null, list.Data[i]); } list.Count = 10; // Check various types of removal and make sure the internal array is reset properly { // Remove an element list.Remove("1"); Assert.AreSame(null, list.Data[list.Count]); list.RemoveAt(5); Assert.AreSame(null, list.Data[list.Count]); // Remove the last element specifically to tap into a different code path list.RemoveAt(list.Count - 1); Assert.AreSame(null, list.Data[list.Count]); // Remove a range list.RemoveRange(0, 5); for (int i = list.Count; i < list.Data.Length; i++) { Assert.AreSame(null, list.Data[i]); } // Clear the list list.Clear(); for (int i = list.Count; i < list.Data.Length; i++) { Assert.AreSame(null, list.Data[i]); } } }
///<summary> /// Removes an entity from the manager. ///</summary> ///<param name="e">Entity to remove.</param> ///<exception cref="InvalidOperationException">Thrown if the entity does not belong to this manager.</exception> public void Remove(Entity e) { lock (InterpolatedStates.FlipLocker) { lock (ReadBuffers.FlipLocker) { if (e.BufferedStates.BufferedStatesManager == this) { int index = entities.IndexOf(e); int endIndex = entities.Count - 1; entities[index] = entities[endIndex]; entities.RemoveAt(endIndex); if (index < entities.Count) { entities[index].BufferedStates.motionStateIndex = index; } if (ReadBuffers.Enabled) { ReadBuffers.Remove(index, endIndex); } if (InterpolatedStates.Enabled) { InterpolatedStates.Remove(index, endIndex); } e.BufferedStates.BufferedStatesManager = null; } else { throw new InvalidOperationException("Entity does not belong to this BufferedStatesManager; cannot remove."); } } } }
internal void Remove(ref Int2 index, Grid2DEntry entry) { int cellIndex; int sortingHash; if (TryGetIndex(ref index, out cellIndex, out sortingHash)) { cells.Elements[cellIndex].Remove(entry); if (cells.Elements[cellIndex].entries.count == 0) { //The cell is now empty. Give it back to the pool. var toRemove = cells.Elements[cellIndex]; //There's no cleanup to do on the grid cell. //Its list is empty, and the rest is just value types. cells.RemoveAt(cellIndex); cellPool.GiveBack(toRemove); count--; } } //int sortingHash = index.GetSortingHash(); //int minIndex = 0; //inclusive //int maxIndex = count; //exclusive //int i = 0; //while (maxIndex - minIndex > 0) //If the testing interval has a length of zero, we've done as much as we can. //{ // i = (maxIndex + minIndex) / 2; // if (cells.Elements[i].sortingHash > sortingHash) // maxIndex = i; // else if (cells.Elements[i].sortingHash < sortingHash) // minIndex = ++i; // else // { // //Found an equal sorting hash! // //The hash can collide, and we cannot add an entry to // //an incorrect index. It would break the 'cell responsibility' // //used by the cell update process to avoid duplicate overlaps. // //So, check if the index we found is ACTUALLY correct. // if (cells.Elements[i].cellIndex.Y == index.Y && cells.Elements[i].cellIndex.Z == index.Z) // { // cells.Elements[i].Remove(entry); // if (cells.Elements[i].entries.count == 0) // { // //The cell is now empty. Give it back to the pool. // var toRemove = cells.Elements[i]; // //There's no cleanup to do on the grid cell. // //Its list is empty, and the rest is just value types. // cells.RemoveAt(i); // cellPool.GiveBack(toRemove); // count--; // } // return; // } // //If it was not the correct index, let it continue searching. // } //} ////Getting here should be impossible. }
///<summary> /// Cleans up the constraint. ///</summary> public override void CleanUp() { //Deactivate any remaining constraints. for (int i = penetrationConstraints.count - 1; i >= 0; i--) { var penetrationConstraint = penetrationConstraints.Elements[i]; penetrationConstraint.CleanUp(); penetrationConstraints.RemoveAt(i); penetrationConstraintPool.Push(penetrationConstraint); } if (twistFriction.isActive) { twistFriction.CleanUp(); slidingFriction.CleanUp(); } }
/// <summary> /// Removes an entry from the broad phase. /// </summary> /// <param name="entry">Entry to remove.</param> public override void Remove(BroadPhaseEntry entry) { base.Remove(entry); for (int i = 0; i < entries.Count; i++) { if (entries.Elements[i].item == entry) { var gridEntry = entries.Elements[i]; entries.RemoveAt(i); //Remove the object from any cells that it is held by. for (int j = gridEntry.previousMin.Y; j <= gridEntry.previousMax.Y; j++) { for (int k = gridEntry.previousMin.Z; k <= gridEntry.previousMax.Z; k++) { var index = new Int2 { Y = j, Z = k }; cellSet.Remove(ref index, gridEntry); } } gridEntry.item = null; entryPool.GiveBack(gridEntry); return; } } }
internal void Destroy(Contact contact, int index) { Fixture fixtureA = contact.FixtureA; Fixture fixtureB = contact.FixtureB; Body bodyA = fixtureA.Body; Body bodyB = fixtureB.Body; if (EndContact != null && contact.IsTouching()) { EndContact(contact); } // Remove from the world. if (index == -1) { ContactList.Remove(contact); } else { ContactList.RemoveAt(index); } // Remove from body 1 if (contact.NodeA.Prev != null) { contact.NodeA.Prev.Next = contact.NodeA.Next; } if (contact.NodeA.Next != null) { contact.NodeA.Next.Prev = contact.NodeA.Prev; } if (contact.NodeA == bodyA.ContactList) { bodyA.ContactList = contact.NodeA.Next; } // Remove from body 2 if (contact.NodeB.Prev != null) { contact.NodeB.Prev.Next = contact.NodeB.Next; } if (contact.NodeB.Next != null) { contact.NodeB.Next.Prev = contact.NodeB.Prev; } if (contact.NodeB == bodyB.ContactList) { bodyB.ContactList = contact.NodeB.Next; } contact.Destroy(); }
///<summary> /// Cleans up the constraint. ///</summary> public override void CleanUp() { //Deactivate any remaining constraints. for (int i = penetrationConstraints.count - 1; i >= 0; i--) { var penetrationConstraint = penetrationConstraints.Elements[i]; penetrationConstraint.CleanUp(); penetrationConstraints.RemoveAt(i); penetrationConstraintPool.Push(penetrationConstraint); } for (int i = frictionConstraints.count - 1; i >= 0; i--) { var frictionConstraint = frictionConstraints.Elements[i]; frictionConstraint.CleanUp(); frictionConstraints.RemoveAt(i); frictionConstraintPool.Push(frictionConstraint); } }
[Test] public void Basics() { RawList <int> intList = new RawList <int>(); intList.Add(10); intList.AddRange(new int[] { 17, 42, 94 }); Assert.AreEqual(4, intList.Count); Assert.IsTrue(intList.Contains(42)); Assert.AreEqual(2, intList.IndexOf(42)); CollectionAssert.AreEqual(new int[] { 10, 17, 42, 94 }, intList); CollectionAssert.AreEqual(new int[] { 10, 17, 42, 94 }, intList.Data.Take(intList.Count)); intList.ShrinkToFit(); Assert.AreEqual(intList.Count, intList.Capacity); intList.Remove(42); Assert.AreEqual(3, intList.Count); Assert.IsTrue(!intList.Contains(42)); Assert.AreEqual(-1, intList.IndexOf(42)); CollectionAssert.AreEqual(new int[] { 10, 17, 94 }, intList); CollectionAssert.AreEqual(new int[] { 10, 17, 94 }, intList.Data.Take(intList.Count)); intList.Insert(1, 100); CollectionAssert.AreEqual(new int[] { 10, 100, 17, 94 }, intList); CollectionAssert.AreEqual(new int[] { 10, 100, 17, 94 }, intList.Data.Take(intList.Count)); intList.InsertRange(2, new int[] { 150, 200, 250, 300 }); CollectionAssert.AreEqual(new int[] { 10, 100, 150, 200, 250, 300, 17, 94 }, intList); CollectionAssert.AreEqual(new int[] { 10, 100, 150, 200, 250, 300, 17, 94 }, intList.Data.Take(intList.Count)); intList.RemoveAt(1); CollectionAssert.AreEqual(new int[] { 10, 150, 200, 250, 300, 17, 94 }, intList); CollectionAssert.AreEqual(new int[] { 10, 150, 200, 250, 300, 17, 94 }, intList.Data.Take(intList.Count)); intList.RemoveLast(); CollectionAssert.AreEqual(new int[] { 10, 150, 200, 250, 300, 17 }, intList); CollectionAssert.AreEqual(new int[] { 10, 150, 200, 250, 300, 17 }, intList.Data.Take(intList.Count)); intList.RemoveLast(4); CollectionAssert.AreEqual(new int[] { 10, 150 }, intList); CollectionAssert.AreEqual(new int[] { 10, 150 }, intList.Data.Take(intList.Count)); intList.Clear(); Assert.AreEqual(0, intList.Count); Assert.IsTrue(!intList.Contains(10)); }
internal void Remove(ref Int2 index, Grid2DEntry entry) { int cellIndex; int sortingHash; if (TryGetIndex(ref index, out cellIndex, out sortingHash)) { cells.Elements[cellIndex].Remove(entry); if (cells.Elements[cellIndex].entries.Count == 0) { //The cell is now empty. Give it back to the pool. GridCell2D toRemove = cells.Elements[cellIndex]; //There's no cleanup to do on the grid cell. //Its list is empty, and the rest is just value types. cells.RemoveAt(cellIndex); cellPool.GiveBack(toRemove); count--; } } }
public static void Unmount(string prefix) { //if (prefix[prefix.Length - 1] != DirectorySeparatorChar) { // prefix = prefix + DirectorySeparatorChar; //} for (int i = 0; i < virtualFileSystems.Count; i++) { if (virtualFileSystems[i].Prefix == prefix) { IDisposable disposable = virtualFileSystems[i].FileSystem as IDisposable; if (disposable != null) { disposable.Dispose(); } virtualFileSystems.RemoveAt(i); break; } } }
[Test] public void Basics() { RawList<int> intList = new RawList<int>(); intList.Add(10); intList.AddRange(new int[] { 17, 42, 94 }); Assert.AreEqual(4, intList.Count); Assert.IsTrue(intList.Contains(42)); Assert.AreEqual(2, intList.IndexOf(42)); CollectionAssert.AreEqual(new int[] { 10, 17, 42, 94 }, intList); CollectionAssert.AreEqual(new int[] { 10, 17, 42, 94 }, intList.Data.Take(intList.Count)); intList.ShrinkToFit(); Assert.AreEqual(intList.Count, intList.Capacity); intList.Remove(42); Assert.AreEqual(3, intList.Count); Assert.IsTrue(!intList.Contains(42)); Assert.AreEqual(-1, intList.IndexOf(42)); CollectionAssert.AreEqual(new int[] { 10, 17, 94 }, intList); CollectionAssert.AreEqual(new int[] { 10, 17, 94 }, intList.Data.Take(intList.Count)); intList.Insert(1, 100); CollectionAssert.AreEqual(new int[] { 10, 100, 17, 94 }, intList); CollectionAssert.AreEqual(new int[] { 10, 100, 17, 94 }, intList.Data.Take(intList.Count)); intList.InsertRange(2, new int[] { 150, 200, 250, 300 }); CollectionAssert.AreEqual(new int[] { 10, 100, 150, 200, 250, 300, 17, 94 }, intList); CollectionAssert.AreEqual(new int[] { 10, 100, 150, 200, 250, 300, 17, 94 }, intList.Data.Take(intList.Count)); intList.RemoveAt(1); CollectionAssert.AreEqual(new int[] { 10, 150, 200, 250, 300, 17, 94 }, intList); CollectionAssert.AreEqual(new int[] { 10, 150, 200, 250, 300, 17, 94 }, intList.Data.Take(intList.Count)); intList.Clear(); Assert.AreEqual(0, intList.Count); Assert.IsTrue(!intList.Contains(94)); }
private static void GenerateCollisionShapes(TileEdgeMap edgeMap, Vector2 origin, Vector2 tileSize, bool roundedCorners, IList <ShapeInfo> shapeList) { // Traverse the edge map and gradually create chain / loop // shapes until all edges have been used. RawList <Point2> currentChain = new RawList <Point2>(); RawList <Vector2> vertexBuffer = new RawList <Vector2>(); while (true) { // Begin a new continuous chain of nodes currentChain.Clear(); // Find a starting node for our current chain. // If there is none, we found and handled all edges. Point2 start = edgeMap.FindNonEmpty(); if (start == new Point2(-1, -1)) { break; } // Traverse the current chain node-by-node from the start we found Point2 current = start; while (true) { // Add the current node to our continuous chain currentChain.Add(current); // Find the next node that connects to the current one. // If there is none, our current chain is done. Point2 next = edgeMap.GetClockwiseNextFrom(current); if (next == new Point2(-1, -1)) { break; } // Remove the edge we used to get to the next node edgeMap.RemoveEdge(current, next); // Use the next node as origin for traversing further current = next; } // Generate a shape from the current chain bool isLoop = (start == currentChain[currentChain.Count - 1]); if (isLoop) { currentChain.RemoveAt(currentChain.Count - 1); } vertexBuffer.Clear(); // Rounded corners if (roundedCorners && currentChain.Count >= 3) { vertexBuffer.Reserve(currentChain.Count * 2); vertexBuffer.Count = 0; for (int i = 0; i < currentChain.Count; i++) { int prevIndex = (i - 1 + currentChain.Count) % currentChain.Count; int nextIndex = (i + 1) % currentChain.Count; Vector2 currentVert = origin + tileSize * (Vector2)currentChain[i]; Vector2 prevVert = origin + tileSize * (Vector2)currentChain[prevIndex]; Vector2 nextVert = origin + tileSize * (Vector2)currentChain[nextIndex]; if (nextVert - currentVert != currentVert - prevVert) { if (!isLoop && (i == 0 || i == currentChain.Count - 1)) { vertexBuffer.Add(currentVert); } else { vertexBuffer.Add(currentVert + (prevVert - currentVert).Normalized * tileSize * 0.2f); vertexBuffer.Add(currentVert + (nextVert - currentVert).Normalized * tileSize * 0.2f); } } } } // Sharp corners else { vertexBuffer.Reserve(currentChain.Count); vertexBuffer.Count = 0; for (int i = 0; i < currentChain.Count; i++) { int prevIndex = (i - 1 + currentChain.Count) % currentChain.Count; int nextIndex = (i + 1) % currentChain.Count; Vector2 currentVert = origin + tileSize * (Vector2)currentChain[i]; Vector2 prevVert = origin + tileSize * (Vector2)currentChain[prevIndex]; Vector2 nextVert = origin + tileSize * (Vector2)currentChain[nextIndex]; if (nextVert - currentVert != currentVert - prevVert) { vertexBuffer.Add(currentVert); } } } Vector2[] vertices = new Vector2[vertexBuffer.Count]; vertexBuffer.CopyTo(vertices, 0); shapeList.Add(isLoop ? (ShapeInfo) new LoopShapeInfo(vertices) : (ShapeInfo) new ChainShapeInfo(vertices)); } }
protected RawList<ImportInputAssignment> SelectImporter(AssetImportEnvironment env) { if (!env.IsPrepareStep) throw new ArgumentException( "The specified import environment must be configured as a preparation environment.", "env"); // Find an importer to handle some or all of the unhandled input files RawList<ImportInputAssignment> candidateMapping = new RawList<ImportInputAssignment>(); foreach (IAssetImporter importer in AssetManager.Importers) { env.ResetAcquiredData(); try { importer.PrepareImport(env); } catch (Exception ex) { Log.Editor.WriteError("An error occurred in the preparation step of '{1}': {0}", Log.Exception(ex), Log.Type(importer.GetType())); continue; } if (env.HandledInput.Any()) { candidateMapping.Add(new ImportInputAssignment { Importer = importer, HandledInput = env.HandledInput.ToArray(), ExpectedOutput = env.Output.ToArray() }); } } // Sort candidate mapping from most files to least files, so we can solve the biggest conflicts first candidateMapping.Sort((a, b) => b.HandledInput.Length - a.HandledInput.Length); // Determine if multiple importers intend to handle the same files and resolve conflicts List<int> conflictingIndices = new List<int>(); List<string> conflictingFiles = new List<string>(); for (int mainIndex = 0; mainIndex < candidateMapping.Count; mainIndex++) { ImportInputAssignment assignment = candidateMapping[mainIndex]; // Find all conflicts related to this assignment conflictingIndices.Clear(); conflictingFiles.Clear(); for (int secondIndex = 0; secondIndex < candidateMapping.Count; secondIndex++) { if (secondIndex == mainIndex) continue; ImportInputAssignment conflictAssignment = candidateMapping[secondIndex]; IEnumerable<string> mainFiles = assignment.HandledInput.Select(item => item.Path); IEnumerable<string> secondFiles = conflictAssignment.HandledInput.Select(item => item.Path); string[] conflicts = mainFiles.Intersect(secondFiles).ToArray(); if (conflicts.Length > 0) { if (conflictingIndices.Count == 0) conflictingIndices.Add(mainIndex); conflictingIndices.Add(secondIndex); conflictingFiles.AddRange(conflicts); } } // Resolve conflicts with this assignment if (conflictingIndices.Count > 0) { // Determine which importer to prefer for this conflict ImportInputAssignment[] conflictingAssignments = conflictingIndices.Select(i => candidateMapping[i]).ToArray(); int keepIndex = this.ResolveMappingConflict(conflictingAssignments); // If we somehow decided that none of the options is viable, abort the operation if (keepIndex == -1) { candidateMapping.Clear(); return candidateMapping; } // Sort indices to remove in declining order and remove their mappings conflictingIndices.Remove(keepIndex); conflictingIndices.Sort((a, b) => b - a); foreach (int index in conflictingIndices) { candidateMapping.RemoveAt(index); } // Start over with the conflict search mainIndex = -1; continue; } } return candidateMapping; }
private static void MaintainEdge(int a, int b, RawList<int> edges) { bool contained = false; int index = 0; for (int k = 0; k < edges.Count; k += 2) { if ((edges[k] == a && edges[k + 1] == b) || (edges[k] == b && edges[k + 1] == a)) { contained = true; index = k; } } //If it isn't present, add it to the edge list. if (!contained) { edges.Add(a); edges.Add(b); } else { //If it is present, that means both edge-connected triangles were deleted now, so get rid of it. edges.RemoveAt(index); edges.RemoveAt(index); } }
/// <summary> /// Identifies the indices of points in a set which are on the outer convex hull of the set. /// </summary> /// <param name="points">List of points in the set.</param> /// <param name="indices">List of indices composing the triangulated surface of the convex hull. /// Each group of 3 indices represents a triangle on the surface of the hull.</param> public static void GetConvexHull(RawList<Vector3> points, RawList<int> indices) { //Points is what will be used as a vertex buffer. var outsidePoints = Resources.GetIntList(); var edges = Resources.GetIntList(); var toRemove = Resources.GetIntList(); //Populate the outside points for (int k = 0; k < points.Count; k++) { outsidePoints.Add(k); } //Find an initial tetrahedron var initialTetrahedron = Resources.GetIntList(); /*float volume = 0; Random random = new Random(); Vector3 dir; int count = 0; while (initialTetrahedron.Count != 4 && count < 100) { dir = new Vector3((float)random.NextDouble() - .5f, (float)random.NextDouble() - .5f, (float)random.NextDouble() - .5f); getExtremePointOfSet(dir, outsidePoints, points, out maxIndex); if(!initialTetrahedron.Contains(maxIndex)) initialTetrahedron.Add(maxIndex); if (initialTetrahedron.Count == 4) { //(a-d) * ((b-d)x(c-d) volume = Vector3.Dot(Vector3.Cross(points[initialTetrahedron[1]] - points[initialTetrahedron[3]], points[initialTetrahedron[2]] - points[initialTetrahedron[3]]), points[initialTetrahedron[0]] - points[initialTetrahedron[3]]); if (Math.Abs(volume) < epsilon) initialTetrahedron.RemoveAt(3); } count++; }*/ int min, max; GetExtremePointsOfSet(Vector3.Up, points, out min, out max); if (min == max) throw new ArgumentException("Point set is degenerate."); initialTetrahedron.Add(min); initialTetrahedron.Add(max); Vector3 direction = NoVector; for (int i = 0; i < points.Count; i++) { if (i != min && i != max) { direction = Vector3.Cross(points[min] - points[i], points[max] - points[i]); if (direction.LengthSquared() > BigEpsilon) { break; } } } float minDistance, maxDistance; float lineMin = Vector3.Dot(direction, points[min]); GetExtremePointsOfSet(direction, points, out min, out max, out minDistance, out maxDistance); if (Math.Abs(minDistance - lineMin) < BigEpsilon) { if (Math.Abs(maxDistance - lineMin) < BigEpsilon) { throw new ArgumentException("Point set is degenerate."); } initialTetrahedron.Add(max); } else { initialTetrahedron.Add(min); } direction = Vector3.Cross(points[initialTetrahedron[1]] - points[initialTetrahedron[0]], points[initialTetrahedron[2]] - points[initialTetrahedron[0]]); lineMin = Vector3.Dot(direction, points[initialTetrahedron[0]]); GetExtremePointsOfSet(direction, points, out min, out max, out minDistance, out maxDistance); if (Math.Abs(minDistance - lineMin) < BigEpsilon) { if (Math.Abs(maxDistance - lineMin) < BigEpsilon) { throw new ArgumentException("Point set is degenerate."); } initialTetrahedron.Add(max); } else { initialTetrahedron.Add(min); } //Add initial tetrahedron triangles to indices list, remove from outside points, and remove all interior points from outside points. if (initialTetrahedron.Count == 4) { indices.Add(initialTetrahedron[0]); indices.Add(initialTetrahedron[1]); indices.Add(initialTetrahedron[2]); indices.Add(initialTetrahedron[1]); indices.Add(initialTetrahedron[2]); indices.Add(initialTetrahedron[3]); indices.Add(initialTetrahedron[2]); indices.Add(initialTetrahedron[3]); indices.Add(initialTetrahedron[0]); indices.Add(initialTetrahedron[3]); indices.Add(initialTetrahedron[0]); indices.Add(initialTetrahedron[1]); for (int k = 0; k < 4; k++) { outsidePoints.Remove(initialTetrahedron[k]); } VerifyWindings(indices, points); RemovePointsInPolyhedronIfInside(outsidePoints, points, indices); } else throw new ArgumentException("Could not form an initial tetrahedron from the input points; ensure that the input point set has volume."); Resources.GiveBack(initialTetrahedron); while (outsidePoints.Count > 0) { //While the convex hull is incomplete for (int k = 0; k < indices.Count; k += 3) { //Find the normal of the triangle Vector3 normal; FindNormal(indices, points, k, out normal); //Get the furthest point in the direction of the normal. int maxIndex; Vector3 maximum = GetExtremePointOfSet(normal, outsidePoints, points, out maxIndex); //If the point is visible by the triangle, continue. Vector3 offset; Vector3.Subtract(ref maximum, ref points.Elements[indices.Elements[k]], out offset); float dot; Vector3.Dot(ref normal, ref offset, out dot); if (dot >= 0) { //It's been picked! Remove the maximum point from the outside. outsidePoints.Remove(maxIndex); //Remove any triangles that can see the point, including itself! edges.Clear(); toRemove.Clear(); for (int n = 0; n < indices.Count; n += 3) { //Go through each triangle, if it can be seen, delete it and use maintainEdge on its edges. if (IsTriangleVisibleFromPoint(indices, points, n, ref maximum)) { //This triangle can see it! MaintainEdge(indices[n], indices[n + 1], edges); MaintainEdge(indices[n], indices[n + 2], edges); MaintainEdge(indices[n + 1], indices[n + 2], edges); indices.RemoveAt(n); indices.RemoveAt(n); indices.RemoveAt(n); n -= 3; } } //Create new triangles for (int n = 0; n < edges.Count; n += 2) { //For each edge, create a triangle with the extreme point. indices.Add(edges[n]); indices.Add(edges[n + 1]); indices.Add(maxIndex); } VerifyWindings(indices, points); //Remove all points from the outsidePoints if they are inside the polyhedron RemovePointsInPolyhedronIfInside(outsidePoints, points, indices); //The list has been significantly messed with, so restart the loop. break; } } } //"Hullify" the points. Resources.GiveBack(outsidePoints); Resources.GiveBack(edges); Resources.GiveBack(toRemove); }
private void RemoveParticle(int index) { particles.RemoveAt(index); }
protected RawList <ImportInputAssignment> SelectImporter(AssetImportEnvironment env) { if (!env.IsPrepareStep) { throw new ArgumentException( "The specified import environment must be configured as a preparation environment.", "env"); } // Find an importer to handle some or all of the unhandled input files RawList <ImportInputAssignment> candidateMapping = new RawList <ImportInputAssignment>(); foreach (IAssetImporter importer in AssetManager.Importers) { env.ResetAcquiredData(); try { importer.PrepareImport(env); } catch (Exception ex) { Log.Editor.WriteError("An error occurred in the preparation step of '{1}': {0}", Log.Exception(ex), Log.Type(importer.GetType())); continue; } if (env.HandledInput.Any()) { candidateMapping.Add(new ImportInputAssignment { Importer = importer, HandledInput = env.HandledInput.ToArray(), ExpectedOutput = env.Output.ToArray() }); } } // Sort candidate mapping from most files to least files, so we can solve the biggest conflicts first candidateMapping.Sort((a, b) => b.HandledInput.Length - a.HandledInput.Length); // Determine if multiple importers intend to handle the same files and resolve conflicts List <int> conflictingIndices = new List <int>(); List <string> conflictingFiles = new List <string>(); for (int mainIndex = 0; mainIndex < candidateMapping.Count; mainIndex++) { ImportInputAssignment assignment = candidateMapping[mainIndex]; // Find all conflicts related to this assignment conflictingIndices.Clear(); conflictingFiles.Clear(); for (int secondIndex = 0; secondIndex < candidateMapping.Count; secondIndex++) { if (secondIndex == mainIndex) { continue; } ImportInputAssignment conflictAssignment = candidateMapping[secondIndex]; IEnumerable <string> mainFiles = assignment.HandledInput.Select(item => item.Path); IEnumerable <string> secondFiles = conflictAssignment.HandledInput.Select(item => item.Path); string[] conflicts = mainFiles.Intersect(secondFiles).ToArray(); if (conflicts.Length > 0) { if (conflictingIndices.Count == 0) { conflictingIndices.Add(mainIndex); } conflictingIndices.Add(secondIndex); conflictingFiles.AddRange(conflicts); } } // Resolve conflicts with this assignment if (conflictingIndices.Count > 0) { // Determine which importer to prefer for this conflict ImportInputAssignment[] conflictingAssignments = conflictingIndices.Select(i => candidateMapping[i]).ToArray(); int keepIndex = this.ResolveMappingConflict(conflictingAssignments); // If we somehow decided that none of the options is viable, abort the operation if (keepIndex == -1) { candidateMapping.Clear(); return(candidateMapping); } // Sort indices to remove in declining order and remove their mappings conflictingIndices.Remove(keepIndex); conflictingIndices.Sort((a, b) => b - a); foreach (int index in conflictingIndices) { candidateMapping.RemoveAt(index); } // Start over with the conflict search mainIndex = -1; continue; } } return(candidateMapping); }
[Test] public void RemoveResetsReferenceTypesToDefault() { RawList<string> list = new RawList<string>(Enumerable.Range(0, 10).Select(i => i.ToString())); // Is the internal array empty if not assigned otherwise? if (list.Capacity > list.Count) Assert.AreSame(null, list.Data[list.Count]); // Adjusting the count shouldn't affect the internal array, just as documented list.Count = 0; for (int i = 0; i < 10; i++) { Assert.AreNotSame(null, list.Data[i]); } list.Count = 10; // Check various types of removal and make sure the internal array is reset properly { // Remove an element list.Remove("1"); Assert.AreSame(null, list.Data[list.Count]); list.RemoveAt(5); Assert.AreSame(null, list.Data[list.Count]); // Remove a range list.RemoveRange(0, 5); for (int i = list.Count; i < list.Data.Length; i++) { Assert.AreSame(null, list.Data[i]); } // Clear the list list.Clear(); for (int i = list.Count; i < list.Data.Length; i++) { Assert.AreSame(null, list.Data[i]); } } }
private static void GenerateCollisionShapes(TileEdgeMap edgeMap, Vector2 origin, Vector2 tileSize, bool roundedCorners, IList<ShapeInfo> shapeList) { // Traverse the edge map and gradually create chain / loop // shapes until all edges have been used. RawList<Point2> currentChain = new RawList<Point2>(); RawList<Vector2> vertexBuffer = new RawList<Vector2>(); while (true) { // Begin a new continuous chain of nodes currentChain.Clear(); // Find a starting node for our current chain. // If there is none, we found and handled all edges. Point2 start = edgeMap.FindNonEmpty(); if (start == new Point2(-1, -1)) break; // Traverse the current chain node-by-node from the start we found Point2 current = start; while (true) { // Add the current node to our continuous chain currentChain.Add(current); // Find the next node that connects to the current one. // If there is none, our current chain is done. Point2 next = edgeMap.GetClockwiseNextFrom(current); if (next == new Point2(-1, -1)) break; // Remove the edge we used to get to the next node edgeMap.RemoveEdge(current, next); // Use the next node as origin for traversing further current = next; } // Generate a shape from the current chain bool isLoop = (start == currentChain[currentChain.Count - 1]); if (isLoop) currentChain.RemoveAt(currentChain.Count - 1); vertexBuffer.Clear(); // Rounded corners if (roundedCorners && currentChain.Count >= 3) { vertexBuffer.Reserve(currentChain.Count * 2); vertexBuffer.Count = 0; for (int i = 0; i < currentChain.Count; i++) { int prevIndex = (i - 1 + currentChain.Count) % currentChain.Count; int nextIndex = (i + 1) % currentChain.Count; Vector2 currentVert = origin + tileSize * (Vector2)currentChain[i]; Vector2 prevVert = origin + tileSize * (Vector2)currentChain[prevIndex]; Vector2 nextVert = origin + tileSize * (Vector2)currentChain[nextIndex]; if (nextVert - currentVert != currentVert - prevVert) { if (!isLoop && (i == 0 || i == currentChain.Count - 1)) { vertexBuffer.Add(currentVert); } else { vertexBuffer.Add(currentVert + (prevVert - currentVert).Normalized * tileSize * 0.2f); vertexBuffer.Add(currentVert + (nextVert - currentVert).Normalized * tileSize * 0.2f); } } } } // Sharp corners else { vertexBuffer.Reserve(currentChain.Count); vertexBuffer.Count = 0; for (int i = 0; i < currentChain.Count; i++) { int prevIndex = (i - 1 + currentChain.Count) % currentChain.Count; int nextIndex = (i + 1) % currentChain.Count; Vector2 currentVert = origin + tileSize * (Vector2)currentChain[i]; Vector2 prevVert = origin + tileSize * (Vector2)currentChain[prevIndex]; Vector2 nextVert = origin + tileSize * (Vector2)currentChain[nextIndex]; if (nextVert - currentVert != currentVert - prevVert) vertexBuffer.Add(currentVert); } } shapeList.Add(isLoop ? (ShapeInfo)new LoopShapeInfo(vertexBuffer) : (ShapeInfo)new ChainShapeInfo(vertexBuffer)); } }