/// <summary> /// Replace the given frame in the digest with a new frame. /// </summary> /// <param name="oldFrame">Frame to replace.</param> /// <param name="newFrame">Replacement frame.</param> public void Replace(ViewTimeFrame oldFrame, ViewTimeFrame newFrame) { Frames.Remove(oldFrame); // Use Add instead of Frames.Add, because it may be necessary to combine touching // frames. Add(newFrame); }
/// <summary> /// Combine this frame with the given frame, returning a frame representing the /// timespan covered by at least one of the two. /// </summary> /// <param name="other">The frame to combine with this one.</param> public ViewTimeFrame Union(ViewTimeFrame other) { // If this frame doesn't touch the other one, they can't be combined. if (!Touches(other)) { throw new ArgumentException("Cannot combine frames that do not touch."); } // The lesser of the two start times and the greater of the two end times are the // start and end of the combined frame. return(new ViewTimeFrame( Math.Min(Start, other.Start), Math.Max(End, other.End) )); }
/// <summary> /// Add a timeframe to the digest. /// </summary> public void Add(ViewTimeFrame newFrame) { if (!Frames.Any(f => f.Touches(newFrame))) { // If the new frame doesn't touch a frame already in the digest, simply add it to // the set. No need to combine it with any others. Frames.Add(newFrame); } else { // Since the new frame touches an existing one, find the first existing frame it // touches... var touchingFrame = Frames.First(f => f.Touches(newFrame)); // Then replace the touching frame with the union of the new and old frame. Replace(touchingFrame, touchingFrame.Union(newFrame)); } }
/// <summary> /// Get whether this time frame touches the other. Touching includes overlapping or being /// adjacent (sharing a start or end time). /// </summary> public bool Touches(ViewTimeFrame other) { return(Contains(other.Start) || other.Contains(Start)); }