changeset 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 04caefd35391
children 3c3eedc2fad8
files data/fileio/CSVStreamWriter.h
diffstat 1 files changed, 38 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/data/fileio/CSVStreamWriter.h	Tue Apr 17 10:03:50 2018 +0100
+++ b/data/fileio/CSVStreamWriter.h	Tue Apr 17 10:03:50 2018 +0100
@@ -24,23 +24,42 @@
 #include <QString>
 #include <algorithm>
 
+namespace 
+{
+    const auto initProgressCalculator = [](sv_frame_t nFramesToWrite) {
+        return [nFramesToWrite](sv_frame_t nFramesWritten) {
+            return 100 * nFramesWritten / nFramesToWrite;
+        };
+    };
+} // namespace
+
 namespace CSVStreamWriter
 {
 
-template <class OutStream>
-bool writeInChunks(OutStream& oss,
-                   const Model& model,
-                   const Selection& extents,
-                   ProgressReporter* reporter = nullptr,
-                   QString delimiter = ",",
-                   DataExportOptions options = DataExportDefaults,
-                   const sv_frame_t blockSize = 16384)
+template <
+    class OutStream,
+    class ProgressCalculatorInit = decltype(initProgressCalculator)
+>
+bool 
+writeInChunks(OutStream& oss,
+              const Model& model,
+              const Selection& extents,
+              ProgressReporter* reporter = nullptr,
+              QString delimiter = ",",
+              DataExportOptions options = DataExportDefaults,
+              const sv_frame_t blockSize = 16384,
+              const ProgressCalculatorInit& initCalc = initProgressCalculator)
 {
     if (blockSize <= 0) return false;
-    sv_frame_t readPtr = extents.isEmpty() ?
+    const auto startFrame = extents.isEmpty() ?
         model.getStartFrame() : extents.getStartFrame();
-    sv_frame_t endFrame = extents.isEmpty() ?
+    const auto endFrame = extents.isEmpty() ?
         model.getEndFrame() : extents.getEndFrame();
+    const auto hasValidExtents = startFrame >= 0 && endFrame > startFrame;
+    if (!hasValidExtents) return false;
+    const auto calculateProgress = initCalc(endFrame - startFrame);
+
+    auto readPtr = startFrame;
     int previousPercentagePoint = 0;
 
     const auto wasCancelled = [&reporter]() { 
@@ -59,8 +78,8 @@
             start,
             end
         ) << (end < endFrame ? "\n" : "");
-
-        const auto currentPercentage = 100 * end / endFrame;
+        const auto nFramesWritten = end - startFrame;
+        const auto currentPercentage = calculateProgress(nFramesWritten);
         const bool hasIncreased = currentPercentage > previousPercentagePoint;
 
         if (hasIncreased) {
@@ -73,12 +92,13 @@
 }
 
 template <class OutStream>
-bool writeInChunks(OutStream& oss,
-                   const Model& model,
-                   ProgressReporter* reporter = nullptr,
-                   QString delimiter = ",",
-                   DataExportOptions options = DataExportDefaults,
-                   const sv_frame_t blockSize = 16384)
+bool 
+writeInChunks(OutStream& oss,
+              const Model& model,
+              ProgressReporter* reporter = nullptr,
+              QString delimiter = ",",
+              DataExportOptions options = DataExportDefaults,
+              const sv_frame_t blockSize = 16384)
 {
     const Selection empty;
     return CSV::writeInChunks(