|
@@ -19,18 +19,18 @@ namespace ChunkyImageLib
|
|
private static SKPaint ClippingPaint { get; } = new SKPaint() { BlendMode = SKBlendMode.DstIn };
|
|
private static SKPaint ClippingPaint { get; } = new SKPaint() { BlendMode = SKBlendMode.DstIn };
|
|
private Chunk tempChunk;
|
|
private Chunk tempChunk;
|
|
|
|
|
|
- public Vector2i CommitedSize { get; private set; }
|
|
|
|
|
|
+ public Vector2i CommittedSize { get; private set; }
|
|
public Vector2i LatestSize { get; private set; }
|
|
public Vector2i LatestSize { get; private set; }
|
|
|
|
|
|
private List<(IOperation operation, HashSet<Vector2i> affectedChunks)> queuedOperations = new();
|
|
private List<(IOperation operation, HashSet<Vector2i> affectedChunks)> queuedOperations = new();
|
|
|
|
|
|
- private Dictionary<Vector2i, Chunk> commitedChunks = new();
|
|
|
|
|
|
+ private Dictionary<Vector2i, Chunk> committedChunks = new();
|
|
private Dictionary<Vector2i, Chunk> latestChunks = new();
|
|
private Dictionary<Vector2i, Chunk> latestChunks = new();
|
|
private Dictionary<Vector2i, LatestChunkData> latestChunksData = new();
|
|
private Dictionary<Vector2i, LatestChunkData> latestChunksData = new();
|
|
|
|
|
|
public ChunkyImage(Vector2i size)
|
|
public ChunkyImage(Vector2i size)
|
|
{
|
|
{
|
|
- CommitedSize = size;
|
|
|
|
|
|
+ CommittedSize = size;
|
|
LatestSize = size;
|
|
LatestSize = size;
|
|
tempChunk = Chunk.Create();
|
|
tempChunk = Chunk.Create();
|
|
}
|
|
}
|
|
@@ -50,22 +50,22 @@ namespace ChunkyImageLib
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// Returns the latest version of the chunk, with uncommited changes applied if they exist
|
|
|
|
|
|
+ /// Returns the latest version of the chunk, with uncommitted changes applied if they exist
|
|
/// </summary>
|
|
/// </summary>
|
|
public Chunk? GetLatestChunk(Vector2i pos)
|
|
public Chunk? GetLatestChunk(Vector2i pos)
|
|
{
|
|
{
|
|
if (queuedOperations.Count == 0)
|
|
if (queuedOperations.Count == 0)
|
|
- return MaybeGetChunk(pos, commitedChunks);
|
|
|
|
|
|
+ return MaybeGetChunk(pos, committedChunks);
|
|
ProcessQueueForChunk(pos);
|
|
ProcessQueueForChunk(pos);
|
|
- return MaybeGetChunk(pos, latestChunks) ?? MaybeGetChunk(pos, commitedChunks);
|
|
|
|
|
|
+ return MaybeGetChunk(pos, latestChunks) ?? MaybeGetChunk(pos, committedChunks);
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// Returns the commited version of the chunk ignoring any uncommited changes
|
|
|
|
|
|
+ /// Returns the committed version of the chunk ignoring any uncommitted changes
|
|
/// </summary>
|
|
/// </summary>
|
|
- internal Chunk? GetCommitedChunk(Vector2i pos)
|
|
|
|
|
|
+ internal Chunk? GetCommittedChunk(Vector2i pos)
|
|
{
|
|
{
|
|
- return MaybeGetChunk(pos, commitedChunks);
|
|
|
|
|
|
+ return MaybeGetChunk(pos, committedChunks);
|
|
}
|
|
}
|
|
|
|
|
|
private Chunk? MaybeGetChunk(Vector2i pos, Dictionary<Vector2i, Chunk> from) => from.ContainsKey(pos) ? from[pos] : null;
|
|
private Chunk? MaybeGetChunk(Vector2i pos, Dictionary<Vector2i, Chunk> from) => from.ContainsKey(pos) ? from[pos] : null;
|
|
@@ -129,7 +129,7 @@ namespace ChunkyImageLib
|
|
{
|
|
{
|
|
chunk.Dispose();
|
|
chunk.Dispose();
|
|
}
|
|
}
|
|
- LatestSize = CommitedSize;
|
|
|
|
|
|
+ LatestSize = CommittedSize;
|
|
latestChunks.Clear();
|
|
latestChunks.Clear();
|
|
latestChunksData.Clear();
|
|
latestChunksData.Clear();
|
|
}
|
|
}
|
|
@@ -146,16 +146,16 @@ namespace ChunkyImageLib
|
|
operation.Dispose();
|
|
operation.Dispose();
|
|
}
|
|
}
|
|
CommitLatestChunks();
|
|
CommitLatestChunks();
|
|
- CommitedSize = LatestSize;
|
|
|
|
|
|
+ CommittedSize = LatestSize;
|
|
queuedOperations.Clear();
|
|
queuedOperations.Clear();
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// Returns all chunks that have something in them, including latest (uncommited) ones
|
|
|
|
|
|
+ /// Returns all chunks that have something in them, including latest (uncommitted) ones
|
|
/// </summary>
|
|
/// </summary>
|
|
public HashSet<Vector2i> FindAllChunks()
|
|
public HashSet<Vector2i> FindAllChunks()
|
|
{
|
|
{
|
|
- var allChunks = commitedChunks.Select(chunk => chunk.Key).ToHashSet();
|
|
|
|
|
|
+ var allChunks = committedChunks.Select(chunk => chunk.Key).ToHashSet();
|
|
allChunks.UnionWith(latestChunks.Select(chunk => chunk.Key).ToHashSet());
|
|
allChunks.UnionWith(latestChunks.Select(chunk => chunk.Key).ToHashSet());
|
|
foreach (var (operation, opChunks) in queuedOperations)
|
|
foreach (var (operation, opChunks) in queuedOperations)
|
|
{
|
|
{
|
|
@@ -165,7 +165,7 @@ namespace ChunkyImageLib
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// Returns chunks affected by operations that haven't been commited yet
|
|
|
|
|
|
+ /// Returns chunks affected by operations that haven't been committed yet
|
|
/// </summary>
|
|
/// </summary>
|
|
public HashSet<Vector2i> FindAffectedChunks()
|
|
public HashSet<Vector2i> FindAffectedChunks()
|
|
{
|
|
{
|
|
@@ -185,14 +185,14 @@ namespace ChunkyImageLib
|
|
if (data.QueueProgress != queuedOperations.Count)
|
|
if (data.QueueProgress != queuedOperations.Count)
|
|
throw new Exception("Trying to commit chunk that wasn't fully processed");
|
|
throw new Exception("Trying to commit chunk that wasn't fully processed");
|
|
|
|
|
|
- if (commitedChunks.ContainsKey(pos))
|
|
|
|
|
|
+ if (committedChunks.ContainsKey(pos))
|
|
{
|
|
{
|
|
- var oldChunk = commitedChunks[pos];
|
|
|
|
- commitedChunks.Remove(pos);
|
|
|
|
|
|
+ var oldChunk = committedChunks[pos];
|
|
|
|
+ committedChunks.Remove(pos);
|
|
oldChunk.Dispose();
|
|
oldChunk.Dispose();
|
|
}
|
|
}
|
|
if (!data.IsDeleted)
|
|
if (!data.IsDeleted)
|
|
- commitedChunks.Add(pos, chunk);
|
|
|
|
|
|
+ committedChunks.Add(pos, chunk);
|
|
else
|
|
else
|
|
chunk.Dispose();
|
|
chunk.Dispose();
|
|
}
|
|
}
|
|
@@ -205,7 +205,7 @@ namespace ChunkyImageLib
|
|
{
|
|
{
|
|
Chunk? targetChunk = null;
|
|
Chunk? targetChunk = null;
|
|
if (latestChunksData.TryGetValue(chunkPos, out LatestChunkData chunkData))
|
|
if (latestChunksData.TryGetValue(chunkPos, out LatestChunkData chunkData))
|
|
- chunkData = new() { QueueProgress = 0, IsDeleted = !commitedChunks.ContainsKey(chunkPos) };
|
|
|
|
|
|
+ chunkData = new() { QueueProgress = 0, IsDeleted = !committedChunks.ContainsKey(chunkPos) };
|
|
|
|
|
|
if (chunkData.QueueProgress == queuedOperations.Count)
|
|
if (chunkData.QueueProgress == queuedOperations.Count)
|
|
return;
|
|
return;
|
|
@@ -218,7 +218,7 @@ namespace ChunkyImageLib
|
|
var (operation, operChunks) = queuedOperations[i];
|
|
var (operation, operChunks) = queuedOperations[i];
|
|
if (operation is RasterClipOperation clipOperation)
|
|
if (operation is RasterClipOperation clipOperation)
|
|
{
|
|
{
|
|
- var chunk = clipOperation.ClippingMask.GetCommitedChunk(chunkPos);
|
|
|
|
|
|
+ var chunk = clipOperation.ClippingMask.GetCommittedChunk(chunkPos);
|
|
if (chunk != null)
|
|
if (chunk != null)
|
|
activeClips.Add(chunk);
|
|
activeClips.Add(chunk);
|
|
else
|
|
else
|
|
@@ -285,10 +285,10 @@ namespace ChunkyImageLib
|
|
return chunkData.IsDeleted;
|
|
return chunkData.IsDeleted;
|
|
}
|
|
}
|
|
|
|
|
|
- public bool CheckIfCommitedIsEmpty()
|
|
|
|
|
|
+ public bool CheckIfCommittedIsEmpty()
|
|
{
|
|
{
|
|
- FindAndDeleteEmptyCommitedChunks();
|
|
|
|
- return commitedChunks.Count == 0;
|
|
|
|
|
|
+ FindAndDeleteEmptyCommittedChunks();
|
|
|
|
+ return committedChunks.Count == 0;
|
|
}
|
|
}
|
|
|
|
|
|
private HashSet<Vector2i> FindAllChunksOutsideBounds(Vector2i size)
|
|
private HashSet<Vector2i> FindAllChunksOutsideBounds(Vector2i size)
|
|
@@ -303,12 +303,12 @@ namespace ChunkyImageLib
|
|
return chunkPos.X < 0 || chunkPos.Y < 0 || chunkPos.X * ChunkSize >= imageSize.X || chunkPos.Y * ChunkSize >= imageSize.Y;
|
|
return chunkPos.X < 0 || chunkPos.Y < 0 || chunkPos.X * ChunkSize >= imageSize.X || chunkPos.Y * ChunkSize >= imageSize.Y;
|
|
}
|
|
}
|
|
|
|
|
|
- private void FindAndDeleteEmptyCommitedChunks()
|
|
|
|
|
|
+ private void FindAndDeleteEmptyCommittedChunks()
|
|
{
|
|
{
|
|
if (queuedOperations.Count != 0)
|
|
if (queuedOperations.Count != 0)
|
|
throw new Exception("This method cannot be used while any operations are queued");
|
|
throw new Exception("This method cannot be used while any operations are queued");
|
|
HashSet<Vector2i> toRemove = new();
|
|
HashSet<Vector2i> toRemove = new();
|
|
- foreach (var (pos, chunk) in commitedChunks)
|
|
|
|
|
|
+ foreach (var (pos, chunk) in committedChunks)
|
|
{
|
|
{
|
|
if (IsChunkEmpty(chunk))
|
|
if (IsChunkEmpty(chunk))
|
|
{
|
|
{
|
|
@@ -317,7 +317,7 @@ namespace ChunkyImageLib
|
|
}
|
|
}
|
|
}
|
|
}
|
|
foreach (var pos in toRemove)
|
|
foreach (var pos in toRemove)
|
|
- commitedChunks.Remove(pos);
|
|
|
|
|
|
+ committedChunks.Remove(pos);
|
|
}
|
|
}
|
|
|
|
|
|
private unsafe bool IsChunkEmpty(Chunk chunk)
|
|
private unsafe bool IsChunkEmpty(Chunk chunk)
|
|
@@ -340,10 +340,10 @@ namespace ChunkyImageLib
|
|
if (targetChunk == null)
|
|
if (targetChunk == null)
|
|
{
|
|
{
|
|
targetChunk = Chunk.Create();
|
|
targetChunk = Chunk.Create();
|
|
- var maybeCommitedChunk = MaybeGetChunk(chunkPos, commitedChunks);
|
|
|
|
|
|
+ var maybeCommittedChunk = MaybeGetChunk(chunkPos, committedChunks);
|
|
|
|
|
|
- if (maybeCommitedChunk != null)
|
|
|
|
- maybeCommitedChunk.Surface.CopyTo(targetChunk.Surface);
|
|
|
|
|
|
+ if (maybeCommittedChunk != null)
|
|
|
|
+ maybeCommittedChunk.Surface.CopyTo(targetChunk.Surface);
|
|
else
|
|
else
|
|
targetChunk.Surface.SkiaSurface.Canvas.Clear();
|
|
targetChunk.Surface.SkiaSurface.Canvas.Clear();
|
|
|
|
|
|
@@ -358,7 +358,7 @@ namespace ChunkyImageLib
|
|
return;
|
|
return;
|
|
CancelChanges();
|
|
CancelChanges();
|
|
tempChunk.Dispose();
|
|
tempChunk.Dispose();
|
|
- foreach (var chunk in commitedChunks)
|
|
|
|
|
|
+ foreach (var chunk in committedChunks)
|
|
chunk.Value.Dispose();
|
|
chunk.Value.Dispose();
|
|
disposed = true;
|
|
disposed = true;
|
|
}
|
|
}
|