using System.Collections.Generic; namespace Netron.Diagramming.Core.Layout.Force { /// /// Represents a spring in a force simulation. /// public class Spring { #region Fields private static SpringFactory mFactory = new SpringFactory(); private ForceItem item1; private ForceItem item2; private float length; private float coeff; #endregion #region Properties /// /// Retrieve the SpringFactory instance, which serves as an object pool /// for Spring instances. /// /// The spring factory. public static SpringFactory Factory { get { return mFactory; } } /// /// The first ForceItem endpoint /// public ForceItem Item1 { get { return item1; } set { item1 = value; } } /// /// The second ForceItem endpoint /// public ForceItem Item2 { get { return item2; } set { item2 = value; } } /// /// The spring's resting length /// public float Length { get { return length; } set { length = value; } } /// /// The spring tension co-efficient /// public float Coeff { get { return coeff; } set { coeff = value; } } #endregion #region Constructor /// /// Create a new Spring instance /// the first ForceItem endpoint /// the second ForceItem endpoint /// the spring tension co-efficient /// the spring's resting length /// public Spring(ForceItem fi1, ForceItem fi2, float k, float len) { item1 = fi1; item2 = fi2; coeff = k; length = len; } #endregion #region Classes /// /// The SpringFactory is responsible for generating Spring instances /// and maintaining an object pool of Springs to reduce garbage collection /// overheads while force simulations are running. /// public sealed class SpringFactory { public const int Capacity = 5000; private List springs = new List(Capacity); /// /// Get a Spring instance and set it to the given parameters. /// public Spring getSpring(ForceItem f1, ForceItem f2, float k, float length) { if (springs.Count > 0) { Spring s = springs[springs.Count - 1]; springs.Remove(s); s.Item1 = f1; s.Item2 = f2; s.Coeff = k; s.Length = length; return s; } else { return new Spring(f1, f2, k, length); } } /// /// Reclaim a Spring into the object pool. /// public void reclaim(Spring s) { s.Item1 = null; s.Item2 = null; if (springs.Count < Capacity) springs.Add(s); } } #endregion } }