public async Task AddLine(DrawnLine newLine) { if (newLine.Points.Count == 0) { Log.WriteLine("[Plane/{0}] Lines that don't contain any points can't be added to a chunk!", Name); return; } List <DrawnLine> chunkedLineParts; // Split the line up into chunked pieces if neccessary if (newLine.SpansMultipleChunks) { chunkedLineParts = newLine.SplitOnChunks(); } else { chunkedLineParts = new List <DrawnLine>() { newLine } }; foreach (DrawnLine linePart in chunkedLineParts) { if (linePart.Points.Count == 0) { Log.WriteLine("[Plane/{0}] Warning: A line part has no points in it O.o", Name); } } // Add each segment to the appropriate chunk, buffering the chunk update message BeginChunkUpdateBuffering(); foreach (DrawnLine newLineSegment in chunkedLineParts) { Chunk containingChunk = await FetchChunk(newLineSegment.ContainingChunk); containingChunk.Add(newLineSegment); } FinishChunkUpdateBuffering(); }
/// <summary> /// Splits this line into a list of lines that don't cross chunk boundaries. /// </summary> /// <returns>A list of lines, that, when stitched together, will produce this line.</returns> public List <DrawnLine> SplitOnChunks() { List <DrawnLine> results = new List <DrawnLine>(); // Don't bother splitting the line up if it all falls in the same chunk if (!SpansMultipleChunks) { results.Add(this); return(results); } DrawnLine nextLine = new DrawnLine(LineId); ChunkReference currentChunk = null; foreach (LocationReference point in Points) { if (currentChunk != null && !point.ContainingChunk.Equals(currentChunk)) { // We're heading into a new chunk! Split the line up here. // TODO: Add connecting lines to each DrawnLine instance to prevent gaps nextLine.Colour = Colour; nextLine.Width = Width; if (nextLine.Points.Count > 0) { results.Add(nextLine); } nextLine = new DrawnLine(LineId); } nextLine.Points.Add(point); if (!point.ContainingChunk.Equals(currentChunk)) { currentChunk = point.ContainingChunk; } } if (nextLine.Points.Count > 0) { nextLine.Colour = Colour; nextLine.Width = Width; results.Add(nextLine); } // Set the ContinuesIn and ContinuesFrom properties // so that clients can find the next / previous chunk line fragmentss for (int i = 0; i < results.Count - 1; i++) { // Set the ContinuesFrom reference, but not on the first fragment in the list if (i > 0) { results[i].ContinuesFrom = results[i - 1].ContainingChunk; results[i].ContinuesFromId = results[i - 1].UniqueId; } // Set the ContinuesIn reference, but not on the last fragment in the list if (i < results.Count - 1) { results[i].ContinuesIn = results[i + 1].ContainingChunk; results[i].ContinuesWithId = results[i + 1].UniqueId; } } return(results); }