using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; namespace RealTimeGraphEx.Models { public class ConcurrentpointsList { private List points; private List temppoints; private readonly object _lock = new object(); private bool isReading; public ConcurrentpointsList() { points = new List(); temppoints = new List(); } public void StartReading() { lock (_lock) { isReading = true; } } public void StopReading() { lock (_lock) { isReading = false; } } public void Add(double value) { if (!isReading) { lock (_lock) { points.AddRange(temppoints); points.Add(value); } } else { lock (_lock) { temppoints.Add(value); } } } public void AddRange(IEnumerable values) { if (!isReading) { lock (_lock) { points.AddRange(temppoints); points.AddRange(values); } } else { lock (_lock) { temppoints.AddRange(values); } } } public void Replace(double value, int index) { lock (_lock) { if (index < points.Count) { points.RemoveAt(index); points.Insert(index, value); } } } public void RemoveFromStart(int count) { if (count < 1) return; lock (_lock) { points.RemoveRange(0, count); } } public void RemoveRange(int index, int count) { lock (_lock) { points.RemoveRange(index, count); } } public void Clear() { lock (_lock) { points.Clear(); temppoints.Clear(); } } public List GetAndClearAllPoints() { List clonedPoints = new List(); lock (_lock) { clonedPoints.AddRange(points); points.Clear(); } return clonedPoints; } public int Count { get { lock (_lock) { return points.Count; } } } public double this[int index] { get { lock (_lock) { return points[index]; } } set { lock (_lock) { points[index] = value; } } } #region DX public SharpDX.Vector2[] ToDXPolygonPoints(double offsetX, double offsetY, double scaleFactor, Func scaleY) { double xValue = 0; lock (_lock) { SharpDX.Vector2[] vectors = new SharpDX.Vector2[points.Count]; try { for (int i = 0; i < points.Count; i++) { vectors[i] = new SharpDX.Vector2((float)(xValue + offsetX), (float)(scaleY(points[i]) + offsetY)); xValue += scaleFactor; } return vectors; } catch { return vectors; } } } public SharpDX.Vector2[] ToDXPolygonPointsFill(double offsetX, double offsetY, double width, double height, double scaleFactor, Func scaleY) { double xValue = 0; lock (_lock) { SharpDX.Vector2[] vectors = new SharpDX.Vector2[points.Count + 4]; for (int i = 0; i < points.Count; i++) { vectors[i] = new SharpDX.Vector2((float)(xValue + offsetX), (float)(scaleY(points[i]) + offsetY)); xValue += scaleFactor; } xValue += scaleFactor; int c = points.Count - 1; vectors[c++] = new SharpDX.Vector2((float)(xValue + offsetX), (float)vectors[vectors.Length - 5].Y); vectors[c++] = new SharpDX.Vector2((float)(xValue + offsetX), (float)height); vectors[c++] = new SharpDX.Vector2(0, (float)height); vectors[c++] = new SharpDX.Vector2(0, (float)vectors[1].Y); return vectors; } } #endregion #region Fast public int[] ToPolygonPoints(double offsetX, double offsetY, double scaleFactor, Func scaleY) { double xValue = 0; lock (_lock) { List polyPoints = new List(); try { for (int i = 0; i < points.Count; i++) { polyPoints.Add((int)(xValue + offsetX)); polyPoints.Add((int)(scaleY(points[i]) + offsetY)); xValue += scaleFactor; } return polyPoints.ToArray(); } catch { return polyPoints.ToArray(); } } } public int[] ToPolygonPointsFill(double offsetX, double offsetY, double width, double height, double scaleFactor, Func scaleY) { double xValue = 0; lock (points) { List polyPoints = new List(); for (int i = 0; i < points.Count; i++) { polyPoints.Add((int)(xValue + offsetX)); polyPoints.Add((int)(scaleY(points[i]) + offsetY)); xValue += scaleFactor; } polyPoints.Add((int)((xValue - scaleFactor) + offsetX)); polyPoints.Add((int)height); polyPoints.Add(0); polyPoints.Add((int)height); polyPoints.Add(0); polyPoints.Add(polyPoints[1]); return polyPoints.ToArray(); } } public int[] ToPolygonPointsReflection(double offsetX, double offsetY, double height, double scaleFactor, Func scaleY) { double xValue = 0; lock (points) { List polyPoints = new List(); for (int i = 0; i < points.Count; i++) { polyPoints.Add((int)(xValue + offsetX)); polyPoints.Add((int)((height - scaleY(points[i])) + offsetY)); xValue += scaleFactor; } return polyPoints.ToArray(); } } public int[] ToPolygonPointsWaveFill(double offsetX, double offsetY, double width, double height, double scaleFactor, Func scaleY) { double xValue = 0; lock (points) { List polyPoints = new List(); for (int i = 0; i < points.Count; i++) { polyPoints.Add((int)(xValue + offsetX)); polyPoints.Add((int)((scaleY(points[i])) + offsetY)); xValue += scaleFactor; } polyPoints.Add((int)width); polyPoints.Add((int)(height / 2)); polyPoints.Add((int)width); polyPoints.Add((int)((height - scaleY(points[points.Count - 1])) + offsetY)); xValue -= scaleFactor; for (int i = points.Count - 1; i >= 0; i--) { polyPoints.Add((int)(xValue + offsetX)); polyPoints.Add((int)((height - scaleY(points[i])) + offsetY)); xValue -= scaleFactor; } polyPoints.Add(0); polyPoints.Add(polyPoints[polyPoints.Count - 2]); polyPoints.Add(polyPoints[0]); polyPoints.Add((int)(height / 2)); polyPoints.Add(0); polyPoints.Add((int)(height / 2)); polyPoints.Add(0); polyPoints.Add(polyPoints[1]); return polyPoints.ToArray(); } } #endregion #region Reach public List ToReachPolygonPoints(double width, double height, double scaleFactor, Func scaleY) { double xValue = 0; lock (points) { List polyPoints = new List(); for (int i = 0; i < points.Count; i++) { polyPoints.Add(new Point(xValue, scaleY(points[i]))); xValue += scaleFactor; } return polyPoints; } } public List ToReachPolygonPointsFill(double width, double height, double scaleFactor, Func scaleY) { double xValue = 0; lock (points) { List polyPoints = new List(); for (int i = 0; i < points.Count; i++) { polyPoints.Add(new Point(xValue, scaleY(points[i]))); xValue += scaleFactor; } polyPoints.Add(new Point(xValue, height)); polyPoints.Add(new Point(0, height)); polyPoints.Add(new Point(0, polyPoints[0].Y)); return polyPoints; } } public List ToReachPolygonPointsWaveFill(double width, double height, double scaleFactor, Func scaleY) { if (points.Count == 0) return new List(); double xValue = 0; lock (points) { List polyPoints = new List(); for (int i = 0; i < points.Count; i++) { polyPoints.Add(new Point(xValue, scaleY(points[i]))); xValue += scaleFactor; } polyPoints.Add(new Point(width, (height / 2))); polyPoints.Add(new Point(width, (height - scaleY(points[points.Count - 1])))); xValue -= scaleFactor; for (int i = points.Count - 1; i >= 0; i--) { polyPoints.Add(new Point(xValue, (height - scaleY(points[i])))); xValue -= scaleFactor; } polyPoints.Add(new Point(0, polyPoints[polyPoints.Count - 1].Y)); polyPoints.Add(new Point(0, (height / 2))); polyPoints.Add(new Point(0, (height / 2))); polyPoints.Add(new Point(0, polyPoints[0].Y)); return polyPoints; } } #endregion public List GetPoints() { lock (_lock) { return points.ToList(); } } } }