diff --git a/ArpamGuiQt/src/RFBuffer.cpp b/ArpamGuiQt/src/RFBuffer.cpp index 1ac27a3..2a4503d 100644 --- a/ArpamGuiQt/src/RFBuffer.cpp +++ b/ArpamGuiQt/src/RFBuffer.cpp @@ -124,7 +124,9 @@ void BScanData::exportToFile( // Save frame index // Touch file to create an empty txt file with the frame idx as title - { std::ofstream fs(directory / fmt::format("frame_{}.txt", frameIdx)); } + { + std::ofstream fs(directory / fmt::format("frame_{}.txt", frameIdx)); + } /* Exported crops from annotation @@ -157,7 +159,7 @@ void BScanData::exportToFile( // Save radial images if (exportSetting.saveRadialImages) { // Save combined image - auto pausPath = (directory / "PAUSradial.tiff").string(); + const auto pausPath = (directory / "PAUSradial.tiff").string(); if (!cv::imwrite(pausPath, PAUSradial)) { std::cerr << "Failed to save " << pausPath << "\n"; } @@ -188,6 +190,7 @@ void BScanData::exportAnnotatedCrops( for (const auto &anno : annotations) { switch (anno.type) { + case annotation::Annotation::Type::Rect: { const auto qrect = anno.rect().toRect(); const auto rect = cvRect(qrect); @@ -216,9 +219,8 @@ void BScanData::exportAnnotatedCrops( const auto name = fmt::format("USradial-{}", annoSuffix); croppedQImages.emplace_back(cropped, name); } - } + } break; - break; case annotation::Annotation::Fan: { const auto arc = anno.arc(); @@ -273,9 +275,11 @@ void BScanData::exportAnnotatedCrops( exportCropped(PA.rfLog, fmt::format("PA-{}", annoSuffix)); } break; + case annotation::Annotation::Polygon: case annotation::Annotation::Line: case annotation::Annotation::Size: + std::cerr << " Ignoring export of unsupported anntation\n"; break; } } diff --git a/ArpamGuiQt/src/RFBuffer.hpp b/ArpamGuiQt/src/RFBuffer.hpp index 00548b8..0d6a14e 100644 --- a/ArpamGuiQt/src/RFBuffer.hpp +++ b/ArpamGuiQt/src/RFBuffer.hpp @@ -103,84 +103,78 @@ Thread safe buffer for the producer/consumer pattern Inspired by https://andrew128.github.io/ProducerConsumer/ */ -template class RFBuffer { +template class RFBuffer { public: RFBuffer() { - for (int i = 0; i < buffer.size(); ++i) { - buffer[i] = std::make_shared>(); + for (auto &sptr : m_buffer) { + sptr = std::make_shared>(); } } // The exit condition for a consumer is receiving a nullptr void exit() { - std::unique_lock unique_lock(mtx); + std::unique_lock unique_lock(m_mtx); - not_full.wait(unique_lock, [this] { return buffer_size != buffer.size(); }); + m_not_full.wait(unique_lock, + [this] { return buffer_size != m_buffer.size(); }); - buffer[right] = nullptr; + m_buffer[m_wpos] = nullptr; // Update fields - right = (right + 1) % buffer.size(); + m_wpos = (m_wpos + 1) % m_buffer.size(); buffer_size++; - // Unlock unique lock unique_lock.unlock(); // Notify one thread that buffer isn't empty - not_empty.notify_one(); + m_not_empty.notify_one(); } template void produce(const Func &producer_callback) { - std::unique_lock unique_lock(mtx); + std::unique_lock unique_lock(m_mtx); // Wait if the buffer is full - not_full.wait(unique_lock, [this] { return buffer_size != buffer.size(); }); + m_not_full.wait(unique_lock, + [this] { return buffer_size != m_buffer.size(); }); - // Add input to buffer - // buffer[right] = num; - auto &currData = buffer[right]; - { producer_callback(currData); } + // Add to buffer + producer_callback(m_buffer[m_wpos]); // Update fields - right = (right + 1) % buffer.size(); + m_wpos = (m_wpos + 1) % m_buffer.size(); buffer_size++; - // Unlock unique lock unique_lock.unlock(); // Notify one thread that buffer isn't empty - not_empty.notify_one(); + m_not_empty.notify_one(); } template void consume(const Func &consumer_callback) { // Acquire - std::unique_lock unique_lock(mtx); + std::unique_lock unique_lock(m_mtx); // Wait if buffer is empty - not_empty.wait(unique_lock, [this]() { return buffer_size != 0; }); + m_not_empty.wait(unique_lock, [this]() { return buffer_size != 0; }); // Get from buffer - { - auto &result = buffer[left]; - consumer_callback(result); - } + consumer_callback(m_buffer[m_rpos]); // Update appropriate fields - left = (left + 1) % buffer.size(); + m_rpos = (m_rpos + 1) % m_buffer.size(); buffer_size--; - // Unlock unique lock unique_lock.unlock(); // Notify one thread that the buffer isn't full - not_full.notify_one(); + m_not_full.notify_one(); } private: - std::array>, 10> buffer{}; - int buffer_size{0}; - int left{0}; // index where vars are put inside of buffer (produced) - int right{0}; // idx where vars are removed from buffer (consumed) + std::array>, Capacity> m_buffer{}; + size_t buffer_size{}; + size_t m_rpos{}; // read idx where vars are removed from buffer (consumed) + size_t m_wpos{}; // write idx where vars are put inside of buffer (produced) // Concurrency - std::mutex mtx; - std::condition_variable not_empty; - std::condition_variable not_full; + std::mutex m_mtx; + std::condition_variable m_not_empty; + std::condition_variable m_not_full; };