2017-01-06 18:57:58 +00:00
|
|
|
|
using System;
|
2017-01-07 20:19:21 +00:00
|
|
|
|
using System.Collections.Generic;
|
2017-01-08 14:45:48 +00:00
|
|
|
|
using System.Linq;
|
2017-07-29 12:20:12 +00:00
|
|
|
|
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
|
2017-01-06 18:57:58 +00:00
|
|
|
|
namespace Nibriboard.RippleSpace
|
|
|
|
|
{
|
2017-01-06 19:05:27 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Represents a line drawn across the plane.
|
|
|
|
|
/// </summary>
|
2017-07-29 12:20:12 +00:00
|
|
|
|
[Serializable]
|
|
|
|
|
[JsonObject(MemberSerialization.OptIn)]
|
2017-01-06 18:57:58 +00:00
|
|
|
|
public class DrawnLine
|
|
|
|
|
{
|
2017-01-08 14:45:48 +00:00
|
|
|
|
/// <summary>
|
2017-09-28 21:07:26 +00:00
|
|
|
|
/// This line (fragment?)'s unique id. Should be globally unique - please blow up
|
|
|
|
|
/// if it isn't!
|
|
|
|
|
/// </summary>
|
|
|
|
|
[JsonProperty]
|
|
|
|
|
public readonly string UniqueId = NCuid.Cuid.Generate();
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The id of line that this <see cref="DrawnLine" /> is part of.
|
2017-01-08 14:45:48 +00:00
|
|
|
|
/// Note that this id may not be unique - several lines that were all
|
|
|
|
|
/// drawn at once may also have the same id. This is such that a single
|
2017-07-29 12:20:12 +00:00
|
|
|
|
/// line that was split across multiple chunks can still be referenced and
|
|
|
|
|
/// joined together.
|
2017-01-08 14:45:48 +00:00
|
|
|
|
/// </summary>
|
2017-07-29 12:20:12 +00:00
|
|
|
|
[JsonProperty]
|
2017-04-23 16:11:46 +00:00
|
|
|
|
public readonly string LineId;
|
2017-01-08 14:45:48 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The width of the line.
|
|
|
|
|
/// </summary>
|
2017-07-29 12:20:12 +00:00
|
|
|
|
[JsonProperty]
|
2017-04-28 17:14:14 +00:00
|
|
|
|
public int Width;
|
2017-01-08 14:45:48 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The colour of the line.
|
|
|
|
|
/// </summary>
|
2017-07-29 12:20:12 +00:00
|
|
|
|
[JsonProperty]
|
2017-01-08 14:45:48 +00:00
|
|
|
|
public string Colour;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The points that represent the line.
|
|
|
|
|
/// </summary>
|
2017-07-29 12:20:12 +00:00
|
|
|
|
[JsonProperty]
|
2017-01-07 20:19:21 +00:00
|
|
|
|
public List<LocationReference> Points = new List<LocationReference>();
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Whether this line spans multiple chunks.
|
|
|
|
|
/// </summary>
|
2017-07-29 12:20:12 +00:00
|
|
|
|
[JsonProperty]
|
2017-01-07 20:19:21 +00:00
|
|
|
|
public bool SpansMultipleChunks {
|
|
|
|
|
get {
|
|
|
|
|
// TODO: Make this more intelligent such that connecting lines
|
|
|
|
|
// can be stored that connect lines that span multiple chunks
|
|
|
|
|
if (Points.Count == 0)
|
|
|
|
|
return false;
|
|
|
|
|
ChunkReference containingChunk = Points[0].ContainingChunk;
|
|
|
|
|
foreach(LocationReference point in Points)
|
|
|
|
|
{
|
2017-04-28 21:25:55 +00:00
|
|
|
|
if (!point.ContainingChunk.Equals(containingChunk))
|
2017-01-07 20:19:21 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-22 21:35:56 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The chunk reference of the next chunk that this line continues in.
|
|
|
|
|
/// A value of null is present when this line doesn't continue into another chunk.
|
|
|
|
|
/// </summary>
|
|
|
|
|
[JsonProperty]
|
|
|
|
|
public ChunkReference ContinuesIn = null;
|
2017-09-29 14:42:14 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The id of the line that this line fragment is continued by.
|
|
|
|
|
/// </summary>
|
|
|
|
|
[JsonProperty]
|
|
|
|
|
public string ContinuesWithId = null;
|
2017-09-22 21:35:56 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The chunk reference of the previous chunk that contains the line fragment that
|
|
|
|
|
/// this line continues from. Is null when this line either doesn't continue from
|
|
|
|
|
/// another line fragment or doesn't span multiple chunks.
|
|
|
|
|
/// </summary>
|
|
|
|
|
[JsonProperty]
|
|
|
|
|
public ChunkReference ContinuesFrom = null;
|
2017-09-29 14:42:14 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The id of the line fragment that this line continues from.
|
|
|
|
|
/// </summary>
|
|
|
|
|
[JsonProperty]
|
|
|
|
|
public string ContinuesFromId = null;
|
2017-09-22 21:35:56 +00:00
|
|
|
|
|
2017-01-07 20:19:21 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets a reference in chunk-space ot the chunk that this line starts in.
|
2017-09-29 14:42:14 +00:00
|
|
|
|
/// </summary>
|
|
|
|
|
[JsonProperty]
|
2017-01-07 20:19:21 +00:00
|
|
|
|
public ChunkReference ContainingChunk {
|
|
|
|
|
get {
|
|
|
|
|
if (Points.Count == 0)
|
|
|
|
|
throw new InvalidOperationException("Error: This line doesn't contain any points yet!");
|
|
|
|
|
return Points[0].ContainingChunk;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-23 16:11:46 +00:00
|
|
|
|
public DrawnLine() : this(Guid.NewGuid().ToString("N"))
|
2017-01-08 14:45:48 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
2017-06-27 11:03:21 +00:00
|
|
|
|
public DrawnLine(string inLineId)
|
2017-01-08 14:45:48 +00:00
|
|
|
|
{
|
|
|
|
|
LineId = inLineId;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-28 21:25:55 +00:00
|
|
|
|
/// <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()
|
2017-01-06 18:57:58 +00:00
|
|
|
|
{
|
2017-01-08 14:45:48 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-29 11:56:32 +00:00
|
|
|
|
DrawnLine nextLine = new DrawnLine(LineId);
|
2017-01-08 14:45:48 +00:00
|
|
|
|
ChunkReference currentChunk = null;
|
|
|
|
|
foreach(LocationReference point in Points)
|
|
|
|
|
{
|
2017-04-28 21:25:55 +00:00
|
|
|
|
if(currentChunk != null && !point.ContainingChunk.Equals(currentChunk))
|
2017-01-08 14:45:48 +00:00
|
|
|
|
{
|
2017-05-29 11:56:32 +00:00
|
|
|
|
// 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;
|
2017-07-29 15:21:15 +00:00
|
|
|
|
if(nextLine.Points.Count > 0)
|
|
|
|
|
results.Add(nextLine);
|
2017-01-08 14:45:48 +00:00
|
|
|
|
nextLine = new DrawnLine(LineId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nextLine.Points.Add(point);
|
2017-04-28 21:25:55 +00:00
|
|
|
|
if(!point.ContainingChunk.Equals(currentChunk))
|
|
|
|
|
currentChunk = point.ContainingChunk;
|
2017-01-08 14:45:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-04-28 21:25:55 +00:00
|
|
|
|
if(nextLine.Points.Count > 0)
|
2017-05-29 11:56:32 +00:00
|
|
|
|
{
|
|
|
|
|
nextLine.Colour = Colour;
|
|
|
|
|
nextLine.Width = Width;
|
2017-04-28 21:25:55 +00:00
|
|
|
|
results.Add(nextLine);
|
2017-05-29 11:56:32 +00:00
|
|
|
|
}
|
2017-04-28 21:25:55 +00:00
|
|
|
|
|
2017-09-22 21:35:56 +00:00
|
|
|
|
// 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
|
2017-09-29 14:42:14 +00:00
|
|
|
|
if(i > 0) {
|
2017-09-22 21:35:56 +00:00
|
|
|
|
results[i].ContinuesFrom = results[i - 1].ContainingChunk;
|
2017-09-29 14:42:14 +00:00
|
|
|
|
results[i].ContinuesFromId = results[i - 1].UniqueId;
|
|
|
|
|
}
|
2017-09-22 21:35:56 +00:00
|
|
|
|
|
|
|
|
|
// Set the ContinuesIn reference, but not on the last fragment in the list
|
2017-09-29 14:42:14 +00:00
|
|
|
|
if(i < results.Count - 1) {
|
2017-09-22 21:35:56 +00:00
|
|
|
|
results[i].ContinuesIn = results[i + 1].ContainingChunk;
|
2017-09-29 14:42:14 +00:00
|
|
|
|
results[i].ContinuesWithId = results[i + 1].UniqueId;
|
|
|
|
|
}
|
2017-09-22 21:35:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-01-08 14:45:48 +00:00
|
|
|
|
return results;
|
2017-01-06 18:57:58 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|