mirror of
https://github.com/cyanfish/naps2.git
synced 2024-10-04 19:37:15 +03:00
Generalize worker operations
This commit is contained in:
parent
66eb4f018f
commit
89795c946f
@ -64,20 +64,13 @@ namespace NAPS2.ImportExport.Pdf
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (UseWorker)
|
Status.Success = DoWork(new SavePdfWorkArgs
|
||||||
{
|
{
|
||||||
using (var worker = WorkerServiceFactory.Create())
|
SubFileName = subFileName,
|
||||||
{
|
Snapshots = snapshots.Export(),
|
||||||
worker.Service.SetRecoveryFolder(RecoveryImage.RecoveryFolder.FullName);
|
PdfSettings = pdfSettings,
|
||||||
worker.Callback.OnProgress += OnProgress;
|
OcrLanguageCode = ocrLanguageCode
|
||||||
worker.Service.ExportPdf(subFileName, snapshots.Export(), pdfSettings, ocrLanguageCode);
|
});
|
||||||
Status.Success = worker.Callback.WaitForFinish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Status.Success = pdfExporter.Export(subFileName, snapshots, pdfSettings, ocrLanguageCode, OnProgress);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (UnauthorizedAccessException ex)
|
catch (UnauthorizedAccessException ex)
|
||||||
{
|
{
|
||||||
@ -114,9 +107,24 @@ namespace NAPS2.ImportExport.Pdf
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected internal override bool DoWorkInternal(WorkArgs args)
|
||||||
|
{
|
||||||
|
var a = (SavePdfWorkArgs)args;
|
||||||
|
return pdfExporter.Export(a.SubFileName, a.Snapshots.Import(), a.PdfSettings, a.OcrLanguageCode, OnProgress);
|
||||||
|
}
|
||||||
|
|
||||||
public override void WaitUntilFinished()
|
public override void WaitUntilFinished()
|
||||||
{
|
{
|
||||||
thread.Join();
|
thread.Join();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
internal class SavePdfWorkArgs : WorkArgs
|
||||||
|
{
|
||||||
|
public string SubFileName { get; set; }
|
||||||
|
public List<ScannedImage.SnapshotExport> Snapshots { get; set; }
|
||||||
|
public PdfSettings PdfSettings { get; set; }
|
||||||
|
public string OcrLanguageCode { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5282,13 +5282,13 @@
|
|||||||
<Content Include="Icons\contrast_with_sun.ico" />
|
<Content Include="Icons\contrast_with_sun.ico" />
|
||||||
<Content Include="Icons\control_play_blue-small.png" />
|
<Content Include="Icons\control_play_blue-small.png" />
|
||||||
<Content Include="Icons\email.ico" />
|
<Content Include="Icons\email.ico" />
|
||||||
<None Include="Icons\email.png" />
|
|
||||||
<None Include="Icons\email_setting.png" />
|
<None Include="Icons\email_setting.png" />
|
||||||
<Content Include="Icons\file_extension_pdf.ico" />
|
<Content Include="Icons\file_extension_pdf.ico" />
|
||||||
<None Include="Icons\gmail.png" />
|
<None Include="Icons\gmail.png" />
|
||||||
<Content Include="Icons\image_edit.png" />
|
<Content Include="Icons\image_edit.png" />
|
||||||
<None Include="Icons\outlookweb.png" />
|
<None Include="Icons\outlookweb.png" />
|
||||||
<None Include="Icons\mail_yellow.png" />
|
<None Include="Icons\mail_yellow.png" />
|
||||||
|
<Content Include="Icons\key.ico" />
|
||||||
<Content Include="Icons\picture.ico" />
|
<Content Include="Icons\picture.ico" />
|
||||||
<Content Include="Icons\pictures.png" />
|
<Content Include="Icons\pictures.png" />
|
||||||
<Content Include="Icons\picture_edit.png" />
|
<Content Include="Icons\picture_edit.png" />
|
||||||
|
@ -46,8 +46,9 @@ namespace NAPS2.Operation
|
|||||||
Error?.Invoke(this, args);
|
Error?.Invoke(this, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool OnProgress(int current, int max)
|
protected virtual bool OnProgress(int current, int max)
|
||||||
{
|
{
|
||||||
|
// TODO: Maybe don't make this virtual. Instead, clone the status object, and project event invocations back to the client.
|
||||||
Status.CurrentProgress = current;
|
Status.CurrentProgress = current;
|
||||||
Status.MaxProgress = max;
|
Status.MaxProgress = max;
|
||||||
InvokeStatusChanged();
|
InvokeStatusChanged();
|
||||||
|
@ -1,19 +1,59 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using NAPS2.Recovery;
|
||||||
|
using NAPS2.Util;
|
||||||
using NAPS2.Worker;
|
using NAPS2.Worker;
|
||||||
|
|
||||||
namespace NAPS2.Operation
|
namespace NAPS2.Operation
|
||||||
{
|
{
|
||||||
public abstract class WorkerOperation : OperationBase
|
public abstract class WorkerOperation : OperationBase
|
||||||
{
|
{
|
||||||
|
private readonly IWorkerServiceFactory workerServiceFactory;
|
||||||
|
|
||||||
protected WorkerOperation(IWorkerServiceFactory workerServiceFactory)
|
protected WorkerOperation(IWorkerServiceFactory workerServiceFactory)
|
||||||
{
|
{
|
||||||
WorkerServiceFactory = workerServiceFactory;
|
this.workerServiceFactory = workerServiceFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool UseWorker => !Environment.Is64BitProcess;
|
protected virtual bool UseWorker => !Environment.Is64BitProcess;
|
||||||
|
|
||||||
protected IWorkerServiceFactory WorkerServiceFactory { get; }
|
public ProgressHandler ProgressProxy { get; set; }
|
||||||
|
|
||||||
|
protected bool DoWork(WorkArgs args)
|
||||||
|
{
|
||||||
|
if (UseWorker)
|
||||||
|
{
|
||||||
|
using (var worker = workerServiceFactory.Create())
|
||||||
|
{
|
||||||
|
worker.Service.SetRecoveryFolder(RecoveryImage.RecoveryFolder.FullName);
|
||||||
|
worker.Callback.OnProgress += OnProgress;
|
||||||
|
worker.Service.DoOperationWork(GetType().FullName, args);
|
||||||
|
return worker.Callback.WaitForFinish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DoWorkInternal(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected internal abstract bool DoWorkInternal(WorkArgs args);
|
||||||
|
|
||||||
|
protected override bool OnProgress(int current, int max)
|
||||||
|
{
|
||||||
|
return ProgressProxy?.Invoke(current, max) ?? base.OnProgress(current, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
[KnownType("DerivedTypes")]
|
||||||
|
[Serializable]
|
||||||
|
public class WorkArgs
|
||||||
|
{
|
||||||
|
// ReSharper disable once UnusedMember.Local
|
||||||
|
private static Type[] DerivedTypes()
|
||||||
|
{
|
||||||
|
return Assembly.GetExecutingAssembly().GetTypes().Where(x => x.IsSubclassOf(typeof(WorkArgs))).ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.ServiceModel;
|
using System.ServiceModel;
|
||||||
using NAPS2.ImportExport.Pdf;
|
using NAPS2.ImportExport.Pdf;
|
||||||
|
using NAPS2.Operation;
|
||||||
using NAPS2.Recovery;
|
using NAPS2.Recovery;
|
||||||
using NAPS2.Scan;
|
using NAPS2.Scan;
|
||||||
using NAPS2.Scan.Images;
|
using NAPS2.Scan.Images;
|
||||||
@ -25,6 +26,6 @@ namespace NAPS2.Worker
|
|||||||
List<RecoveryIndexImage> TwainScan(int recoveryFileNumber, ScanDevice scanDevice, ScanProfile scanProfile, ScanParams scanParams);
|
List<RecoveryIndexImage> TwainScan(int recoveryFileNumber, ScanDevice scanDevice, ScanProfile scanProfile, ScanParams scanParams);
|
||||||
|
|
||||||
[OperationContract(IsOneWay = true)]
|
[OperationContract(IsOneWay = true)]
|
||||||
void ExportPdf(string subFileName, List<ScannedImage.SnapshotExport> snapshots, PdfSettings pdfSettings, string ocrLanguageCode);
|
void DoOperationWork(string operationTypeName, WorkerOperation.WorkArgs args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,18 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.ServiceModel;
|
using System.ServiceModel;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using NAPS2.ImportExport.Pdf;
|
using NAPS2.ImportExport.Pdf;
|
||||||
|
using NAPS2.Operation;
|
||||||
using NAPS2.Recovery;
|
using NAPS2.Recovery;
|
||||||
using NAPS2.Scan;
|
using NAPS2.Scan;
|
||||||
using NAPS2.Scan.Images;
|
using NAPS2.Scan.Images;
|
||||||
using NAPS2.Scan.Images.Transforms;
|
using NAPS2.Scan.Images.Transforms;
|
||||||
using NAPS2.Scan.Twain;
|
using NAPS2.Scan.Twain;
|
||||||
|
using NAPS2.Util;
|
||||||
|
|
||||||
namespace NAPS2.Worker
|
namespace NAPS2.Worker
|
||||||
{
|
{
|
||||||
@ -21,13 +24,15 @@ namespace NAPS2.Worker
|
|||||||
{
|
{
|
||||||
private readonly TwainWrapper twainWrapper;
|
private readonly TwainWrapper twainWrapper;
|
||||||
private readonly IPdfExporter pdfExporter;
|
private readonly IPdfExporter pdfExporter;
|
||||||
|
private readonly IOperationFactory operationFactory;
|
||||||
|
|
||||||
public Form ParentForm { get; set; }
|
public Form ParentForm { get; set; }
|
||||||
|
|
||||||
public WorkerService(TwainWrapper twainWrapper, IPdfExporter pdfExporter)
|
public WorkerService(TwainWrapper twainWrapper, IPdfExporter pdfExporter, IOperationFactory operationFactory)
|
||||||
{
|
{
|
||||||
this.twainWrapper = twainWrapper;
|
this.twainWrapper = twainWrapper;
|
||||||
this.pdfExporter = pdfExporter;
|
this.pdfExporter = pdfExporter;
|
||||||
|
this.operationFactory = operationFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Init()
|
public void Init()
|
||||||
@ -56,22 +61,31 @@ namespace NAPS2.Worker
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ExportPdf(string subFileName, List<ScannedImage.SnapshotExport> snapshots, PdfSettings pdfSettings, string ocrLanguageCode)
|
public void DoOperationWork(string operationTypeName, WorkerOperation.WorkArgs args)
|
||||||
{
|
{
|
||||||
// TODO: Make a type for a serializable snapshot
|
// TODO: Make a type for a serializable snapshot
|
||||||
// TODO: Other operations. Import. Recovery. Save images. Password and ghostscript callbacks.
|
// TODO: Other operations. Import. Recovery. Save images. Password and ghostscript callbacks.
|
||||||
// Figure out ghostscript operation in general.
|
// Figure out ghostscript operation in general.
|
||||||
// Also - consider off-process thumbnail rendering. That's probably IO bound though, right?
|
// Also - consider off-process thumbnail rendering. That's probably IO bound though, right?
|
||||||
// So parellization doesn't help. The only benefit would be memory. Which is not a bad benefit.
|
// So parellization doesn't help. The only benefit would be memory. Which is not a bad benefit.
|
||||||
WrapOperation(() => pdfExporter.Export(subFileName, snapshots.Import(), pdfSettings, ocrLanguageCode, Callback.Progress));
|
var operationType = Type.GetType(operationTypeName);
|
||||||
|
if (operationType == null)
|
||||||
|
{
|
||||||
|
Log.Error($"Operation type not available: {operationTypeName}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var op = (WorkerOperation)typeof(IOperationFactory).GetMethod("Create")?.MakeGenericMethod(operationType).Invoke(operationFactory, new object[0]);
|
||||||
|
if (op == null)
|
||||||
|
{
|
||||||
|
Log.Error($"Could not create operation: {operationTypeName}");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WrapOperation(Func<bool> op)
|
|
||||||
{
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
success = op();
|
op.ProgressProxy = Callback.Progress;
|
||||||
|
success = op.DoWorkInternal(args);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user