From 6a1d181a34b1bd7130be4150bd273d33d3be67af Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 3 Sep 2022 13:24:51 +0200 Subject: [PATCH] Add progress information. --- lib/logger.cc | 21 ++++++- lib/logger.h | 35 +++++++++--- lib/readerwriter.cc | 113 ++++++++++++++++++++++++------------- src/gui/customstatusbar.cc | 5 ++ src/gui/customstatusbar.h | 1 + src/gui/mainwindow.cc | 22 ++++++++ 6 files changed, 148 insertions(+), 49 deletions(-) diff --git a/lib/logger.cc b/lib/logger.cc index 108a41f4..bdfa2173 100644 --- a/lib/logger.cc +++ b/lib/logger.cc @@ -83,8 +83,10 @@ std::string Logger::toString(const AnyLogMessage& message) std::set> rawRecords; for (const auto& trackDataFlux : track.trackDatas) { - rawSectors.insert(trackDataFlux->sectors.begin(), trackDataFlux->sectors.end()); - rawRecords.insert(trackDataFlux->records.begin(), trackDataFlux->records.end()); + rawSectors.insert(trackDataFlux->sectors.begin(), + trackDataFlux->sectors.end()); + rawRecords.insert(trackDataFlux->records.begin(), + trackDataFlux->records.end()); } nanoseconds_t clock = 0; @@ -136,6 +138,21 @@ std::string Logger::toString(const AnyLogMessage& message) stream << fmt::format("{} bytes decoded\n", size); }, + /* Large-scale operation start. */ + [&](const BeginOperationLogMessage& m) + { + }, + + /* Large-scale operation end. */ + [&](const EndOperationLogMessage& m) + { + }, + + /* Large-scale operation progress. */ + [&](const OperationProgressLogMessage& m) + { + }, + /* Generic text message */ [&](const std::string& s) { diff --git a/lib/logger.h b/lib/logger.h index cbd1d75a..c2921b87 100644 --- a/lib/logger.h +++ b/lib/logger.h @@ -10,7 +10,7 @@ class Sector; struct ErrorLogMessage { - std::string message; + std::string message; }; struct BeginSpeedOperationLogMessage @@ -29,7 +29,7 @@ struct TrackReadLogMessage struct DiskReadLogMessage { - std::shared_ptr disk; + std::shared_ptr disk; }; struct BeginReadOperationLogMessage @@ -40,8 +40,8 @@ struct BeginReadOperationLogMessage struct EndReadOperationLogMessage { - std::shared_ptr trackDataFlux; - std::set> sectors; + std::shared_ptr trackDataFlux; + std::set> sectors; }; struct BeginWriteOperationLogMessage @@ -54,19 +54,36 @@ struct EndWriteOperationLogMessage { }; +struct BeginOperationLogMessage +{ + std::string message; +}; + +struct EndOperationLogMessage +{ + std::string message; +}; + +struct OperationProgressLogMessage +{ + unsigned progress; +}; + class TrackFlux; -typedef std::variant< - std::string, - ErrorLogMessage, +typedef std::variant + EndWriteOperationLogMessage, + BeginOperationLogMessage, + EndOperationLogMessage, + OperationProgressLogMessage> AnyLogMessage; class Logger diff --git a/lib/readerwriter.cc b/lib/readerwriter.cc index 54939fb4..c1885aab 100644 --- a/lib/readerwriter.cc +++ b/lib/readerwriter.cc @@ -187,8 +187,17 @@ void writeTracks(FluxSink& fluxSink, producer, std::function verifier) { - for (const auto& location : Mapper::computeLocations()) + Logger() << BeginOperationLogMessage{"Encoding and writing to disk"}; + + auto locations = Mapper::computeLocations(); + + int index = 0; + for (const auto& location : locations) { + Logger() << OperationProgressLogMessage{ + index * 100 / (unsigned)locations.size()}; + index++; + testForEmergencyStop(); int retriesRemaining = config.decoder().retries(); @@ -237,6 +246,8 @@ void writeTracks(FluxSink& fluxSink, retriesRemaining--; } } + + Logger() << EndOperationLogMessage{"Write complete"}; } static bool dontVerify(const Location&) @@ -285,30 +296,38 @@ void writeTracksAndVerify(FluxSink& fluxSink, return false; } - Image wanted; - for (const auto& sector : encoder.collectSectors(location, image)) - wanted.put(sector->logicalTrack, sector->logicalSide, sector->logicalSector)->data = sector->data; + Image wanted; + for (const auto& sector : encoder.collectSectors(location, image)) + wanted + .put(sector->logicalTrack, + sector->logicalSide, + sector->logicalSector) + ->data = sector->data; - for (const auto& sector : trackFlux->sectors) - { - const auto s = wanted.get(sector->logicalTrack, sector->logicalSide, sector->logicalSector); - if (!s) - { - Logger() << "spurious sector on verify"; - return false; - } - if (s->data != sector->data.slice(0, s->data.size())) - { - Logger() << "data mismatch on verify"; - return false; - } - wanted.erase(sector->logicalTrack, sector->logicalSide, sector->logicalSector); - } - if (!wanted.empty()) - { - Logger() << "missing sector on verify"; - return false; - } + for (const auto& sector : trackFlux->sectors) + { + const auto s = wanted.get(sector->logicalTrack, + sector->logicalSide, + sector->logicalSector); + if (!s) + { + Logger() << "spurious sector on verify"; + return false; + } + if (s->data != sector->data.slice(0, s->data.size())) + { + Logger() << "data mismatch on verify"; + return false; + } + wanted.erase(sector->logicalTrack, + sector->logicalSide, + sector->logicalSector); + } + if (!wanted.empty()) + { + Logger() << "missing sector on verify"; + return false; + } return true; }); } @@ -319,14 +338,14 @@ void writeDiskCommand(const Image& image, AbstractDecoder* decoder, FluxSource* fluxSource) { - const Image* imagep = ℑ - std::unique_ptr remapped; + const Image* imagep = ℑ + std::unique_ptr remapped; if (config.has_sector_mapping()) - { + { remapped = Mapper::remapSectorsLogicalToPhysical( image, config.sector_mapping()); - imagep = &*remapped; - } + imagep = &*remapped; + } if (fluxSource && decoder) writeTracksAndVerify(fluxSink, encoder, *fluxSource, *decoder, *imagep); @@ -346,9 +365,8 @@ void writeRawDiskCommand(FluxSource& fluxSource, FluxSink& fluxSink) dontVerify); } -std::shared_ptr readAndDecodeTrack(FluxSource& fluxSource, - AbstractDecoder& decoder, - const Location& location) +std::shared_ptr readAndDecodeTrack( + FluxSource& fluxSource, AbstractDecoder& decoder, const Location& location) { auto trackFlux = std::make_shared(); trackFlux->location = location; @@ -378,7 +396,7 @@ std::shared_ptr readAndDecodeTrack(FluxSource& fluxSource, retriesRemaining--; } - return trackFlux; + return trackFlux; } std::shared_ptr readDiskCommand( @@ -390,12 +408,18 @@ std::shared_ptr readDiskCommand( auto diskflux = std::make_shared(); - for (const auto& location : Mapper::computeLocations()) + Logger() << BeginOperationLogMessage{"Reading and decoding disk"}; + auto locations = Mapper::computeLocations(); + unsigned index = 0; + for (const auto& location : locations) { + Logger() << OperationProgressLogMessage{ + index * 100 / (unsigned)locations.size()}; + index++; + testForEmergencyStop(); - auto trackFlux = readAndDecodeTrack( - fluxSource, decoder, location); + auto trackFlux = readAndDecodeTrack(fluxSource, decoder, location); diskflux->tracks.push_back(trackFlux); if (outputFluxSink) @@ -478,6 +502,7 @@ std::shared_ptr readDiskCommand( /* diskflux can't be modified below this point. */ Logger() << DiskReadLogMessage{diskflux}; + Logger() << BeginOperationLogMessage{"Read complete"}; return diskflux; } @@ -494,10 +519,20 @@ void readDiskCommand( void rawReadDiskCommand(FluxSource& fluxsource, FluxSink& fluxsink) { - for (unsigned track : iterate(config.tracks())) + Logger() << BeginOperationLogMessage{"Performing raw read of disk"}; + + auto tracks = iterate(config.tracks()); + auto heads = iterate(config.heads()); + unsigned locations = tracks.size() * heads.size(); + + unsigned index = 0; + for (unsigned track : tracks) { - for (unsigned head : iterate(config.heads())) + for (unsigned head : heads) { + Logger() << OperationProgressLogMessage{index * 100 / locations}; + index++; + testForEmergencyStop(); auto fluxSourceIterator = fluxsource.readFlux(track, head); @@ -511,6 +546,8 @@ void rawReadDiskCommand(FluxSource& fluxsource, FluxSink& fluxsink) fluxsink.writeFlux(track, head, *fluxmap); } } + + Logger() << EndOperationLogMessage{"Raw read complete"}; } void fillBitmapTo(std::vector& bitmap, diff --git a/src/gui/customstatusbar.cc b/src/gui/customstatusbar.cc index 97ddaea2..930f8bcd 100644 --- a/src/gui/customstatusbar.cc +++ b/src/gui/customstatusbar.cc @@ -92,6 +92,11 @@ void CustomStatusBar::SetProgress(int amount) _progressBar->SetValue(amount); } +void CustomStatusBar::SetLeftLabel(const std::string& text) +{ + SetStatusText(text, 0); +} + void CustomStatusBar::SetRightLabel(const std::string& text) { _rightLabel->SetLabel(text); diff --git a/src/gui/customstatusbar.h b/src/gui/customstatusbar.h index fc7f46da..59093569 100644 --- a/src/gui/customstatusbar.h +++ b/src/gui/customstatusbar.h @@ -15,6 +15,7 @@ public: void ShowProgressBar(); void HideProgressBar(); void SetProgress(int amount); + void SetLeftLabel(const std::string& text); void SetRightLabel(const std::string& text); private: diff --git a/src/gui/mainwindow.cc b/src/gui/mainwindow.cc index 1de75975..4cc33ab9 100644 --- a/src/gui/mainwindow.cc +++ b/src/gui/mainwindow.cc @@ -481,6 +481,7 @@ public: /* A fatal error. */ [&](const ErrorLogMessage& m) { + _statusBar->SetLeftLabel(m.message); wxMessageBox(m.message, "Error", wxOK | wxICON_ERROR); _state = _errorState; UpdateState(); @@ -523,6 +524,27 @@ public: { _currentDisk = m.disk; }, + + /* Large-scale operation start. */ + [&](const BeginOperationLogMessage& m) + { + _statusBar->SetLeftLabel(m.message); + _statusBar->ShowProgressBar(); + }, + + /* Large-scale operation end. */ + [&](const EndOperationLogMessage& m) + { + _statusBar->SetLeftLabel(m.message); + _statusBar->HideProgressBar(); + }, + + /* Large-scale operation progress. */ + [&](const OperationProgressLogMessage& m) + { + _statusBar->SetProgress(m.progress); + }, + }, *message); }