private static void updateLines() { var identifiersToRemove = Pool <HashSet <string> > .Spawn(); try { foreach (var idLinePair in _pingLines) { var curLine = idLinePair.Value; curLine.time += Time.deltaTime; if (curLine.time > curLine.lifespan) { identifiersToRemove.Add(idLinePair.Key); } } foreach (var idToRemove in identifiersToRemove) { _pingLines.Remove(idToRemove); } } finally { identifiersToRemove.Clear(); Pool <HashSet <string> > .Recycle(identifiersToRemove); } }
/// <summary> /// Returns whether or not two lists contain the same elements ignoring order. /// </summary> public static bool AreEqualUnordered <T>(IList <T> a, IList <T> b) { var _count = Pool <Dictionary <T, int> > .Spawn(); try { int _nullCount = 0; foreach (var i in a) { if (i == null) { _nullCount++; } else { int count; if (!_count.TryGetValue(i, out count)) { count = 0; } _count[i] = count + 1; } } foreach (var i in b) { if (i == null) { _nullCount--; } else { int count; if (!_count.TryGetValue(i, out count)) { return(false); } _count[i] = count - 1; } } if (_nullCount != 0) { return(false); } foreach (var pair in _count) { if (pair.Value != 0) { return(false); } } return(true); } finally { _count.Clear(); Pool <Dictionary <T, int> > .Recycle(_count); } }
private void updatePings() { var indicesToRemove = Pool <List <int> > .Spawn(); try { for (int i = 0; i < _activePings.Count; i++) { var curPing = _activePings[i]; curPing.time += Time.deltaTime; if (curPing.time > 1f) { indicesToRemove.Add(i); } _activePings[i] = curPing; } for (int i = indicesToRemove.Count - 1; i >= 0; i--) { _activePings.RemoveAt(i); } } finally { indicesToRemove.Clear(); Pool <List <int> > .Recycle(indicesToRemove); } }
/// <summary> /// Returns a list of transforms including this transform and ALL of its children, /// including the children of its children, and the children of their children, and /// so on. /// /// THIS ALLOCATES GARBAGE. Use it for editor code only. /// </summary> public static List <Transform> GetSelfAndAllChildren(this Transform t, bool includeInactiveObjects = false) { var allChildren = new List <Transform>(); Queue <Transform> toVisit = Pool <Queue <Transform> > .Spawn(); try { // Traverse the hierarchy of this object's transform to find all of its Colliders. toVisit.Enqueue(t.transform); Transform curTransform; while (toVisit.Count > 0) { curTransform = toVisit.Dequeue(); // Recursively search children and children's children foreach (var child in curTransform.GetChildren()) { if (includeInactiveObjects || child.gameObject.activeSelf) { toVisit.Enqueue(child); } } allChildren.Add(curTransform); } } finally { toVisit.Clear(); Pool <Queue <Transform> > .Recycle(toVisit); } return(allChildren); }
private void Update() { var transforms = Pool <List <Transform> > .Spawn(); transforms.Clear(); poses.Clear(); try { this.GetComponentsInChildren <Transform>(transforms); foreach (var transform in transforms .Query() .Where(t => string.IsNullOrEmpty(nameMustContain) || t.name.Contains(nameMustContain))) { poses.Add(transform.ToWorldPose()); } } finally { transforms.Clear(); Pool <List <Transform> > .Recycle(transforms); } if (Time.frameCount % _frameCount == 0) { SendAsStream(); } }
/// <summary> /// If you spawned this BoxedIndexableStruct from a Pool, you can call this method /// to recycle it back into the pool. /// /// If you want to send an IIndexableStruct into a context that expects an /// IIndexable without boxing, you can "convert" it to an IIndexable without /// allocating by pooling the wrapper objects instead. /// /// This extension method is short-hand for recycling a pooled wrapper around a /// struct. It should be called in the <code>finally</code> block after a /// <code>try</code> block uses the wrapper as an IIndexable. Be sure to use /// the Pool for the BoxedIndexableStruct to spawn the wrapper in the first place. /// </summary> public static void Recycle <Element, IndexableStruct>(this BoxedIndexableStruct <Element, IndexableStruct> pooledWrapper) where IndexableStruct : struct, IIndexableStruct <Element, IndexableStruct> { Pool <BoxedIndexableStruct <Element, IndexableStruct> > .Recycle(pooledWrapper); }
/// <summary> /// Recursively searches the hierarchy of the argument GameObject to find all of the /// Colliders that are attached to the object's Rigidbody (or that _would_ be /// attached to its Rigidbody if it doesn't have one) and adds them to the provided /// colliders list. Warning: The provided "colliders" List will be cleared before /// use. /// /// Colliders that are the children of other Rigidbody elements beneath the argument /// object are ignored. Optionally, colliders of inactive GameObjects can be included /// in the returned list; by default, these colliders are skipped. /// </summary> public static void FindColliders <T>(GameObject obj, List <T> colliders, bool includeInactiveObjects = false) where T : Collider { colliders.Clear(); Stack <Transform> toVisit = Pool <Stack <Transform> > .Spawn(); List <T> collidersBuffer = Pool <List <T> > .Spawn(); try { // Traverse the hierarchy of this object's transform to find // all of its Colliders. toVisit.Push(obj.transform); Transform curTransform; while (toVisit.Count > 0) { curTransform = toVisit.Pop(); // Recursively search children and children's children foreach (var child in curTransform.GetChildren()) { // Ignore children with Rigidbodies of their own; its own Rigidbody // owns its own colliders and the colliders of its children if (child.GetComponent <Rigidbody>() == null && (includeInactiveObjects || child.gameObject.activeSelf)) { toVisit.Push(child); } } // Since we'll visit every valid child, all we need to do is add the colliders // of every transform we visit. collidersBuffer.Clear(); curTransform.GetComponents <T>(collidersBuffer); foreach (var collider in collidersBuffer) { colliders.Add(collider); } } } finally { toVisit.Clear(); Pool <Stack <Transform> > .Recycle(toVisit); collidersBuffer.Clear(); Pool <List <T> > .Recycle(collidersBuffer); } }
/// <summary> /// Given a list and an ordering, order the list according to the ordering. /// This method assumes the ordering is a valid ordering. /// </summary> public static void ApplyOrdering <T>(this IList <T> list, List <int> ordering) { Assert.IsNotNull(list); Assert.IsNotNull(ordering); Assert.AreEqual(list.Count, ordering.Count, "List must be the same length as the ordering."); List <T> copy = Pool <List <T> > .Spawn(); try { copy.AddRange(list); for (int i = 0; i < list.Count; i++) { list[i] = copy[ordering[i]]; } } finally { copy.Clear(); Pool <List <T> > .Recycle(copy); } }
/// <summary> /// Returns a list of transforms including this transform and ALL of its children, /// including the children of its children, and the children of their children, and /// so on. /// /// THIS ALLOCATES GARBAGE. Use it for editor code only. /// </summary> public static List <Transform> GetSelfAndAllChildren(this Transform t, bool includeInactiveObjects = false) { var allChildren = new List <Transform>(); Stack <Transform> toVisit = Pool <Stack <Transform> > .Spawn(); try { // Traverse the hierarchy of this object's transform to find all of its Colliders. toVisit.Push(t.transform); Transform curTransform; while (toVisit.Count > 0) { curTransform = toVisit.Pop(); // Recursively search children and children's children foreach (var child in curTransform.GetChildren()) { // Ignore children with Rigidbodies of their own; its own Rigidbody // owns its own colliders and the colliders of its children if (includeInactiveObjects || child.gameObject.activeSelf) { toVisit.Push(child); } } // Since we'll visit every valid child, all we need to do is add the colliders // of every transform we visit. allChildren.Add(curTransform); } } finally { toVisit.Clear(); Pool <Stack <Transform> > .Recycle(toVisit); } return(allChildren); }
private void refreshMesh() { if (outputToFilter == null) { return; } if (outputToFilter.sharedMesh == null) { outputToFilter.sharedMesh = new Mesh(); outputToFilter.sharedMesh.name = "PoseRibbonMesh Test"; } var mesh = outputToFilter.sharedMesh; mesh.Clear(); var pose0 = poseSource0.ToLocalPose(); var pose1 = poseSource1.ToLocalPose(); var pose2 = poseSource2.ToLocalPose(); var poses = Pool <List <Pose> > .Spawn(); poses.Clear(); try { poses.Add(pose0); poses.Add(pose1); poses.Add(pose2); if (!usePolyMeshMethod) { #region Non-PolyMesh Method var verts = Pool <List <Vector3> > .Spawn(); verts.Clear(); var indices = Pool <List <int> > .Spawn(); indices.Clear(); try { for (int i = 0; i < poses.Count; i++) { var p = poses[i]; verts.Add(left(p)); verts.Add(right(p)); } int vertsPerPose = 2; bool closeLoop = vertsPerPose != 2; for (int p = 0; p + 1 < poses.Count; p++) { for (int csi = 0; csi < vertsPerPose - (closeLoop ? 0 : 1); csi++) { var csRootIndex = p * vertsPerPose; var nextCSRootIndex = (p + 1) * vertsPerPose; var i0 = csRootIndex + csi; var i1 = nextCSRootIndex + csi; var i2 = nextCSRootIndex + ((csi + 1) % vertsPerPose); var i3 = csRootIndex + ((csi + 1) % vertsPerPose); indices.Add(i0); indices.Add(i1); indices.Add(i2); indices.Add(i0); indices.Add(i2); indices.Add(i3); } } mesh.SetVertices(verts); mesh.SetTriangles(indices, 0, true); mesh.RecalculateNormals(); } finally { verts.Clear(); Pool <List <Vector3> > .Recycle(verts); indices.Clear(); Pool <List <int> > .Recycle(indices); } #endregion } else { polyMesh.Clear(); // quad 0 polyMesh.AddPosition(left(pose0)); polyMesh.AddPosition(right(pose0)); polyMesh.AddPosition(left(pose1)); polyMesh.AddPosition(right(pose1)); var newPoly = Polygon.SpawnQuad(1, 0, 2, 3); polyMesh.AddPolygon(newPoly); // quad 1 polyMesh.AddPosition(left(pose2)); polyMesh.AddPosition(right(pose2)); var nextPoly = Polygon.SpawnQuad(3, 2, 4, 5); polyMesh.AddPolygon(nextPoly); // mark the edge between the two quads as smooth. polyMesh.MarkEdgeSmooth(new Edge(2, 3)); polyMesh.FillUnityMesh(mesh, doubleSided: true); } } finally { poses.Clear(); Pool <List <Pose> > .Recycle(poses); } }