comparison data/fileio/CSVStreamWriter.h @ 1441:51493540a753 streaming-csv-writer

Fix progress reporting and allow for changing how progress is calculating (TODO multi-selection)
author Lucas Thompson <dev@lucas.im>
date Tue, 17 Apr 2018 10:03:50 +0100
parents 09c2ba31a711
children 4507be815384
comparison
equal deleted inserted replaced
1440:04caefd35391 1441:51493540a753
22 #include "base/DataExportOptions.h" 22 #include "base/DataExportOptions.h"
23 #include "data/model/Model.h" 23 #include "data/model/Model.h"
24 #include <QString> 24 #include <QString>
25 #include <algorithm> 25 #include <algorithm>
26 26
27 namespace
28 {
29 const auto initProgressCalculator = [](sv_frame_t nFramesToWrite) {
30 return [nFramesToWrite](sv_frame_t nFramesWritten) {
31 return 100 * nFramesWritten / nFramesToWrite;
32 };
33 };
34 } // namespace
35
27 namespace CSVStreamWriter 36 namespace CSVStreamWriter
28 { 37 {
29 38
30 template <class OutStream> 39 template <
31 bool writeInChunks(OutStream& oss, 40 class OutStream,
32 const Model& model, 41 class ProgressCalculatorInit = decltype(initProgressCalculator)
33 const Selection& extents, 42 >
34 ProgressReporter* reporter = nullptr, 43 bool
35 QString delimiter = ",", 44 writeInChunks(OutStream& oss,
36 DataExportOptions options = DataExportDefaults, 45 const Model& model,
37 const sv_frame_t blockSize = 16384) 46 const Selection& extents,
47 ProgressReporter* reporter = nullptr,
48 QString delimiter = ",",
49 DataExportOptions options = DataExportDefaults,
50 const sv_frame_t blockSize = 16384,
51 const ProgressCalculatorInit& initCalc = initProgressCalculator)
38 { 52 {
39 if (blockSize <= 0) return false; 53 if (blockSize <= 0) return false;
40 sv_frame_t readPtr = extents.isEmpty() ? 54 const auto startFrame = extents.isEmpty() ?
41 model.getStartFrame() : extents.getStartFrame(); 55 model.getStartFrame() : extents.getStartFrame();
42 sv_frame_t endFrame = extents.isEmpty() ? 56 const auto endFrame = extents.isEmpty() ?
43 model.getEndFrame() : extents.getEndFrame(); 57 model.getEndFrame() : extents.getEndFrame();
58 const auto hasValidExtents = startFrame >= 0 && endFrame > startFrame;
59 if (!hasValidExtents) return false;
60 const auto calculateProgress = initCalc(endFrame - startFrame);
61
62 auto readPtr = startFrame;
44 int previousPercentagePoint = 0; 63 int previousPercentagePoint = 0;
45 64
46 const auto wasCancelled = [&reporter]() { 65 const auto wasCancelled = [&reporter]() {
47 return reporter && reporter->wasCancelled(); 66 return reporter && reporter->wasCancelled();
48 }; 67 };
57 delimiter, 76 delimiter,
58 options, 77 options,
59 start, 78 start,
60 end 79 end
61 ) << (end < endFrame ? "\n" : ""); 80 ) << (end < endFrame ? "\n" : "");
62 81 const auto nFramesWritten = end - startFrame;
63 const auto currentPercentage = 100 * end / endFrame; 82 const auto currentPercentage = calculateProgress(nFramesWritten);
64 const bool hasIncreased = currentPercentage > previousPercentagePoint; 83 const bool hasIncreased = currentPercentage > previousPercentagePoint;
65 84
66 if (hasIncreased) { 85 if (hasIncreased) {
67 if (reporter) reporter->setProgress(currentPercentage); 86 if (reporter) reporter->setProgress(currentPercentage);
68 previousPercentagePoint = currentPercentage; 87 previousPercentagePoint = currentPercentage;
71 } 90 }
72 return !wasCancelled(); // setProgress could process event loop 91 return !wasCancelled(); // setProgress could process event loop
73 } 92 }
74 93
75 template <class OutStream> 94 template <class OutStream>
76 bool writeInChunks(OutStream& oss, 95 bool
77 const Model& model, 96 writeInChunks(OutStream& oss,
78 ProgressReporter* reporter = nullptr, 97 const Model& model,
79 QString delimiter = ",", 98 ProgressReporter* reporter = nullptr,
80 DataExportOptions options = DataExportDefaults, 99 QString delimiter = ",",
81 const sv_frame_t blockSize = 16384) 100 DataExportOptions options = DataExportDefaults,
101 const sv_frame_t blockSize = 16384)
82 { 102 {
83 const Selection empty; 103 const Selection empty;
84 return CSV::writeInChunks( 104 return CSV::writeInChunks(
85 oss, 105 oss,
86 model, 106 model,