diff --git a/CMakeLists.txt b/CMakeLists.txt index 92c29c0..ad452aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.16) project(robometry LANGUAGES C CXX - VERSION 1.3.0) + VERSION 1.4.0) include(GNUInstallDirs) include(FeatureSummary) diff --git a/src/librobometry/include/robometry/BufferManager.h b/src/librobometry/include/robometry/BufferManager.h index 2706367..1843a99 100644 --- a/src/librobometry/include/robometry/BufferManager.h +++ b/src/librobometry/include/robometry/BufferManager.h @@ -290,6 +290,12 @@ class BufferManager { */ bool configure(const BufferConfig& _bufferConfig); + /** + * @brief Clear all channels and data from the BufferManager, stopping the periodic save thread. + * After calling this, the BufferManager must be reconfigured before use. + */ + void clear(); + /** * @brief Get the BufferConfig object representing the actual configuration. * diff --git a/src/librobometry/src/BufferManager.cpp b/src/librobometry/src/BufferManager.cpp index 069c25a..c4e0131 100644 --- a/src/librobometry/src/BufferManager.cpp +++ b/src/librobometry/src/BufferManager.cpp @@ -84,6 +84,29 @@ bool robometry::BufferManager::configure(const BufferConfig &_bufferConfig) { return ok; } +void robometry::BufferManager::clear() { + // Stop the periodic save thread if running + if (m_save_thread.joinable()) { + { + std::unique_lock lk_cv(m_mutex_cv); + m_should_stop_thread = true; + m_cv.notify_one(); + } + m_save_thread.join(); + } + m_should_stop_thread = false; + + // Reset the tree to clear all channels + m_tree = std::make_shared>(); + + // Clear channel list from config + m_bufferConfig.channels.clear(); + + // Reset callbacks + m_saveCallback = {}; + m_preSaveCallback = {}; +} + robometry::BufferConfig robometry::BufferManager::getBufferConfig() const { return m_bufferConfig; } diff --git a/test/BufferManagerTest.cpp b/test/BufferManagerTest.cpp index d8ecd7c..c27be38 100644 --- a/test/BufferManagerTest.cpp +++ b/test/BufferManagerTest.cpp @@ -504,6 +504,40 @@ TEST_CASE("Buffer Manager Test") } + SECTION("Test clear") { + robometry::BufferManager bm; + robometry::BufferConfig bufferConfig; + + robometry::ChannelInfo var_one{ "one", {1,1} }; + robometry::ChannelInfo var_two{ "two", {1,1} }; + + // Add channels + REQUIRE(bm.addChannel(var_one)); + REQUIRE(bm.addChannel(var_two)); + + bufferConfig.filename = "buffer_manager_test_clear"; + bufferConfig.n_samples = n_samples; + REQUIRE(bm.configure(bufferConfig)); + + // Add some data + for (int i = 0; i < 3; i++) { + bm.push_back({ i }, "one"); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + bm.push_back({ i + 1 }, "two"); + } + + // Clear the buffer manager + bm.clear(); + + // Verify channels were cleared - the config should be empty + auto config_after = bm.getBufferConfig(); + REQUIRE(config_after.channels.empty()); + + // Verify we can reconfigure after clear + bufferConfig.filename = "buffer_manager_test_clear_after"; + REQUIRE(bm.configure(bufferConfig)); + } + #if defined CATCH_CONFIG_ENABLE_BENCHMARKING SECTION("Benchmarking section scalar int") {