From 758b474cbd71cad19370cd93b613486547a05914 Mon Sep 17 00:00:00 2001 From: Stefano Date: Thu, 23 Oct 2025 16:49:36 +0200 Subject: [PATCH 1/2] Added possibility to set a pre save callback --- CMakeLists.txt | 2 +- .../include/robometry/BufferManager.h | 17 ++++++- src/librobometry/src/BufferManager.cpp | 44 ++++++++++++++----- test/BufferManagerTest.cpp | 34 +++++++++----- 4 files changed, 72 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 25c45de..92c29c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.16) project(robometry LANGUAGES C CXX - VERSION 1.2.8) + VERSION 1.3.0) include(GNUInstallDirs) include(FeatureSummary) diff --git a/src/librobometry/include/robometry/BufferManager.h b/src/librobometry/include/robometry/BufferManager.h index 6cd8c14..2706367 100644 --- a/src/librobometry/include/robometry/BufferManager.h +++ b/src/librobometry/include/robometry/BufferManager.h @@ -501,12 +501,24 @@ class BufferManager { /** * @brief Set the saveCallback function. Thanks to this function you can save additional data - * type along with the matfile salve by telemetry - * @param[in] saveCallback The saveCallback function + * type along with the matfile saved by telemetry. This callback is called after saving the matfile. + * The callback receives as input the full path of the matfile just saved and the triggering method. + * The callback must return true on success, false otherwise. + * @param[in] saveCallback The saveCallback function. * @return true on success, false otherwise. */ bool setSaveCallback(std::function saveCallback); + /** + * @brief Set the preSaveCallback function. Thanks to this function you can decide whether to proceed + * with the saving of the matfile or not. This callback is called before saving the matfile. + * The callback receives as input the triggering method. + * The callback must return true to proceed with the saving, false otherwise. + * @param[in] preSaveCallback The preSaveCallback function. + * @return true on success, false otherwise. + */ + bool setPreSaveCallback(std::function preSaveCallback); + private: static double DefaultClock(); @@ -547,6 +559,7 @@ class BufferManager { std::function m_nowFunction{DefaultClock}; std::function m_saveCallback{}; + std::function m_preSaveCallback {}; std::thread m_save_thread; matioCpp::CellArray m_description_cell_array; diff --git a/src/librobometry/src/BufferManager.cpp b/src/librobometry/src/BufferManager.cpp index 425a0b4..069c25a 100644 --- a/src/librobometry/src/BufferManager.cpp +++ b/src/librobometry/src/BufferManager.cpp @@ -32,10 +32,15 @@ robometry::BufferManager::~BufferManager() { } if (m_bufferConfig.auto_save) { std::string fileName; - saveToFile(fileName); - if (m_saveCallback) - { - m_saveCallback(fileName, SaveCallbackSaveMethod::last_call); + bool should_save = true; + if (m_preSaveCallback) { + should_save = m_preSaveCallback(SaveCallbackSaveMethod::last_call); + } + if (should_save) { + saveToFile(fileName); + if (m_saveCallback) { + m_saveCallback(fileName, SaveCallbackSaveMethod::last_call); + } } } } @@ -223,7 +228,18 @@ bool robometry::BufferManager::setSaveCallback(std::function preSaveCallback) +{ + if (preSaveCallback == nullptr) { + std::cout << "Not valid preSaveCallback function." << std::endl; + return false; + } + m_preSaveCallback = preSaveCallback; + return true; +} + +double robometry::BufferManager::DefaultClock() +{ return std::chrono::duration(std::chrono::system_clock::now().time_since_epoch()).count(); } @@ -238,11 +254,19 @@ void robometry::BufferManager::periodicSave() { if (!m_tree->empty()) // if there are channels { - std::string fileName; - saveToFile(fileName, false); - if (m_saveCallback) - { - m_saveCallback(fileName, SaveCallbackSaveMethod::periodic); + bool should_save = true; + if (m_preSaveCallback) { + should_save = m_preSaveCallback(SaveCallbackSaveMethod::periodic); + } + if (should_save) { + std::string fileName; + saveToFile(fileName, false); + if (m_saveCallback) { + m_saveCallback(fileName, SaveCallbackSaveMethod::periodic); + } + } + else { + std::cout << "Pre-save callback prevented the periodic save." << std::endl; } } } diff --git a/test/BufferManagerTest.cpp b/test/BufferManagerTest.cpp index abd80f7..9d85303 100644 --- a/test/BufferManagerTest.cpp +++ b/test/BufferManagerTest.cpp @@ -424,20 +424,30 @@ TEST_CASE("Buffer Manager Test") SECTION("Callback") { - robometry::BufferManager bm; - robometry::BufferConfig bufferConfig; - bufferConfig.n_samples = n_samples; - bufferConfig.filename = "buffer_manager_test_callback"; - bufferConfig.auto_save = true; - - REQUIRE(bm.addChannel({ "int_channel", {1}})); - bm.setSaveCallback(testCallback); - REQUIRE(bm.configure(bufferConfig)); + bool called = false; - for (int i = 0; i < 10; i++) { - bm.push_back(i, "int_channel"); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); + { + robometry::BufferManager bm; + robometry::BufferConfig bufferConfig; + bufferConfig.n_samples = n_samples; + bufferConfig.filename = "buffer_manager_test_callback"; + bufferConfig.auto_save = true; + + REQUIRE(bm.addChannel({ "int_channel", {1}})); + bm.setSaveCallback(testCallback); + bm.setPreSaveCallback([&called](const robometry::SaveCallbackSaveMethod& /**method*/) + { + called = true; + return true; + }); + REQUIRE(bm.configure(bufferConfig)); + + for (int i = 0; i < 10; i++) { + bm.push_back(i, "int_channel"); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } } + REQUIRE(called); } SECTION("Unit of measure") { From 5c6765c01f963f8bfc7fae8f26cf68741ec1fc3d Mon Sep 17 00:00:00 2001 From: Stefano Date: Thu, 23 Oct 2025 17:18:47 +0200 Subject: [PATCH 2/2] Added REQUIRE whe setting the callbacks in test --- test/BufferManagerTest.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/BufferManagerTest.cpp b/test/BufferManagerTest.cpp index 9d85303..d8ecd7c 100644 --- a/test/BufferManagerTest.cpp +++ b/test/BufferManagerTest.cpp @@ -434,12 +434,12 @@ TEST_CASE("Buffer Manager Test") bufferConfig.auto_save = true; REQUIRE(bm.addChannel({ "int_channel", {1}})); - bm.setSaveCallback(testCallback); - bm.setPreSaveCallback([&called](const robometry::SaveCallbackSaveMethod& /**method*/) + REQUIRE(bm.setSaveCallback(testCallback)); + REQUIRE(bm.setPreSaveCallback([&called](const robometry::SaveCallbackSaveMethod& /**method*/) { called = true; return true; - }); + })); REQUIRE(bm.configure(bufferConfig)); for (int i = 0; i < 10; i++) {