Optimize session loading

This commit is contained in:
Ben Olden-Cooligan 2024-01-14 22:34:14 -08:00
parent 3588a920d0
commit f83aae50be
6 changed files with 51 additions and 12 deletions

View File

@ -306,13 +306,10 @@ public class DesktopController
AutoSessionRestore = _config.Get(c => c.KeepSession),
ThumbnailSize = _thumbnailController.RenderSize
};
if (op.Start(_desktopImagesController.ReceiveScannedImage(), recoveryParams))
if (op.Start(_desktopImagesController.ReceiveScannedImage(), _desktopImagesController.AppendImageBatch,
recoveryParams))
{
if (recoveryParams.AutoSessionRestore)
{
_operationProgress.ShowBackgroundProgress(op);
}
else
if (!recoveryParams.AutoSessionRestore)
{
_operationProgress.ShowProgress(op);
}

View File

@ -28,4 +28,11 @@ public class DesktopImagesController
}
};
}
public void AppendImageBatch(IEnumerable<ProcessedImage> images)
{
_imageList.Mutate(
new ImageListMutation.Append(images.Select(image => new UiImage(image))),
isPassiveInteraction: true);
}
}

View File

@ -56,6 +56,18 @@ public abstract class OperationBase : IOperation
StartTask(() => Task.FromResult(action()));
}
protected void RunSync(Func<bool> action)
{
try
{
_tcs.TrySetResult(action());
}
catch (Exception ex)
{
_tcs.TrySetException(ex);
}
}
private void StartTask(Func<Task<bool>> action)
{
Task.Run(async () =>

View File

@ -102,8 +102,8 @@ public class RecoverableFolder : IDisposable
}
}
public bool TryRecover(Action<ProcessedImage> imageCallback, RecoveryParams recoveryParams,
ProgressHandler progress)
public bool TryRecover(Action<ProcessedImage> imageCallback, Action<IEnumerable<ProcessedImage>> imageBatchCallback,
RecoveryParams recoveryParams, ProgressHandler progress)
{
if (_disposed) throw new ObjectDisposedException(nameof(RecoverableFolder));
@ -111,6 +111,8 @@ public class RecoverableFolder : IDisposable
int totalProgress = ImageCount;
progress.Report(currentProgress, totalProgress);
var recoveredImages = new List<ProcessedImage>();
foreach (RecoveryIndexImage indexImage in _recoveryIndex.Images)
{
if (progress.IsCancellationRequested)
@ -145,11 +147,22 @@ public class RecoverableFolder : IDisposable
var storage = new ImageFileStorage(newPath);
var recoveredImage = CreateRecoveredImage(recoveryParams, storage, indexImage);
imageCallback(recoveredImage);
if (!recoveryParams.AutoSessionRestore)
{
imageCallback(recoveredImage);
}
else
{
recoveredImages.Add(recoveredImage);
}
currentProgress++;
progress.Report(currentProgress, totalProgress);
}
if (recoveryParams.AutoSessionRestore)
{
imageBatchCallback(recoveredImages);
}
// Now that we've recovered successfully, we can safely delete the old folder
TryDelete();
return true;

View File

@ -18,7 +18,8 @@ internal class RecoveryOperation : OperationBase
AllowBackground = true;
}
public bool Start(Action<ProcessedImage> imageCallback, RecoveryParams recoveryParams)
public bool Start(Action<ProcessedImage> imageCallback, Action<IEnumerable<ProcessedImage>> imageBatchCallback,
RecoveryParams recoveryParams)
{
Status = new OperationStatus
{
@ -35,11 +36,13 @@ internal class RecoveryOperation : OperationBase
switch (recoveryParams.AutoSessionRestore ? RecoverAction.Recover : PromptToRecover(recoverableFolder))
{
case RecoverAction.Recover:
RunAsync(() =>
Action<Func<bool>> runFunc = recoveryParams.AutoSessionRestore ? RunSync : RunAsync;
runFunc(() =>
{
try
{
return recoverableFolder.TryRecover(imageCallback, recoveryParams, ProgressHandler);
return recoverableFolder.TryRecover(imageCallback, imageBatchCallback, recoveryParams,
ProgressHandler);
}
finally
{

View File

@ -2,6 +2,13 @@
public class RecoveryParams
{
// In case the user has the "Keep images across sessions" option, we want to make the recovery operation feel more
// seamless. This means a few things:
// - Image files are moved instead of copied. This is destructive (higher risk of data loss) but fast.
// - Thumbnails rendering is deferred.
// - No operation progress is displayed.
// - The operation is run synchronously (with only moving files + no thumbnail rendering it should be trivially fast).
// - Images are sent back to the UI as a single batch (speeds up UI rendering).
public bool AutoSessionRestore { get; set; }
public int? ThumbnailSize { get; set; }