Compare commits

1 Commits

Author SHA1 Message Date
Sylvain Schneider
0165dfe8f0 Initial UI setup 2026-05-22 17:24:30 +02:00
316 changed files with 78404 additions and 31 deletions

73
.clang-format Normal file
View File

@@ -0,0 +1,73 @@
# Project-wide C++ formatting (C++ latest / Visual Studio + clang-format)
BasedOnStyle: Mozilla
Language: Cpp
# General layout
ColumnLimit: 0
IndentWidth: 2
ContinuationIndentWidth: 2
AlwaysBreakBeforeMultilineStrings: false
TabWidth: 2
UseTab: Never
# Braces/style (matches your current Allman-like style)
BreakBeforeBraces: Allman
#AllowShortIfStatementsOnASingleLine: Never
#AllowShortBlocksOnASingleLine: Never
# AllowShortFunctionsOnASingleLine: None
AllowShortFunctionsOnASingleLine: Inline
AllowShortLoopsOnASingleLine: false
#AllowShortLambdasOnASingleLine: None
# Lambdas
LambdaBodyIndentation: Signature
# Wrapping / argument formatting
# BinPackArguments: false
# BinPackParameters: false
AllowAllParametersOfDeclarationOnNextLine: false
# AlignAfterOpenBracket: DontAlign
AlignAfterOpenBracket: Align
# Pointers/references
PointerAlignment: Right
ReferenceAlignment: Right
# Namespaces
FixNamespaceComments: true
# Includes
SortIncludes: CaseSensitive
IncludeBlocks: Regroup
# Keep comments readable
ReflowComments: true
# Breaking
BreakAfterReturnType: None
AlwaysBreakAfterDefinitionReturnType: None
BreakConstructorInitializersBeforeComma: false
BreakBeforeTernaryOperators: true
# Spacing
SpaceBeforeParens: ControlStatements
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 5
AccessModifierOffset: 0
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: true
AllowShortCaseLabelsOnASingleLine: false
IndentCaseLabels: true
IndentPPDirectives: AfterHash
NamespaceIndentation: None
# Sorting
SortUsingDeclarations: Lexicographic
# C++ specifics
Standard: Latest

63
.gitignore vendored
View File

@@ -1,34 +1,35 @@
# ---> C++ # Ignore build folters
# Prerequisites bin/
*.d obj/
out/
archives/
tmp/
# Compiled Object files # Ignore IDE user files / folders
*.slo .vs/
*.lo enc_temp_folder/
*.o *.aps
*.obj *.depend
*.db-journal
*.layout
*.opensdf
*.sdf
*.suo
*.user
*.filters
# Precompiled Headers # Ignore compiled user files
*.gch *.dat
*.pch *.pdf
*.db
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
#------------------------
# Temporary excludes from GIT
aggregoViewer/
binaryResources/
dataConverter/
mathAnalysis_dll
*.ods
*.zip
*.xlsx
*.bkp

402
CMakeLists.txt Normal file
View File

@@ -0,0 +1,402 @@
cmake_minimum_required (VERSION 3.23)
#------------------------------------------------
#--- Setup compiler settings ---
#------------------------------------------------
# Set C language standard
set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF) # Only standard features, no compiler-specific extensions
# Set C++ language standard
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) # Only standard features, no compiler-specific extensions
# Options
set(APP_WIN32 ON CACHE BOOL "Build app as a Windows GUI application" FORCE)
# Set compiler flags based on build type
set(GENERAL_C_FLAGS
/MP # Enable multi-processor compilation
)
set(GENERAL_CXX_FLAGS
/MP # Enable multi-processor compilation
/EHsc # Enable C++ exception handling
)
set(DEBUG_C_FLAGS
/Od # Disable optimization for debugging
/Zi # Generate complete debugging information
/RTC1 # Enable runtime error checks
/Ob0 # Disable inline expansion
/W3 # Enable standard warnings
# /W4 # Enable high-level warnings
)
set(DEBUG_CXX_FLAGS
/Od # Disable optimization for debugging
/Zi # Generate complete debugging information
/RTC1 # Enable runtime error checks
/Ob0 # Disable inline expansion
/W3 # Enable standard warnings
# /W4 # Enable high-level warnings
)
set(RELEASE_C_FLAGS
/O2 # Optimize for speed
/Ot # Favor fast code
/Oi # Generate intrinsic functions
/GL # Enable whole program optimization
/Ob2 # Enable inline expansion
/W3 # Enable standard warnings
# /W4 # Enable high-level warnings
)
set(RELEASE_CXX_FLAGS
/O2 # Optimize for speed
/Ot # Favor fast code
/Oi # Generate intrinsic functions
/GL # Enable whole program optimization
/Ob2 # Enable inline expansion
/W3 # Enable standard warnings
# /W4 # Enable high-level warnings
)
#------------------------------------------------
#--- Project configuration ---
#------------------------------------------------
# Define the project settings
project("kwa.fr")
# Source directory
set(SRC_DIR
"src"
)
# Resource files (add resource files here if needed)
set(RESOURCE_FILES
# "src/file.rc"
)
#------------------------------------------------
#--- Sanity checks ---
#------------------------------------------------
# Ensure build type is set (Debug, Release, etc.)
if(NOT CMAKE_BUILD_TYPE)
message(FATAL_ERROR "CMAKE_BUILD_TYPE must be set")
endif()
# Ensure DEV_LIB environment variable is defined (used for external libraries)
if(NOT DEFINED ENV{DEV_LIB})
message(FATAL_ERROR "DEV_LIB environment variable must be defined")
endif()
set(DEV_LIB $ENV{DEV_LIB})
#------------------------------------------------
#--- Include directories ---
#------------------------------------------------
# General include directories (add your common include paths here)
set(GENERAL_INCLUDE_DIRS
"src"
"sdi_toolBox_1.0.x/toolBox"
"sdi_toolBox_2.x.x/toolBox"
"${DEV_LIB}/boost_1_87_0"
"${DEV_LIB}/wxWidgets-3.2.8/include/msvc"
"${DEV_LIB}/wxWidgets-3.2.8/include"
"${DEV_LIB}/openssl-3.5.0/include"
"${DEV_LIB}/hidapi-0.15.0/include"
"${DEV_LIB}/webview2/build/native/include"
)
# Additional include directories for Debug configuration
set(DEBUG_INCLUDE_DIRS
# "path/to/debug/include"
)
# Additional include directories for Release configuration
set(RELEASE_INCLUDE_DIRS
# "path/to/debug/include"
)
#------------------------------------------------
#--- Library directories ---
#------------------------------------------------
# General library directories (add your common library paths here)
set(GENERAL_LIBRARY_DIRS
${CMAKE_BINARY_DIR}
"${DEV_LIB}/boost_1_87_0/stage/lib"
"${DEV_LIB}/wxWidgets-3.2.8/lib/vc_x64_dll"
"${DEV_LIB}/openssl-3.5.0/lib"
"${DEV_LIB}/hidapi-0.15.0/lib"
"${DEV_LIB}/webview2/build/native/x64"
)
# Additional library directories for Debug configuration
set(DEBUG_LIBRARY_DIRS
# "path/to/debug/lib"
)
# Additional library directories for Release configuration
set(RELEASE_LIBRARY_DIRS
# "path/to/debug/lib"
)
#------------------------------------------------
#--- Preprocessor definitions ---
#------------------------------------------------
# General preprocessor definitions (add your common defines here)
set(GENERAL_PREPROCESSOR_DEFINITIONS
"_CRT_SECURE_NO_DEPRECATE"
"_CRT_NONSTDC_NO_DEPRECATE"
"_UNICODE"
"_WINDOWS"
"NOMINMAX"
"UNICODE"
"WIN32"
"WIN32_LEAN_AND_MEAN"
"WXUSINGDLL"
)
# Additional preprocessor definitions for Debug configuration
set(DEBUG_PREPROCESSOR_DEFINITIONS
"_DEBUG"
"DEBUG"
"WXDEBUG"
)
# Additional preprocessor definitions for Release configuration
set(RELEASE_PREPROCESSOR_DEFINITIONS
"NDEBUG"
)
#------------------------------------------------
#--- Libraries and DLLs ---
#------------------------------------------------
# General libraries to link (add your common libraries here)
set(GENERAL_LIB
"WebView2Loader.dll.lib"
"hidapid.lib"
)
# Additional libraries for Debug configuration
set(DEBUG_LIB
# "libDebug.lib"
"wxmsw32ud_webview.lib"
)
# Additional libraries for Release configuration
set(RELEASE_LIB
# "libRelease.lib"
"wxmsw32u_webview.lib"
)
# General DLLs to copy after build (add your common DLLs here)
set(GENERAL_BIN
"${DEV_LIB}/webview2/build/native/x64/WebView2Loader.dll"
)
# Additional DLLs for Debug configuration
set(DEBUG_BIN
"${DEV_LIB}/wxWidgets-3.2.8/lib/vc_x64_dll/wxbase32ud_vc_x64_custom.dll"
"${DEV_LIB}/wxWidgets-3.2.8/lib/vc_x64_dll/wxmsw32ud_core_vc_x64_custom.dll"
"${DEV_LIB}/wxWidgets-3.2.8/lib/vc_x64_dll/wxmsw32ud_webview_vc_x64_custom.dll"
)
# Additional DLLs for Release configuration
set(RELEASE_BIN
"${DEV_LIB}/wxWidgets-3.2.8/lib/vc_x64_dll/wxbase32u_vc_x64_custom.dll"
"${DEV_LIB}/wxWidgets-3.2.8/lib/vc_x64_dll/wxmsw32u_core_vc_x64_custom.dll"
"${DEV_LIB}/wxWidgets-3.2.8/lib/vc_x64_dll/wxmsw32u_webview_vc_x64_custom.dll"
)
#------------------------------------------------
#--- WebView2 SDK ---
#------------------------------------------------
#------------------------------------------------
#--- MSVC Debug Information Format Policy ---
#------------------------------------------------
# Ensure CMake policy CMP0141 is set to NEW to control the MSVC debug information format.
# This sets CMAKE_MSVC_DEBUG_INFORMATION_FORMAT to "EditAndContinue" for Debug and RelWithDebInfo configurations,
# and to "ProgramDatabase" for other configurations, but only when using the MSVC compiler.
if (POLICY CMP0141)
cmake_policy(SET CMP0141 NEW)
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
endif()
#------------------------------------------------
#--- Source files gathering ---
#------------------------------------------------
# Collect all C and C++ source files from each directory in SRC_DIR
set(SOURCES_C "")
set(SOURCES_CPP "")
foreach(DIR IN LISTS SRC_DIR)
file(GLOB_RECURSE DIR_SOURCES_C "${DIR}/*.c")
file(GLOB_RECURSE DIR_SOURCES_CPP "${DIR}/*.cpp")
list(APPEND SOURCES_C ${DIR_SOURCES_C})
list(APPEND SOURCES_CPP ${DIR_SOURCES_CPP})
endforeach()
#------------------------------------------------
#--- Target definition ---
#------------------------------------------------
# Define the main executable target
message(STATUS "APP_WIN32='${APP_WIN32}'")
if(APP_WIN32)
add_executable(${PROJECT_NAME} WIN32
${SOURCES_C}
${SOURCES_CPP}
${RESOURCE_FILES}
)
else()
add_executable(${PROJECT_NAME}
${SOURCES_C}
${SOURCES_CPP}
${RESOURCE_FILES}
)
endif()
#------------------------------------------------
#--- Target properties setup ---
#------------------------------------------------
# Setup include directories
target_include_directories(${PROJECT_NAME} SYSTEM PRIVATE
${GENERAL_INCLUDE_DIRS}
$<$<CONFIG:Debug>:${DEBUG_INCLUDE_DIRS}>
$<$<CONFIG:Release>:${RELEASE_INCLUDE_DIRS}>
)
# Setup library directories
target_link_directories(${PROJECT_NAME} PRIVATE
${GENERAL_LIBRARY_DIRS}
$<$<CONFIG:Debug>:${DEBUG_LIBRARY_DIRS}>
$<$<CONFIG:Release>:${RELEASE_LIBRARY_DIRS}>
)
# Setup preprocessor definitions
target_compile_definitions(${PROJECT_NAME} PRIVATE
${GENERAL_PREPROCESSOR_DEFINITIONS}
$<$<CONFIG:Debug>:${DEBUG_PREPROCESSOR_DEFINITIONS}>
$<$<CONFIG:Release>:${RELEASE_PREPROCESSOR_DEFINITIONS}>
)
# Setup linked libraries
target_link_libraries(${PROJECT_NAME} PRIVATE
${GENERAL_LIB}
$<$<CONFIG:Debug>:${DEBUG_LIB}>
$<$<CONFIG:Release>:${RELEASE_LIB}>
)
# Setup compiler options
set(PROJET_C_FLAGS
${GENERAL_C_FLAGS}
$<$<CONFIG:Debug>:${DEBUG_C_FLAGS}>
$<$<CONFIG:Release>:${RELEASE_C_FLAGS}>
)
set(PROJET_CXX_FLAGS
${GENERAL_CXX_FLAGS}
$<$<CONFIG:Debug>:${DEBUG_CXX_FLAGS}>
$<$<CONFIG:Release>:${RELEASE_CXX_FLAGS}>
)
target_compile_options(${PROJECT_NAME} PRIVATE
$<$<COMPILE_LANGUAGE:C>:${PROJET_C_FLAGS}> # Apply to C files
$<$<COMPILE_LANGUAGE:CXX>:${PROJET_CXX_FLAGS}> # Apply to C++ files
)
# Setup compiler and linker options (MSVC specific)
if(MSVC)
target_link_options(${PROJECT_NAME} PRIVATE "/ignore:4099" "/PROFILE")
endif()
#------------------------------------------------
#--- Post-build: Copy DLLs ---
#------------------------------------------------
# Copy DLLs to the output directory after build
foreach(dll IN LISTS GENERAL_BIN)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${dll}" "${CMAKE_BINARY_DIR}"
VERBATIM
)
endforeach()
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
foreach(dll IN LISTS DEBUG_BIN)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${dll}" "${CMAKE_BINARY_DIR}"
VERBATIM
)
endforeach()
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
foreach(dll IN LISTS RELEASE_BIN)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${dll}" "${CMAKE_BINARY_DIR}"
VERBATIM
)
endforeach()
endif()
#------------------------------------------------
#--- Project compilation log ---
#------------------------------------------------
# Print project and environment information for diagnostics
message(STATUS "--------------------------------------------------------")
message(STATUS "┏(-_-)┛┗(-_-)┓┗(-_-)┛┏(-_-)┓┏(-_-)┓┗(-_-)┛┏(-_-)┛┗(-_-)┓")
message(STATUS "--------------------------------------------------------")
message(STATUS "--- Platform Information -------------------------------")
message(STATUS "System Name: ${CMAKE_SYSTEM_NAME}")
message(STATUS "Processor: ${CMAKE_SYSTEM_PROCESSOR}")
message(STATUS "CMake Generator: ${CMAKE_GENERATOR}")
message(STATUS "--------------------------------------------------------")
message(STATUS "--- Compiler/Language Settings -------------------------")
message(STATUS "Build Type: ${CMAKE_BUILD_TYPE}")
message(STATUS "C Standard: ${CMAKE_C_STANDARD}")
message(STATUS "C Compiler ID: ${CMAKE_C_COMPILER_ID}")
message(STATUS "C Compiler Version: ${CMAKE_C_COMPILER_VERSION}")
message(STATUS "C Common Compiler Flags: ${GENERAL_C_FLAGS}")
message(STATUS "C Debug Compiler Flags: ${DEBUG_C_FLAGS}")
message(STATUS "C Release Compiler Flags: ${RELEASE_C_FLAGS}")
message(STATUS "C++ Standard: ${CMAKE_CXX_STANDARD}")
message(STATUS "C++ Compiler ID: ${CMAKE_CXX_COMPILER_ID}")
message(STATUS "C++ Compiler Version: ${CMAKE_CXX_COMPILER_VERSION}")
message(STATUS "C++ Common Compiler Flags: ${GENERAL_CXX_FLAGS}")
message(STATUS "C++ Debug Compiler Flags: ${DEBUG_CXX_FLAGS}")
message(STATUS "C++ Release Compiler Flags: ${RELEASE_CXX_FLAGS}")
message(STATUS "Common Linker Flags: ${CMAKE_EXE_LINKER_FLAGS}")
message(STATUS "Debug Linker Flags: ${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
message(STATUS "Release Linker Flags: ${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
message(STATUS "--------------------------------------------------------")
message(STATUS "--- Path Information -----------------------------------")
message(STATUS "Source Dir: ${CMAKE_CURRENT_SOURCE_DIR}")
message(STATUS "Binary Dir: ${CMAKE_CURRENT_BINARY_DIR}")
if(MSVC)
message(STATUS "--------------------------------------------------------")
message(STATUS "--- Microsoft Visual C++ (MSVC) Information ------------")
# Check the major compiler version
if(MSVC_VERSION GREATER_EQUAL 1950)
message(STATUS "MSVC Compiler Version: ${MSVC_VERSION} (Visual Studio 2026 or newer)")
elseif(MSVC_VERSION GREATER_EQUAL 1930)
message(STATUS "MSVC Compiler Version: ${MSVC_VERSION} (Visual Studio 2022)")
endif()
message(STATUS "MSVC Toolset Version: ${MSVC_TOOLSET_VERSION}")
endif()
message(STATUS "--------------------------------------------------------")
message(STATUS "--- Project Information --------------------------------")
message(STATUS "Project Name: ${PROJECT_NAME}")
message(STATUS "Preset Name: ${PRESET_NAME}")
message(STATUS "--------------------------------------------------------")
message(STATUS "┏(-_-)┛┗(-_-)┓┗(-_-)┛┏(-_-)┓┏(-_-)┓┗(-_-)┛┏(-_-)┛┗(-_-)┓")
message(STATUS "--------------------------------------------------------")

41
CMakePresets.json Normal file
View File

@@ -0,0 +1,41 @@
{
"version": 3,
"configurePresets": [
{
"name": "windows-base",
"hidden": true,
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"cacheVariables": {
"CMAKE_C_COMPILER": "cl.exe",
"CMAKE_CXX_COMPILER": "cl.exe"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{
"name": "x64-debug",
"displayName": "x64 Debug",
"inherits": "windows-base",
"architecture": {
"value": "x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "x64-release",
"displayName": "x64 Release",
"inherits": "x64-debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
}
]
}

View File

@@ -0,0 +1,430 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <curl/curl.h>
#include <filesystem>
#include <memory>
#include <mutex>
#include <ostream>
#include <sdi_toolBox/logs/reLog.h>
#include <string>
#include <unordered_map>
namespace sdi_ToolBox::communication
{
//--------------------------------------------------------------
class CurlGlobalInitializer
{
public:
static void init() // Initialize libcurl globally
{
static auto instance = std::unique_ptr<CurlGlobalInitializer>(new CurlGlobalInitializer());
}
public:
virtual ~CurlGlobalInitializer() // Default destructor
{
curl_global_cleanup();
}
CurlGlobalInitializer(const CurlGlobalInitializer &obj) = delete; // Copy constructor
CurlGlobalInitializer(CurlGlobalInitializer &&obj) noexcept = delete; // Move constructor
CurlGlobalInitializer &operator=(const CurlGlobalInitializer &obj) = delete; // Copy assignment operator
CurlGlobalInitializer &operator=(CurlGlobalInitializer &&obj) noexcept = delete; // Move assignment operator
protected:
CurlGlobalInitializer() // Default constructor
{
if (curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK)
throw std::runtime_error("ERROR: Failed to initialize cURL");
}
};
//--------------------------------------------------------------
/* --- */
//--------------------------------------------------------------
class CurlHttpClient
{
public:
enum class Method : uint8_t
{
http_GET,
http_POST,
http_PUT,
http_DELETE,
};
struct Settings
{
bool enableSSL = true;
bool ssl_verifyPeer = true;
bool ssl_verifyHost = true;
std::filesystem::path ssl_caInfo;
std::string ssl_certBlob;
std::chrono::seconds timeout{ 10 };
bool operator==(const Settings &other) const
{
// Compare all fields against the other object
return (enableSSL == other.enableSSL &&
ssl_verifyPeer == other.ssl_verifyPeer &&
ssl_verifyHost == other.ssl_verifyHost &&
ssl_caInfo == other.ssl_caInfo &&
ssl_certBlob == other.ssl_certBlob);
}
};
using Headers = std::unordered_map<std::string, std::string>;
struct Request
{
std::string url;
Method method = Method::http_GET;
std::string body;
Headers headers;
Settings settings;
bool operator==(const Request &other) const
{
// Compare all fields against the other object
return (url == other.url &&
method == other.method &&
body == other.body &&
headers == other.headers &&
settings == other.settings);
}
};
struct Response
{
int returnCode = -1;
std::string content;
};
public:
CurlHttpClient(); // Default constructor
virtual ~CurlHttpClient() = default; // Default destructor
CurlHttpClient(const CurlHttpClient &obj) = delete; // Copy constructor
CurlHttpClient(CurlHttpClient &&obj) noexcept = delete; // Move constructor
CurlHttpClient &operator=(const CurlHttpClient &obj) = delete; // Copy assignment operator
CurlHttpClient &operator=(CurlHttpClient &&obj) noexcept = delete; // Move assignment operator
const Response &performRequest(const Request &request = {}); // Perform HTTP request
const Response &performRequest_nothrow(const Request &request = {}); // Perform HTTP request
const Request &getRequest() const; // Retrieves curl request
const Response &getResponse() const; // Retrieves curl response
protected:
mutable std::mutex m_mtx;
CURL *m_curl = nullptr;
curl_slist *m_headerList = nullptr;
Request m_request;
Response m_response;
private:
CURLcode setRequestOptions(); // Set cURL request options
static size_t write_callback(void *contents, // Callback for writing received data
size_t size,
size_t itemCount,
void *userData);
};
//--------------------------------------------------------------
/* Default constructor */
inline CurlHttpClient::CurlHttpClient()
{
CurlGlobalInitializer::init();
}
//--------------------------------------------------------------
/* Perform HTTP request */
inline const CurlHttpClient::Response &CurlHttpClient::performRequest(const Request &request)
{
std::lock_guard lock(m_mtx);
if (const Request default_req = {}; request != default_req)
m_request = request;
try
{
m_curl = curl_easy_init();
if (!m_curl)
throw std::runtime_error("unable to initialize curl library");
// Set request options
if (const auto res = setRequestOptions(); res != CURLE_OK)
throw std::runtime_error(std::format("ERROR: Failed to set up CURL options: {}", curl_easy_strerror(res)));
// Perform request
if (const auto res = curl_easy_perform(m_curl); res != CURLE_OK)
throw std::runtime_error(std::format("ERROR: curl_easy_perform() failed: {}", curl_easy_strerror(res)));
if (const auto res = curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, &m_response.returnCode); res != CURLE_OK)
throw std::runtime_error(std::format("ERROR: Failed to get content code: {}", curl_easy_strerror(res)));
}
catch (const std::exception &e)
{
m_response.returnCode = -1;
m_response.content = e.what();
}
// Free resources
if (m_curl)
{
curl_easy_cleanup(m_curl); // free the easy curl handle
m_curl = nullptr;
}
if (m_headerList)
{
curl_slist_free_all(m_headerList); // free the custom headers
m_curl = nullptr;
}
if (m_response.returnCode == -1)
throw std::runtime_error(m_response.content);
return m_response;
}
//--------------------------------------------------------------
/* Perform HTTP request */
inline const CurlHttpClient::Response &CurlHttpClient::performRequest_nothrow(const Request &request)
{
try
{
performRequest(request);
}
catch (const std::exception &e)
{
LogError() << e.what() << std::endl;
}
return m_response;
}
//--------------------------------------------------------------
/* Retrieves curl request */
inline const CurlHttpClient::Request &CurlHttpClient::getRequest() const
{
std::lock_guard lock(m_mtx);
return m_request;
}
//--------------------------------------------------------------
/* Retrieves curl response */
inline const CurlHttpClient::Response &CurlHttpClient::getResponse() const
{
std::lock_guard lock(m_mtx);
return m_response;
}
//--------------------------------------------------------------
/* Set cURL request options */
inline CURLcode CurlHttpClient::setRequestOptions()
{
// --- Common Options ---
// Set the target URL
if (const auto res = curl_easy_setopt(m_curl, CURLOPT_URL, m_request.url.c_str()); res != CURLE_OK)
return res;
// Set the write callback function
if (const auto res = curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, write_callback); res != CURLE_OK)
return res;
// Set the user data pointer for the callback (our content buffer)
if (const auto res = curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &m_response.content); res != CURLE_OK)
return res;
// Set custom headers if any
if (m_headerList)
{
// Prepare header list
for (const auto &[key, value] : m_request.headers)
{
const auto header = format("{0:}: {1:}", key, value);
m_headerList = curl_slist_append(m_headerList, header.c_str());
}
// Append headers to the request
if (const auto res = curl_easy_setopt(m_curl, CURLOPT_HTTPHEADER, m_headerList); res != CURLE_OK)
return res;
}
// Set the max time in seconds for the entire operation (including connection and transfer)
if (const auto res = curl_easy_setopt(m_curl, CURLOPT_TIMEOUT, m_request.settings.timeout.count()); res != CURLE_OK)
return res;
// --- SSL/TLS Options ---
// curl documentation recommends setting both for full control
if (m_request.settings.enableSSL)
{
// Enable peer certificate verification
if (const auto res = curl_easy_setopt(m_curl, CURLOPT_SSL_VERIFYPEER, 1L); res != CURLE_OK)
return res;
// Enable host name verification (prevents 'Man-in-the-middle' attacks)
if (const auto res = curl_easy_setopt(m_curl, CURLOPT_SSL_VERIFYHOST, 2L); res != CURLE_OK)
return res;
if (!m_request.settings.ssl_caInfo.empty())
{
// Optionally, set the path to a CA bundle file (often not needed
// if curl is built with a system-wide CA store)
if (const auto res = curl_easy_setopt(m_curl, CURLOPT_CAINFO, m_request.settings.ssl_caInfo.c_str()); res != CURLE_OK)
return res;
}
else if (!m_request.settings.ssl_certBlob.empty())
{
if (const auto res = curl_easy_setopt(m_curl, CURLOPT_SSLKEY_BLOB, &m_request.settings.ssl_certBlob); res != CURLE_OK)
return res;
}
}
else
{
// Disable verification (USE WITH CAUTION: Insecure!)
if (const auto res = curl_easy_setopt(m_curl, CURLOPT_SSL_VERIFYPEER, 0L); res != CURLE_OK)
return res;
if (const auto res = curl_easy_setopt(m_curl, CURLOPT_SSL_VERIFYHOST, 0L); res != CURLE_OK)
return res;
}
// --- Method-Specific Options ---
switch (m_request.method)
{
using enum Method;
case http_GET:
{
if (const auto res = curl_easy_setopt(m_curl, CURLOPT_HTTPGET, 1L); res != CURLE_OK)
return res;
break;
}
case http_POST:
{
if (const auto res = curl_easy_setopt(m_curl, CURLOPT_POST, 1L); res != CURLE_OK)
return res;
// Set the data to be sent
if (const auto res = curl_easy_setopt(m_curl, CURLOPT_POSTFIELDS, m_request.body.c_str()); res != CURLE_OK)
return res;
break;
}
case http_PUT:
{
if (const auto res = curl_easy_setopt(m_curl, CURLOPT_PUT, 1L); res != CURLE_OK)
return res;
if (const auto res = curl_easy_setopt(m_curl, CURLOPT_CUSTOMREQUEST, "PUT"); res != CURLE_OK)
return res;
if (const auto res = curl_easy_setopt(m_curl, CURLOPT_POSTFIELDS, m_request.body.c_str()); res != CURLE_OK)
return res;
break;
}
case http_DELETE:
{
if (const auto res = curl_easy_setopt(m_curl, CURLOPT_CUSTOMREQUEST, "DELETE"); res != CURLE_OK)
return res;
break;
}
}
return CURLE_OK;
}
//--------------------------------------------------------------
/* Callback for writing received data */
inline size_t CurlHttpClient::write_callback(void *contents, const size_t size, const size_t itemCount, void *userData)
{
// Total size of the incoming buffer
const auto realSize = size * itemCount;
// Append the received data to the content string
const auto &response = static_cast<std::string *>(userData);
response->append(static_cast<char *>(contents), realSize);
return realSize;
}
//--------------------------------------------------------------
/* --- */
//--------------------------------------------------------------
class CurlInfo
{
public:
CurlInfo(); // Default constructor
virtual ~CurlInfo() = default; // Default destructor
CurlInfo(const CurlInfo &obj) = delete; // Copy constructor
CurlInfo(CurlInfo &&obj) noexcept = delete; // Move constructor
CurlInfo &operator=(const CurlInfo &obj) = delete; // Copy assignment operator
CurlInfo &operator=(CurlInfo &&obj) noexcept = delete; // Move assignment operator
void toStream(std::ostream &stream); // Print cURL information to stream object
void print(); // Print cURL information to cout
std::string version;
uint32_t features;
bool ssl_support = false;
std::string ssl_version;
std::vector<std::string> availableProtocols;
};
//--------------------------------------------------------------
/* Default constructor */
inline CurlInfo::CurlInfo()
{
CurlGlobalInitializer::init();
// Retrieves information from the library
const auto info = curl_version_info(CURLVERSION_NOW);
version = info->version;
features = info->features;
ssl_support = info->features & CURL_VERSION_SSL;
ssl_version = info->ssl_version;
if (info->protocols)
{
for (const char *const *proto = info->protocols; *proto; ++proto)
availableProtocols.emplace_back(*proto);
}
}
//--------------------------------------------------------------
/* Print cURL information to stream object */
inline void CurlInfo::toStream(std::ostream &stream)
{
stream << "--- libcurl Version Info ---" << "\n";
stream << "Version : " << version << "\n";
stream << "Features (bitmask) : " << std::format("0x{0:X}", features) << "\n";
stream << "SSL/TLS support : " << ((ssl_support) ? std::format("**Yes** [{0:}]", ssl_version) : "No") << "\n";
if (!availableProtocols.empty())
{
stream << "Available protocols: ";
bool first = true;
for (const auto protocol : availableProtocols)
{
if (!first)
stream << ", ";
stream << protocol;
first = false;
}
stream << "\n";
}
}
//--------------------------------------------------------------
/* Print cURL information to cout */
inline void CurlInfo::print()
{
toStream(std::cout);
std::cout << std::flush;
}
//--------------------------------------------------------------
} // namespace sdi_ToolBox::communication

View File

@@ -0,0 +1,6 @@
#pragma once
/**
* @namespace sdi_ToolBox::comm
* @brief Communication protocols and binary handling.
*/

View File

@@ -0,0 +1,784 @@
//{{copyright}}
//{{version}}
//{{license}}
#pragma once
#include "../generic/crc.h"
#include <array>
#include <cstring>
#include <span>
#include <string>
/**
* @namespace sdi_ToolBox::comm::uBinaryFrame
* @brief Utilities for robust binary frame serialization, deserialization, and protocol handling.
*
* This namespace provides classes and constants to manage binary communication frames with automatic
* escaping, CRC calculation, and protocol validation. The supported frame format is:
* [SOF1][SOF2][SIZE][PAYLOAD][CRC16][EOF]
* where special bytes are escaped as needed.
*
* Main components:
* - @ref FrameReceiver : Receives and extracts a complete binary frame from a byte stream.
* - @ref MessageParser : Parses and validates a binary frame, providing typed access to the payload.
* - @ref MessageBuilder : Builds a binary message with CRC calculation and escaping.
* - @ref FramePacker : Packs a message into a complete frame ready for transmission (header, CRC, escaping, etc.).
*/
namespace sdi_ToolBox::comm::uBinaryFrame
{
constexpr uint8_t SOF1_ = 0xAA; // Start of Frame byte (0b10101010 - useful for bus synchronisation)
constexpr uint8_t SOF2_ = 0x55; // Start of Frame byte (0b01010101 - useful for bus synchronisation)
constexpr uint8_t EOF_ = 0x03; // End of Frame byte (End of Text code in ASCII table)
constexpr uint8_t ESC_ = 0x1B; // Escape byte (Escape code in ASCII table)
//--------------------------------------------------------------
/**
* @class FrameReceiver
* @brief Stateful receiver for extracting a complete binary frame from a byte stream.
*
* Handles frame synchronization, byte un-escaping, and buffering.
* The frame is considered complete when the protocol's end-of-frame byte is detected.
*
* @tparam BUFFER_SIZE Maximum size of the internal receive buffer.
*
* Usage:
* - Call push(byte) for each received byte.
* - When push() returns true or isFrameAvailable() is true, use getFrame() to access the frame data.
*
* @code
* FrameReceiver<128> receiver;
* for (uint8_t byte : incomingBytes) {
* if (receiver.push(byte)) {
* auto frame = receiver.getFrame();
* // Process frame...
*
* receiver.reset();
* }
* }
* @endcode
*/
template<size_t BUFFER_SIZE>
class FrameReceiver
{
enum class State : uint8_t
{
WAIT_SOF1,
WAIT_SOF2,
RECEIVE_DATA,
WAIT_EOF,
ESCAPE_NEXT,
END,
};
public:
FrameReceiver() = default; // Default constructor
~FrameReceiver() = default; // Default destructor
FrameReceiver(const FrameReceiver &obj) = default; // Copy constructor
FrameReceiver(FrameReceiver &&obj) noexcept = default; // Move constructor
FrameReceiver &operator=(const FrameReceiver &obj) = default; // Copy assignment operator
FrameReceiver &operator=(FrameReceiver &&obj) noexcept = default; // Move assignment operator
/**
* @brief Resets the receiver state and clears the internal buffer.
*
* After calling this method, the receiver is ready to process a new frame.
*/
void reset();
/**
* @brief Pushes a byte into the receiver buffer and updates the state machine.
* @param byte The received byte to process.
* @return true if a complete frame has been received and is available, false otherwise.
*
* @note If a frame is available, use getFrame() to access its content.
*/
[[nodiscard]] bool push(uint8_t byte);
/**
* @brief Checks if a complete frame is available in the buffer.
* @return true if a frame is available, false otherwise.
*/
[[nodiscard]] bool isFrameAvailable() const;
/**
* @brief Returns a span to the complete frame data.
* @return A span containing the frame bytes, or an empty span if no frame is available.
*
* @note The returned span is only valid until the next reset() or push().
*/
[[nodiscard]] std::span<const uint8_t> getFrame() const;
protected:
std::array<uint8_t, BUFFER_SIZE> m_buffer{}; // Receiver buffer
size_t m_index = 0; // Current index in the buffer
State m_state = State::WAIT_SOF1; // Current state of the receiver
private:
void appendByte(uint8_t byte); // Append a byte to the buffer
};
//--------------------------------------------------------------
template<size_t BUFFER_SIZE>
inline void FrameReceiver<BUFFER_SIZE>::reset()
{
m_index = 0;
m_state = State::WAIT_SOF1;
}
//--------------------------------------------------------------
template<size_t BUFFER_SIZE>
inline bool FrameReceiver<BUFFER_SIZE>::push(const uint8_t byte)
{
switch (m_state)
{
// Initial state: waiting for SOF1
case State::WAIT_SOF1:
{
if (byte == SOF1_)
{
m_index = 0;
m_state = State::WAIT_SOF2; // Next byte should be SOF2
}
break;
}
// Waiting for SOF2
case State::WAIT_SOF2:
{
if (byte == SOF2_)
m_state = State::RECEIVE_DATA; // Start receiving data
else
m_state = State::WAIT_SOF1; // Abort frame reception
break;
}
// Receiving data
case State::RECEIVE_DATA:
{
if (byte == ESC_)
m_state = State::ESCAPE_NEXT; // Next byte is escaped
else if (byte == SOF1_)
m_state = State::WAIT_SOF2; // Restart frame reception
else if (byte == SOF2_)
m_state = State::WAIT_SOF1; // Abort frame reception
else if (byte == EOF_)
{
m_state = State::END; // Frame complete
return true;
}
else
appendByte(byte);
break;
}
// Handling escaped byte
case State::ESCAPE_NEXT:
{
appendByte(byte);
m_state = State::RECEIVE_DATA; // Return to data reception
break;
}
// Frame complete
case State::END:
default:
return true;
}
return false;
}
//--------------------------------------------------------------
template<size_t BUFFER_SIZE>
inline bool FrameReceiver<BUFFER_SIZE>::isFrameAvailable() const
{
return m_state == State::END;
}
//--------------------------------------------------------------
template<size_t BUFFER_SIZE>
inline std::span<const uint8_t> FrameReceiver<BUFFER_SIZE>::getFrame() const
{
if (m_state == State::END)
return { m_buffer.data(), m_index };
return {};
}
//--------------------------------------------------------------
template<size_t BUFFER_SIZE>
inline void FrameReceiver<BUFFER_SIZE>::appendByte(const uint8_t byte)
{
if (m_index < BUFFER_SIZE)
m_buffer[m_index++] = byte;
}
//--------------------------------------------------------------
/* --- */
//--------------------------------------------------------------
/**
* @class MessageParser
* @brief Parses and validates a binary frame, providing typed access to the payload.
*
* Checks frame structure, size, CRC, and end-of-frame marker.
* Allows extraction of typed values or raw data from the payload.
*
* Usage:
* - Construct with a frame buffer.
* - Check validity with isValid() or getStatus().
* - Use get<T>(offset, value) to extract typed data from the payload.
*
* @code
* MessageParser parser(frame);
* if (parser.isValid()) {
* uint16_t id;
* parser.get(0, id);
* std::array<uint8_t, 8> data;
* parser.get(2, std::span<uint8_t>(data));
* // Use id and data...
* }
* @endcode
*/
class MessageParser
{
public:
enum class MessageStatus : uint8_t
{
VALID,
INVALID,
BAD_SIZE,
BAD_CRC,
};
public:
MessageParser() = delete; // Default constructor
~MessageParser() = default; // Default destructor
MessageParser(const MessageParser &obj) = default; // Copy constructor
MessageParser(MessageParser &&obj) noexcept = default; // Move constructor
MessageParser &operator=(const MessageParser &obj) = default; // Copy assignment operator
MessageParser &operator=(MessageParser &&obj) noexcept = default; // Move assignment operator
/**
* @brief Constructs a MessageParser and checks the integrity of the provided frame.
* @param buffer The buffer containing the frame to parse.
*/
explicit MessageParser(std::span<const uint8_t> buffer);
/**
* @brief Checks if the parsed message is valid.
* @return true if the message is valid, false otherwise.
*/
[[nodiscard]] bool isValid() const;
/**
* @brief Gets the current message validity status.
* @return The status as a MessageStatus enum value.
*/
[[nodiscard]] MessageStatus getStatus() const;
/**
* @brief Gets the message payload buffer.
* @return A span containing the payload bytes.
*/
[[nodiscard]] std::span<const uint8_t> getBuffer() const;
/**
* @brief Gets the size of the message payload.
* @return The size of the payload in bytes.
*/
[[nodiscard]] size_t size() const; // Get message payload size
/**
* @brief Extracts a value of type T from the message payload at the specified offset.
* @tparam T The type of the value to extract (POD type or std::span<uint8_t>).
* @param offset The offset in the payload to read from.
* @param value Reference to store the extracted value.
* @return The new offset after reading the value, or the original offset if reading failed.
*
* @note No exception is thrown. If extraction fails, value is not modified.
*/
template<class T>
[[nodiscard]] size_t get(size_t offset, T &value) const;
protected:
std::span<const uint8_t> m_buffer; // Message buffer
MessageStatus m_messageStatus = MessageStatus::INVALID; // Message validity status
private:
void messageCheck(); // Check message integrity
};
//--------------------------------------------------------------
/* Constructor */
inline MessageParser::MessageParser(const std::span<const uint8_t> buffer)
{
m_buffer = buffer;
messageCheck();
}
//--------------------------------------------------------------
inline bool MessageParser::isValid() const
{
return m_messageStatus == MessageStatus::VALID;
}
//--------------------------------------------------------------
/* Get message validity status */
inline MessageParser::MessageStatus MessageParser::getStatus() const
{
return m_messageStatus;
}
//--------------------------------------------------------------
/* Get message payload buffer */
inline std::span<const uint8_t> MessageParser::getBuffer() const
{
return m_buffer;
}
//--------------------------------------------------------------
/* Get message payload size */
inline size_t MessageParser::size() const
{
return m_buffer.size();
}
//--------------------------------------------------------------
template<class T>
inline size_t MessageParser::get(size_t offset, T &value) const
{
static_assert((std::is_standard_layout_v<T> && std::is_trivial_v<T>) || // POD type
std::is_same_v<T, std::span<uint8_t>> || // std::span<uint8_t> type
std::is_same_v<T, std::string>); // std::string type
if constexpr (std::is_standard_layout_v<T> && std::is_trivial_v<T>)
{
// POD type
constexpr size_t typeSize = sizeof(T);
if (offset + typeSize <= m_buffer.size())
{
std::memcpy(&value, m_buffer.data() + offset, typeSize);
return offset + typeSize; // Return new offset
}
}
else if constexpr (std::is_same_v<T, std::span<uint8_t>>)
{
// std::span<uint8_t> type
if (offset + value.size() <= m_buffer.size())
{
std::memcpy(value.data(), m_buffer.data() + offset, value.size());
return offset + value.size(); // Return new offset
}
}
else if constexpr (std::is_same_v<T, std::string>)
{
// std::string type
uint8_t strSize;
offset = get(offset, strSize);
value.resize(strSize);
std::span<uint8_t> strSpan(reinterpret_cast<uint8_t *>(value.data()), strSize);
offset = get(offset, strSpan);
}
return offset; // Unable to read value, return original offset
}
//--------------------------------------------------------------
/* Check message integrity */
inline void MessageParser::messageCheck()
{
/* Message format : [SOF1(1)][SOF2(1)][SIZE(1)][PAYLOAD(n)][CRC16(2)][EOF(1)] */
// Check SIZE
const auto size = m_buffer[0];
if (constexpr size_t CRCSize = 2; m_buffer.size() != CRCSize + size + sizeof(size))
{
m_messageStatus = MessageStatus::BAD_SIZE;
return;
}
// Check CRC16
const auto loCRC = *(m_buffer.rbegin() + 1);
const auto hiCRC = *m_buffer.rbegin();
const uint16_t frameCRC = static_cast<uint16_t>(hiCRC << 8) | static_cast<uint16_t>(loCRC);
const uint16_t computedCRC = generic::CRC16_modbus::computeCRC(m_buffer.subspan(1, m_buffer.size() - 3));
if (frameCRC != computedCRC)
{
m_messageStatus = MessageStatus::BAD_CRC;
return;
}
m_buffer = m_buffer.subspan(1, size);
m_messageStatus = MessageStatus::VALID;
}
//--------------------------------------------------------------
/* --- */
//--------------------------------------------------------------
/**
* @class MessageBuilderHelper
* @brief Utility class to simplify the usage of MessageBuilder templates.
*
* This helper provides convenient methods and type aliases to work with MessageBuilder
* instances without exposing template parameters in function signatures.
*/
class MessageBuilderHelper
{
public:
MessageBuilderHelper() = default; // Default constructor
virtual ~MessageBuilderHelper() = default; // Default destructor
MessageBuilderHelper(const MessageBuilderHelper &obj) = default; // Copy constructor
MessageBuilderHelper(MessageBuilderHelper &&obj) noexcept = default; // Move constructor
MessageBuilderHelper &operator=(const MessageBuilderHelper &obj) = default; // Copy assignment operator
MessageBuilderHelper &operator=(MessageBuilderHelper &&obj) noexcept = default; // Move assignment operator
/**
* @brief Gets the current message buffer as a span.
* @return A span containing the current message bytes.
*/
[[nodiscard]] virtual std::span<const uint8_t> getBuffer() const = 0;
/**
* @brief Checks if the message buffer is full.
* @return true if the buffer is full, false otherwise.
*/
[[nodiscard]] virtual bool isFull() const = 0;
/**
* @brief Gets the current size of the message buffer.
* @return The number of bytes currently in the message buffer.
*/
[[nodiscard]] virtual size_t getBufferSize() const = 0;
/**
* @brief Gets the current CRC16 value of the message.
* @return The current CRC16 value.
*/
[[nodiscard]] virtual uint16_t getCRC() const = 0;
};
//--------------------------------------------------------------
/* --- */
//--------------------------------------------------------------
/**
* @class MessageBuilder
* @brief Builds a binary message payload with CRC calculation and escaping support.
*
* Supports appending POD types or byte spans, and computes CRC incrementally.
* Provides methods to reset, append, and retrieve the current buffer and CRC.
*
* @tparam BUFFER_SIZE Maximum size of the internal message buffer.
*
* Usage:
* - Use append() or operator<< to add data.
* - Retrieve the buffer with getBuffer() and CRC with getCRC().
*
* @code
* MessageBuilder<64> builder;
* builder << uint16_t(0x1234) << std::span<const uint8_t>(data, dataLen);
* auto buffer = builder.getBuffer();
* auto crc = builder.getCRC();
* @endcode
*/
template<size_t BUFFER_SIZE>
class MessageBuilder : public MessageBuilderHelper
{
public:
MessageBuilder(); // Default constructor
virtual ~MessageBuilder() = default; // Default destructor
MessageBuilder(const MessageBuilder &obj) = default; // Copy constructor
MessageBuilder(MessageBuilder &&obj) noexcept = default; // Move constructor
MessageBuilder &operator=(const MessageBuilder &obj) = default; // Copy assignment operator
MessageBuilder &operator=(MessageBuilder &&obj) noexcept = default; // Move assignment operator
/**
* @brief Resets the message builder to an empty state.
* @return Reference to the MessageBuilder for chaining.
*/
MessageBuilder &reset(); // Reset the message builder
/**
* @brief Appends a value of type T to the message buffer.
* @tparam T The type of the value to append (POD type or std::span<uint8_t>).
* @param value The value to append.
* @return Reference to the MessageBuilder for chaining.
*
* @note If appending the value would exceed the buffer size, it is ignored.
*/
template<class T>
MessageBuilder &append(const T &value); // Append value of type T to the message
/**
* @brief Overloads the << operator to append a value of type T to the message buffer.
* @tparam T The type of the value to append (POD type or std::span<uint8_t>).
* @param value The value to append.
* @return Reference to the MessageBuilder for chaining.
*
* @note If appending the value would exceed the buffer size, it is ignored.
*/
template<class T>
MessageBuilder &operator<<(const T &value);
[[nodiscard]] std::span<const uint8_t> getBuffer() const override;
[[nodiscard]] bool isFull() const override;
[[nodiscard]] size_t getBufferSize() const override;
[[nodiscard]] uint16_t getCRC() const override;
protected:
std::array<uint8_t, BUFFER_SIZE> m_buffer{}; // Receiver buffer
size_t m_index = 0; // Current index in the buffer
generic::CRC16_modbus m_CRC; // Current CRC value
};
//--------------------------------------------------------------
template<size_t BUFFER_SIZE>
inline MessageBuilder<BUFFER_SIZE>::MessageBuilder()
{
m_CRC.init();
}
//--------------------------------------------------------------
template<size_t BUFFER_SIZE>
inline MessageBuilder<BUFFER_SIZE> &MessageBuilder<BUFFER_SIZE>::reset()
{
m_index = 0;
m_CRC.init();
return *this; // Return reference to self for chaining
}
//--------------------------------------------------------------
template<size_t BUFFER_SIZE>
template<class T>
inline MessageBuilder<BUFFER_SIZE> &MessageBuilder<BUFFER_SIZE>::append(const T &value)
{
static_assert((std::is_standard_layout_v<T> && std::is_trivial_v<T>) || // POD type
std::is_same_v<T, std::span<uint8_t>> || // std::span<uint8_t> type
std::is_same_v<T, std::span<const uint8_t>> || // std::span<const uint8_t> type
std::is_same_v<T, std::string> || // std::string type
std::is_same_v<T, const std::string>); // const std::string type
if constexpr (std::is_standard_layout_v<T> && std::is_trivial_v<T>)
{
// POD type
constexpr size_t typeSize = sizeof(T);
if (m_index + typeSize <= BUFFER_SIZE)
{
std::array<uint8_t, typeSize> dataBuffer;
std::memcpy(dataBuffer.data(), &value, typeSize);
std::memcpy(m_buffer.data() + m_index, dataBuffer.data(), dataBuffer.size());
m_CRC.update(dataBuffer);
m_index += typeSize;
}
}
else if constexpr (std::is_same_v<T, std::span<uint8_t>> ||
std::is_same_v<T, std::span<const uint8_t>>)
{
// std::span<uint8_t> type
if (m_index + value.size() <= BUFFER_SIZE)
{
std::memcpy(m_buffer.data() + m_index, value.data(), value.size());
m_CRC.update(value);
m_index += value.size();
}
}
else if constexpr (std::is_same_v<T, std::string> || std::is_same_v<T, const std::string>)
{
// std::string type
if (m_index + (value.size() + sizeof(uint8_t)) <= BUFFER_SIZE)
{
append(static_cast<uint8_t>(value.size()));
std::memcpy(m_buffer.data() + m_index, value.data(), value.size());
m_CRC.update(std::span(reinterpret_cast<const uint8_t *>(value.data()), value.size()));
m_index += value.size();
}
}
return *this; // Return reference to self for chaining
}
//--------------------------------------------------------------
template<size_t BUFFER_SIZE>
template<class T>
inline MessageBuilder<BUFFER_SIZE> &MessageBuilder<BUFFER_SIZE>::operator<<(const T &value)
{
append(value);
return *this; // Return reference to self for chaining
}
//--------------------------------------------------------------
template<size_t BUFFER_SIZE>
inline std::span<const uint8_t> MessageBuilder<BUFFER_SIZE>::getBuffer() const
{
return { m_buffer.data(), m_index };
}
//--------------------------------------------------------------
template<size_t BUFFER_SIZE>
inline bool MessageBuilder<BUFFER_SIZE>::isFull() const
{
return m_index >= BUFFER_SIZE;
}
//--------------------------------------------------------------
template<size_t BUFFER_SIZE>
inline size_t MessageBuilder<BUFFER_SIZE>::getBufferSize() const
{
return m_index;
}
//--------------------------------------------------------------
template<size_t BUFFER_SIZE>
inline uint16_t MessageBuilder<BUFFER_SIZE>::getCRC() const
{
return m_CRC.getCRC();
}
//--------------------------------------------------------------
/* --- */
//--------------------------------------------------------------
/**
* @class FramePacker
* @brief Packs a message payload into a complete binary frame ready for transmission.
*
* Adds protocol headers, escapes special bytes, appends CRC and end-of-frame marker.
* Ensures the packed frame fits in the provided buffer size.
*
* @tparam BUFFER_SIZE Maximum size of the output frame buffer.
*
* Usage:
* - Call packMessage(payload, crc) to build the frame.
* - Use isValid() to check for overflow.
* - Retrieve the packed frame with getPackedFrame().
*
* @code
* FramePacker<256> packer;
* if (packer.packMessage(payload, crc)) {
* auto frame = packer.getPackedFrame();
* // Send frame...
* }
* @endcode
*/
template<size_t BUFFER_SIZE>
class FramePacker
{
static constexpr size_t CRC_SIZE = 4; // CRC16(2 x2) --> (CRC is 4 bytes to support escaped CRC)
public:
FramePacker() = default; // Default constructor
explicit FramePacker(std::span<const uint8_t> message, uint16_t crc); // Constructor
~FramePacker() = default; // Default destructor
FramePacker(const FramePacker &obj) = default; // Copy constructor
FramePacker(FramePacker &&obj) noexcept = default; // Move constructor
FramePacker &operator=(const FramePacker &obj) = default; // Copy assignment operator
FramePacker &operator=(FramePacker &&obj) noexcept = default; // Move assignment operator
/**
* @brief Packs the input message into a complete frame with headers, CRC, and escaping.
* @param message The message payload to pack.
* @param crc The CRC16 value to append to the frame.
* @return true if packing was successful without overflow, false otherwise.
*/
bool packMessage(std::span<const uint8_t> message, uint16_t crc);
/**
* @brief Checks if the packed frame is valid (no overflow occurred).
* @return true if the packed frame is valid, false otherwise.
*/
[[nodiscard]] bool isValid() const;
/**
* @brief Gets the packed frame buffer as a span.
* @return A span containing the packed frame bytes.
*/
[[nodiscard]] std::span<const uint8_t> getPackedFrame() const;
protected:
std::array<uint8_t, BUFFER_SIZE> m_frame{}; // Output buffer
size_t m_index = 0; // Current index in output buffer
std::array<uint8_t, CRC_SIZE> m_CRCBuffer{}; // CRC buffer with escaping
size_t m_CRCSize = 0; // Current size of CRC buffer with escaping
bool m_overflow = false; // Flag indicating if overflow occurred during packing
private:
void appendByte(uint8_t byte); // Append byte with escaping to output buffer
void appendRawByte(uint8_t byte); // Append raw byte to output buffer
void packCRC(uint16_t crc); // Pack CRC into CRC buffer with escaping
};
//--------------------------------------------------------------
template<size_t BUFFER_SIZE>
inline FramePacker<BUFFER_SIZE>::FramePacker(const std::span<const uint8_t> message, const uint16_t crc)
{
packMessage(message, crc);
}
//--------------------------------------------------------------
template<size_t BUFFER_SIZE>
inline bool FramePacker<BUFFER_SIZE>::packMessage(const std::span<const uint8_t> message, const uint16_t crc)
{
// Reset state
m_index = 0;
m_overflow = false;
// Prepare CRC buffer with escaping
packCRC(crc);
// Append header
appendRawByte(SOF1_); // Append SOF1
appendRawByte(SOF2_); // Append SOF2
appendByte(static_cast<uint8_t>(message.size())); // Append payload size
// Append payload
for (const auto &byte : message)
appendByte(byte);
// Append CRC
for (size_t i = 0; i < m_CRCSize; i++)
appendRawByte(m_CRCBuffer[i]);
// Append EOF
appendRawByte(EOF_);
return !m_overflow; // Return true if packing was successful
}
//--------------------------------------------------------------
template<size_t BUFFER_SIZE>
inline bool FramePacker<BUFFER_SIZE>::isValid() const
{
return !m_overflow;
}
//--------------------------------------------------------------
template<size_t BUFFER_SIZE>
inline std::span<const uint8_t> FramePacker<BUFFER_SIZE>::getPackedFrame() const
{
return std::span<const uint8_t>(m_frame.data(), m_index);
}
//--------------------------------------------------------------
template<size_t BUFFER_SIZE>
inline void FramePacker<BUFFER_SIZE>::appendByte(const uint8_t byte)
{
if (byte == SOF1_ || byte == SOF2_ || byte == EOF_ || byte == ESC_)
{
appendRawByte(ESC_); // Append escape byte
}
appendRawByte(byte); // Append actual byte
}
//--------------------------------------------------------------
template<size_t BUFFER_SIZE>
inline void FramePacker<BUFFER_SIZE>::appendRawByte(const uint8_t byte)
{
if (m_index < BUFFER_SIZE)
m_frame[m_index++] = byte;
else
m_overflow = true;
}
//--------------------------------------------------------------
template<size_t BUFFER_SIZE>
inline void FramePacker<BUFFER_SIZE>::packCRC(const uint16_t crc)
{
m_CRCSize = 0;
const uint8_t loCRC = static_cast<uint8_t>(crc & 0x00FF);
const uint8_t hiCRC = static_cast<uint8_t>((crc >> 8) & 0x00FF);
if (loCRC == SOF1_ || loCRC == SOF2_ || loCRC == EOF_ || loCRC == ESC_)
m_CRCBuffer[m_CRCSize++] = ESC_;
m_CRCBuffer[m_CRCSize++] = loCRC;
if (hiCRC == SOF1_ || hiCRC == SOF2_ || hiCRC == EOF_ || hiCRC == ESC_)
m_CRCBuffer[m_CRCSize++] = ESC_;
m_CRCBuffer[m_CRCSize++] = hiCRC;
}
//--------------------------------------------------------------
} // namespace sdi_ToolBox::comm::uBinaryFrame

View File

@@ -0,0 +1,84 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <cstdint>
#include <string>
namespace sdi_toolBox::console::ANSI
{
//--------------------------------------------------------------
class EscapeCommand
{
public:
enum class Color : uint8_t
{
Black = 0,
Red,
Green,
Yellow,
Blue,
Magenta,
Cyan,
White,
};
static constexpr uint8_t LIGHT = 0x01 << 0; // 0x01
static constexpr uint8_t BRIGHT = 0x01 << 1; // 0x02
static constexpr uint8_t DIM = 0x01 << 2; // 0x04
static constexpr uint8_t UNDERLINE = 0x01 << 3; // 0x08
static constexpr uint8_t BLINK = 0x01 << 4; // 0x10
static constexpr uint8_t REVERSE = 0x01 << 5; // 0x20
public:
static std::string clear();
static std::string get(const Color foregroundColor,
const uint8_t foregroundStyle = 0,
const Color backgroundColor = Color::Black,
const uint8_t backgroundStyle = 0);
};
//--------------------------------------------------------------
inline std::string EscapeCommand::clear()
{
return "\x1b[0m";
}
//--------------------------------------------------------------
inline std::string EscapeCommand::get(const Color foregroundColor, const uint8_t foregroundStyle, const Color backgroundColor, const uint8_t backgroundStyle)
{
std::string command = "\x1b[";
int foregroundColorValue = static_cast<int>(foregroundColor) + 30;
if (foregroundStyle & LIGHT)
foregroundColorValue += 60;
command += std::to_string(foregroundColorValue) + ";";
int backgroundColorValue = static_cast<int>(backgroundColor) + 40;
if (backgroundStyle & LIGHT)
backgroundColorValue += 60;
command += std::to_string(backgroundColorValue);
if (foregroundStyle & BRIGHT)
command += ";1";
if (foregroundStyle & DIM)
command += ";2";
if (foregroundStyle & UNDERLINE)
command += ";4";
if (foregroundStyle & BLINK)
command += ";5";
if (foregroundStyle & REVERSE)
command += ";7";
command += "m";
return command;
}
//--------------------------------------------------------------
} // namespace sdi_toolBox::console::ANSI

View File

@@ -0,0 +1,152 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <string>
#include <vector>
namespace sdi_toolBox::console
{
//--------------------------------------------------------------
class ConsoleTable
{
public:
using Row = std::vector<std::string>;
using ColumnWidths = std::vector<size_t>;
public:
ConsoleTable() = default; // Constructor
virtual ~ConsoleTable() = default; // Destructor
ConsoleTable(const ConsoleTable &other) = delete; // Copy constructor
ConsoleTable(ConsoleTable &&other) noexcept = delete; // Move constructor
ConsoleTable &operator=(const ConsoleTable &other) = delete; // Copy assignment
ConsoleTable &operator=(ConsoleTable &&other) noexcept = delete; // Move assignment
void setHeaders(const Row &headers); // Set table headers
void addRow(const Row &row); // Add a row to the table
[[nodiscard]] std::string render() const; // Render the table as a string
protected:
Row m_headers; // Table headers
std::vector<Row> m_rows; // Table rows
size_t m_padding = 2; // Padding between columns
private:
[[nodiscard]] ColumnWidths calculateColumnWidths() const; // Calculate column widths
[[nodiscard]] static std::string drawSeparator(const ColumnWidths &columnWidths); // Draw a separator line (+---+---+---+)
[[nodiscard]] static std::string drawRow(const Row &row, // Draw a single row
const ColumnWidths &columnWidths);
};
//--------------------------------------------------------------
/* Set table headers */
inline void ConsoleTable::setHeaders(const Row &headers)
{
m_headers = headers;
}
//--------------------------------------------------------------
/* Add a row to the table */
inline void ConsoleTable::addRow(const Row &row)
{
m_rows.push_back(row);
}
//--------------------------------------------------------------
/* Render the table as a string */
inline std::string ConsoleTable::render() const
{
// Calculate column widths
const auto columnWidths = calculateColumnWidths();
// Initialize the output string
std::string output;
// Draw the top separator
output += drawSeparator(columnWidths);
// Draw the headers
output += drawRow(m_headers, columnWidths);
// Draw the separator between headers and data
output += drawSeparator(columnWidths);
// Draw the data rows
for (const auto &row : m_rows)
{
output += drawRow(row, columnWidths);
}
// Draw the bottom separator
output += drawSeparator(columnWidths);
return output;
}
//--------------------------------------------------------------
/* Calculate column widths */
inline ConsoleTable::ColumnWidths ConsoleTable::calculateColumnWidths() const
{
// Determine the number of columns (based on headers or first row)
const auto numColumns = m_headers.empty() ? (m_rows.empty() ? 0 : m_rows[0].size()) : m_headers.size();
// Initialize column widths
ColumnWidths widths(numColumns, 0);
// Calculate widths based on headers
for (size_t i = 0; i < m_headers.size() && i < numColumns; ++i)
{
widths[i] = std::max(widths[i], m_headers[i].length() + m_padding);
}
// Calculate widths based on rows
for (const auto &row : m_rows)
{
for (size_t i = 0; i < row.size() && i < numColumns; ++i)
{
widths[i] = std::max(widths[i], row[i].length() + m_padding);
}
}
return widths;
}
//--------------------------------------------------------------
/* Draw a separator line (+---+---+---+) */
inline std::string ConsoleTable::drawSeparator(const ColumnWidths &columnWidths)
{
std::string output;
output += "+";
for (const auto &width : columnWidths)
{
output += std::string(width, '-') + "+";
}
output += "\n";
return output;
}
//--------------------------------------------------------------
/* Draw a single row */
inline std::string ConsoleTable::drawRow(const Row &row, const ColumnWidths &columnWidths)
{
std::string output;
output += "|";
for (size_t i = 0; i < columnWidths.size(); ++i)
{
const auto cellContent = (i < row.size()) ? row[i] : "";
output += " " + cellContent;
// Add padding spaces
const size_t paddingSpaces = columnWidths[i] - cellContent.length() - 1;
output += std::string(paddingSpaces, ' ');
output += "|";
}
output += "\n";
return output;
}
//--------------------------------------------------------------
} // namespace sdi_toolBox::console

View File

@@ -0,0 +1,124 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#ifdef _WIN32
# include <Windows.h>
#endif // defined WIN32
#include <iostream>
#include <memory>
namespace sdi_toolBox::logs
{
//--------------------------------------------------------------
class Win32Console
{
public:
static void initConsole(); // Init application console and attach debug console under MSW
static void releaseConsole(); // Release application console
public:
virtual ~Win32Console(); // Default destructor
Win32Console(const Win32Console &obj) = delete; // Copy constructor
Win32Console(Win32Console &&obj) noexcept = delete; // Move constructor
Win32Console &operator=(const Win32Console &obj) = delete; // Copy assignment operator
Win32Console &operator=(Win32Console &&obj) noexcept = delete; // Move assignment operator
static bool hasAttachedConsole(); // Returns true if console is attached, false otherwise
protected:
static inline std::unique_ptr<Win32Console> m_singleton;
Win32Console(); // Default constructor
FILE *m_stdoutFile; // Reopened stdout file pointer
FILE *m_stderrFile; // Reopened stderr file pointer
};
//--------------------------------------------------------------
/* Init application console and attach debug console under MSW */
inline void Win32Console::initConsole()
{
#ifndef _WIN32
# error This calss is only available under Windows systems
#endif
if (!m_singleton)
m_singleton = std::unique_ptr<Win32Console>(new Win32Console());
}
//--------------------------------------------------------------
/* Release application console */
inline void Win32Console::releaseConsole()
{
if (m_singleton)
m_singleton.reset();
}
//--------------------------------------------------------------
/* Default constructor */
inline Win32Console::Win32Console()
{
#ifdef _WIN32
bool consoleIsCreated = false;
// Try to attach application to the current console
AttachConsole(ATTACH_PARENT_PROCESS);
if (!GetConsoleWindow()) // No console was available
{
// Create console and attach application to it
if (!AllocConsole())
throw std::logic_error("Unable to attach application to debug console"); // Error during creating console
consoleIsCreated = true;
}
// Reopen stdout and stderr streams to console window
if (freopen_s(&m_stdoutFile, "CONOUT$", "w", stdout) != 0)
throw std::logic_error("Unable to reopen stdout"); // Error during reopen on stdout
if (freopen_s(&m_stderrFile, "CONOUT$", "w", stderr) != 0)
throw std::logic_error("Unable to reopen stderr"); // Error during reopen on stderr
std::cout.clear();
std::cerr.clear();
if (!consoleIsCreated)
std::cout << std::endl; // Add a new line if console was already existing
#endif
}
//--------------------------------------------------------------
/* Default destructor */
inline Win32Console::~Win32Console()
{
#ifdef _WIN32
std::cout.clear();
std::cerr.clear();
// Free console
FreeConsole();
// Close reopened stdout and stderr streams
(void)fclose(m_stdoutFile);
(void)fclose(m_stderrFile);
#endif
}
//--------------------------------------------------------------
/* Returns true if console is attached, false otherwise */
inline bool Win32Console::hasAttachedConsole()
{
#ifdef _WIN32
if (GetConsoleWindow())
return true;
#endif
return false;
}
//--------------------------------------------------------------
} // namespace sdi_toolBox::logs

View File

@@ -0,0 +1,81 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <openssl/evp.h>
#include <span>
#include <vector>
namespace sdi_toolBox::crypto
{
//--------------------------------------------------------------
class Base64
{
public:
Base64() = default; // Default constructor
virtual ~Base64() = default; // Default destructor
Base64(const Base64 &obj) = delete; // Copy constructor
Base64(Base64 &&obj) noexcept = delete; // Move constructor
Base64 &operator=(const Base64 &obj) = delete; // Copy assignment operator
Base64 &operator=(Base64 &&obj) noexcept = delete; // Move assignment operator
static std::string encode(const std::span<uint8_t> &binary_data); // Encodes binary data into a Base64 string
static std::vector<uint8_t> decode(const std::string &base64_string); // Decodes a Base64 string into binary data
};
//--------------------------------------------------------------
/* Encodes binary data into a Base64 string */
inline std::string Base64::encode(const std::span<uint8_t> &binary_data)
{
if (binary_data.empty())
return "";
// Calculate the length of the encoded data
const size_t output_len_max = EVP_ENCODE_LENGTH(binary_data.size());
// Allocate output buffer (with null terminator)
std::vector<char> output_buffer(output_len_max + 1, 0);
// OpenSSL encoding
const auto final_len = EVP_EncodeBlock(reinterpret_cast<uint8_t *>(output_buffer.data()),
binary_data.data(),
binary_data.size());
if (final_len < 0)
throw std::runtime_error("Error: Base64 encoding failed");
return std::string(output_buffer.data());
}
//--------------------------------------------------------------
/* Decodes a Base64 string into binary data */
inline std::vector<uint8_t> Base64::decode(const std::string &base64_string)
{
if (base64_string.empty())
return {};
// Calculate the length of the decoded data
const auto output_len_max = EVP_DECODE_LENGTH(base64_string.size());
// Allocate output buffer
std::vector<uint8_t> output_buffer(output_len_max);
// OpenSSL decoding
const auto final_len = EVP_DecodeBlock(output_buffer.data(),
reinterpret_cast<const unsigned char *>(base64_string.data()),
static_cast<int>(base64_string.size()));
if (final_len < 0)
throw std::runtime_error("Error: Base64 decoding failed: Invalid data");
output_buffer.resize(final_len);
return output_buffer;
}
//--------------------------------------------------------------
} // namespace sdi_toolBox::crypto

View File

@@ -0,0 +1,71 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <span>
#include <string>
#include <vector>
namespace sdi_toolBox::crypto
{
//--------------------------------------------------------------
class Data8
{
public:
Data8() = default; // Default constructor
explicit Data8(const std::string &data); // Constructor from string
explicit Data8(const std::span<const uint8_t> &data); // Constructor from byte span
virtual ~Data8() = default; // Default destructor
Data8(const Data8 &obj) = delete; // Copy constructor
Data8(Data8 &&obj) noexcept = delete; // Move constructor
Data8 &operator=(const Data8 &obj) = delete; // Copy assignment operator
Data8 &operator=(Data8 &&obj) noexcept = delete; // Move assignment operator
[[nodiscard]] std::string getString() const; // Get data as string
[[nodiscard]] std::span<const uint8_t> getBytes() const; // Get data as byte span
[[nodiscard]] size_t getSize() const; // Get data size
protected:
std::vector<uint8_t> m_data; // Raw data storage
};
//--------------------------------------------------------------
/* Constructor from string */
inline Data8::Data8(const std::string &data)
{
m_data = std::vector<uint8_t>(data.begin(), data.end());
}
//--------------------------------------------------------------
inline Data8::Data8(const std::span<const uint8_t> &data)
{
m_data = std::vector<uint8_t>(data.begin(), data.end());
}
//--------------------------------------------------------------
/* Get data as string */
inline std::string Data8::getString() const
{
return std::string(m_data.begin(), m_data.end());
}
//--------------------------------------------------------------
/* Get data as byte span */
inline std::span<const uint8_t> Data8::getBytes() const
{
return m_data;
}
//--------------------------------------------------------------
/* Get data size */
inline size_t Data8::getSize() const
{
return m_data.size();
}
//--------------------------------------------------------------
} // namespace sdi_toolBox::crypto

View File

@@ -0,0 +1,78 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <filesystem>
#include <openssl/evp.h>
#include <span>
#include <string>
namespace sdi_toolBox::crypto
{
//--------------------------------------------------------------
class DigitalHash
{
public:
DigitalHash() = default; // Default constructor
virtual ~DigitalHash() = default; // Default destructor
DigitalHash(const DigitalHash &obj) = delete; // Copy constructor
DigitalHash(DigitalHash &&obj) noexcept = delete; // Move constructor
DigitalHash &operator=(const DigitalHash &obj) = delete; // Copy assignment operator
DigitalHash &operator=(DigitalHash &&obj) noexcept = delete; // Move assignment operator
static std::string calculateDataHash(const std::span<const uint8_t> &data, const EVP_MD *md_type); // Calculate digital hash from data buffer
};
//--------------------------------------------------------------
/* Calculate digital hash from data buffer */
inline std::string DigitalHash::calculateDataHash(const std::span<const uint8_t> &data, const EVP_MD *md_type)
{
// Initialize OpenSSL digest context
EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
if (!mdctx)
throw std::runtime_error("Error: Failed to create EVP_MD_CTX");
// Initialize digest operation
if (EVP_DigestInit_ex(mdctx, md_type, nullptr) != 1)
{
EVP_MD_CTX_free(mdctx);
throw std::runtime_error("Error: EVP_DigestInit_ex failed");
}
// Update digest with data
if (EVP_DigestUpdate(mdctx, data.data(), data.size()) != 1)
{
EVP_MD_CTX_free(mdctx);
throw std::runtime_error("Error: EVP_DigestUpdate failed");
}
// Finalize digest computation
std::vector<uint8_t> hash(EVP_MD_size(md_type));
unsigned int hash_len = 0;
if (EVP_DigestFinal_ex(mdctx, hash.data(), &hash_len) != 1)
{
EVP_MD_CTX_free(mdctx);
throw std::runtime_error("Error: EVP_DigestFinal_ex failed");
}
// Clean up
EVP_MD_CTX_free(mdctx);
// Convert hash to hexadecimal string
std::string hash_hex;
for (unsigned int i = 0; i < hash_len; ++i)
hash_hex += std::format("{:02x}", hash[i]);
return hash_hex;
}
//--------------------------------------------------------------
} // namespace sdi_toolBox::crypto

View File

@@ -0,0 +1,255 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "data.h"
#include <filesystem>
#include <fstream>
#include <memory>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <span>
#include <string>
#include <vector>
namespace sdi_toolBox::crypto
{
//--------------------------------------------------------------
class DigitalSign
{
// Custom deleter for EVP_PKEY to ensure it's automatically freed
struct EVP_PKEY_Deleter
{
void operator()(EVP_PKEY *p) const
{
if (p)
{
EVP_PKEY_free(p);
}
}
};
using pEVP_PKEY = std::unique_ptr<EVP_PKEY, EVP_PKEY_Deleter>;
struct BIO_Deleter
{
void operator()(BIO *b) const
{
if (b)
{
BIO_free(b);
}
}
};
using pBIO = std::unique_ptr<BIO, BIO_Deleter>;
struct EVP_MD_CTX_Deleter
{
void operator()(EVP_MD_CTX *ctx) const
{
if (ctx)
{
EVP_MD_CTX_free(ctx);
}
}
};
using pEVP_MD_CTX = std::unique_ptr<EVP_MD_CTX, EVP_MD_CTX_Deleter>;
public:
DigitalSign() = default; // Default constructor
virtual ~DigitalSign() = default; // Default destructor
DigitalSign(const DigitalSign &obj) = delete; // Copy constructor
DigitalSign(DigitalSign &&obj) noexcept = delete; // Move constructor
DigitalSign &operator=(const DigitalSign &obj) = delete; // Copy assignment operator
DigitalSign &operator=(DigitalSign &&obj) noexcept = delete; // Move assignment operator
void loadPEMKeyFromFile(const std::filesystem::path &filepath, bool is_private); // Load key from PEM file
void loadPEMKeyFromMemory(const std::string &key, bool is_private); // Load key from memory
std::vector<uint8_t> sign(const Data8 &data, const EVP_MD *digest_type = EVP_sha256()) const; // Sign data with private key
std::string signHex(const Data8 &data, const EVP_MD *digest_type = EVP_sha256()) const; // Sign data with private key
bool verify(const Data8 &data, const std::span<const uint8_t> &signature, const EVP_MD *digest_type = EVP_sha256()) const; // Verify signature with public key
bool verify(const Data8 &data, const std::string &signature, const EVP_MD *digest_type = EVP_sha256()) const; // Verify signature with public key
protected:
pEVP_PKEY m_privateKey;
pEVP_PKEY m_publicKey;
private:
static std::vector<uint8_t> hexToBytes(const std::string &hexString); // Converts a hexadecimal string into a vector of bytes
static std::string bytesToHex(const std::span<const uint8_t> &bytes); // Converts a span of bytes into a hexadecimal string representation
};
//--------------------------------------------------------------
/* Load key from PEM file */
inline void DigitalSign::loadPEMKeyFromFile(const std::filesystem::path &filepath, const bool is_private)
{
std::ifstream file(filepath, std::ifstream::binary);
if (!file.is_open())
throw std::runtime_error("Error: Could not open file " + filepath.string());
const std::string key((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
loadPEMKeyFromMemory(key, is_private);
}
//--------------------------------------------------------------
/* Load key from memory */
inline void DigitalSign::loadPEMKeyFromMemory(const std::string &key, const bool is_private)
{
if (key.empty())
throw std::runtime_error("Error: Input stream is empty or could not be read");
// Create a memory BIO (Basic Input/Output) for reading the key
const auto bio = static_cast<pBIO>(BIO_new_mem_buf(key.data(), static_cast<int>(key.size())));
if (!bio)
throw std::runtime_error("Error: Failed to create memory BIO");
// Use the BIO to read the key
if (is_private)
{
m_privateKey = static_cast<pEVP_PKEY>(PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
if (!m_privateKey)
throw std::runtime_error("Error: Failed to read private key from memory buffer");
}
else
{
m_publicKey = static_cast<pEVP_PKEY>(PEM_read_bio_PUBKEY(bio.get(), nullptr, nullptr, nullptr));
if (!m_publicKey)
throw std::runtime_error("Error: Failed to read private key from memory buffer");
}
}
//--------------------------------------------------------------
/* Sign data with private key */
inline std::vector<uint8_t> DigitalSign::sign(const Data8 &data, const EVP_MD *digest_type) const
{
if (!m_privateKey)
throw std::runtime_error("Error: Private key is not loaded for signing");
// Initialize the context for signing
const auto md_ctx = static_cast<pEVP_MD_CTX>(EVP_MD_CTX_new());
if (!md_ctx)
throw std::runtime_error("Error: Failed to create EVP_MD_CTX");
// Set the context for signing with the private key and digest
if (EVP_DigestSignInit(md_ctx.get(), nullptr, digest_type, nullptr, m_privateKey.get()) != 1)
throw std::runtime_error("Error: EVP_DigestSignInit failed");
// Provide the data to be signed
if (EVP_DigestSignUpdate(md_ctx.get(), data.getBytes().data(), data.getSize()) != 1)
throw std::runtime_error("Error: EVP_DigestSignUpdate failed");
// Determine the required signature size
size_t sigLen = 0;
if (EVP_DigestSignFinal(md_ctx.get(), nullptr, &sigLen) != 1)
throw std::runtime_error("Error: EVP_DigestSignFinal (size) failed");
// Allocate space and generate the signature
std::vector<uint8_t> signature(sigLen);
if (EVP_DigestSignFinal(md_ctx.get(), signature.data(), &sigLen) != 1)
throw std::runtime_error("Error: EVP_DigestSignFinal (signature) failed");
// Resize signature to the actual length used
signature.resize(sigLen);
return signature;
}
//--------------------------------------------------------------
/* Sign data */
inline std::string DigitalSign::signHex(const Data8 &data, const EVP_MD *digest_type) const
{
return bytesToHex(sign(data, digest_type));
}
//--------------------------------------------------------------
/* Verify signature with public key */
inline bool DigitalSign::verify(const Data8 &data, const std::span<const uint8_t> &signature, const EVP_MD *digest_type) const
{
if (!m_publicKey)
throw std::runtime_error("Error: Public key is not loaded for verifying");
// Initialize the context for verifying
const auto md_ctx = static_cast<pEVP_MD_CTX>(EVP_MD_CTX_new());
if (!md_ctx)
throw std::runtime_error("Error: Failed to create EVP_MD_CTX");
// Set the context for verifying with the public key and digest
if (EVP_DigestVerifyInit(md_ctx.get(), nullptr, digest_type, nullptr, m_publicKey.get()) != 1)
throw std::runtime_error("Error: EVP_DigestVerifyInit failed");
// Provide the original data
if (EVP_DigestVerifyUpdate(md_ctx.get(), data.getBytes().data(), data.getSize()) != 1)
throw std::runtime_error("Error: EVP_DigestVerifyUpdate failed");
// Verify the signature
// Returns 1 for a good signature, 0 for a bad signature, and -1 on error
const auto result = EVP_DigestVerifyFinal(md_ctx.get(), signature.data(), signature.size());
if (result == 1)
return true; // Signature is valid
if (result == 0)
return false; // Signature is NOT valid
throw std::runtime_error("Error: EVP_DigestVerifyFinal failed during execution");
}
//--------------------------------------------------------------
/* Verify signature with public key */
inline bool DigitalSign::verify(const Data8 &data, const std::string &signature, const EVP_MD *digest_type) const
{
return verify(data, hexToBytes(signature), digest_type);
}
//--------------------------------------------------------------
/* Converts a hexadecimal string into a vector of bytes */
inline std::vector<uint8_t> DigitalSign::hexToBytes(const std::string &hexString)
{
// A valid hex string must have an even length
if (hexString.length() % 2 != 0)
throw std::invalid_argument("Hex string must have an even length");
std::vector<uint8_t> bytes;
bytes.reserve(hexString.length() / 2);
for (size_t i = 0; i < hexString.length(); i += 2)
{
std::string byteString = hexString.substr(i, 2);
unsigned long byteVal;
try
{
byteVal = std::stoul(byteString, nullptr, 16);
}
catch (const std::exception & /*e*/)
{
throw std::invalid_argument("Invalid hexadecimal character sequence: " + byteString); // Non-hex characters ?
}
// Check if the value fits in a uint8_t (should always be true for 2 chars)
if (byteVal > 0xFF)
throw std::invalid_argument("Internal error: Converted value exceeds 0xFF");
bytes.push_back(static_cast<uint8_t>(byteVal));
}
return bytes;
}
//--------------------------------------------------------------
/* Converts a span of bytes into a hexadecimal string representation */
inline std::string DigitalSign::bytesToHex(const std::span<const uint8_t> &bytes)
{
std::stringstream ss;
ss << std::hex << std::uppercase << std::setfill('0');
for (const uint8_t byte : bytes)
ss << std::format("{0:02X}", byte);
return ss.str();
}
//--------------------------------------------------------------
} // namespace sdi_toolBox::crypto

View File

@@ -0,0 +1,49 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <chrono>
namespace sdi_toolBox::dateTime
{
//--------------------------------------------------------------
/**
* @brief Abstract interface for pause functionality.
*
* Provides a common interface for implementing pause or delay mechanisms.
* Derived classes must implement the wait() method to pause execution
* for a specified duration.
*/
class IPause
{
public:
using Duration = std::chrono::milliseconds;
public:
~IPause() = default; // Default destructor
IPause(const IPause &obj) = default; // Copy constructor
IPause(IPause &&obj) noexcept = default; // Move constructor
IPause &operator=(const IPause &obj) = default; // Copy assignment operator
IPause &operator=(IPause &&obj) noexcept = default; // Move assignment operator
/**
* @brief Pause execution for the specified duration.
* @param duration Duration of the pause.
*/
virtual void wait(const Duration &duration) const = 0;
protected:
IPause() = default; // Default constructor
};
//--------------------------------------------------------------
} // namespace sdi_toolBox::dateTime

View File

@@ -0,0 +1,100 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <chrono>
namespace sdi_toolBox::dateTime
{
//--------------------------------------------------------------
/**
* @brief Abstract interface for timer functionality.
*
* Provides a common interface for timer implementations, allowing
* measurement of elapsed time and checking for timeouts.
* Derived classes must implement the now() method to provide the
* current time point.
*/
class ITimer
{
public:
using Clock = std::chrono::high_resolution_clock;
using TimePoint = Clock::time_point;
using Duration = std::chrono::milliseconds;
public:
virtual ~ITimer() = default; // Default destructor
ITimer(const ITimer &obj) = default; // Copy constructor
ITimer(ITimer &&obj) noexcept = default; // Move constructor
ITimer &operator=(const ITimer &obj) = default; // Copy assignment operator
ITimer &operator=(ITimer &&obj) noexcept = default; // Move assignment operator
/**
* @brief Resets the reference time point to the current time.
*/
void reset();
/**
* @brief Returns the current time point.
* @return The current time point as defined by the derived class.
*/
[[nodiscard]] virtual TimePoint now() const = 0;
/**
* @brief Returns the elapsed duration since the last reset.
* @return Duration since the last reset.
*/
[[nodiscard]] Duration getElapsed() const;
/**
* @brief Checks if the specified duration has elapsed since the last reset.
* @param duration The duration to check.
* @param autoReset If true, automatically resets the timer when the duration has elapsed.
* @return True if the duration has elapsed, false otherwise.
*/
[[nodiscard]] bool isElapsed(const Duration duration,
bool autoReset = false);
protected:
ITimer() = default; // Default constructor
TimePoint m_t0; // Timepoint t0 for elapsed time measurement
};
//--------------------------------------------------------------
/* Reset the timepoint t0 */
inline void ITimer::reset()
{
m_t0 = now();
}
//--------------------------------------------------------------
/* Get the elapsed time */
inline ITimer::Duration ITimer::getElapsed() const
{
return std::chrono::duration_cast<Duration>(now() - m_t0);
}
//--------------------------------------------------------------
/* Check if the specified delay has elapsed */
inline bool ITimer::isElapsed(const Duration duration, bool autoReset)
{
Duration elapsed = getElapsed();
if (elapsed >= duration)
{
if (autoReset)
reset();
return true;
}
return false;
}
//--------------------------------------------------------------
} // namespace sdi_toolBox::dateTime

View File

@@ -0,0 +1,59 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "iPause.h"
#include <thread>
namespace sdi_toolBox::dateTime
{
//--------------------------------------------------------------
/**
* @brief Standard pause implementation.
*
* Implements IPause to provide a blocking pause using standard C++ mechanisms.
* The actual delay is performed using std::this_thread::sleep_for.
*/
class Pause : public IPause
{
public:
Pause() = default; // Default constructor
~Pause() = default; // Default destructor
Pause(const Pause &obj) = default; // Copy constructor
Pause(Pause &&obj) noexcept = default; // Move constructor
Pause &operator=(const Pause &obj) = default; // Copy assignment operator
Pause &operator=(Pause &&obj) noexcept = default; // Move assignment operator
explicit Pause(const Duration &duration); // Constructor
/**
* @brief Pause execution for the specified duration.
* @param duration Duration of the pause.
*/
void wait(const Duration &duration) const override;
};
//--------------------------------------------------------------
/* Constructor */
inline Pause::Pause(const Duration &duration)
{
wait(duration);
}
//--------------------------------------------------------------
/* Pause execution for the specified duration */
inline void Pause::wait(const Duration &duration) const
{
std::this_thread::sleep_for(duration);
}
//--------------------------------------------------------------
} // namespace sdi_toolBox::dateTime

View File

@@ -0,0 +1,55 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "iTimer.h"
namespace sdi_toolBox::dateTime
{
//--------------------------------------------------------------
/**
* @brief Standard timer implementation using std::chrono.
*
* Implements ITimer using std::chrono::high_resolution_clock for
* high-precision timing in standard C++ environments.
*/
class Timer : public ITimer
{
public:
Timer(); // Default constructor
~Timer() = default; // Default destructor
Timer(const Timer &obj) = default; // Copy constructor
Timer(Timer &&obj) noexcept = default; // Move constructor
Timer &operator=(const Timer &obj) = default; // Copy assignment operator
Timer &operator=(Timer &&obj) noexcept = default; // Move assignment operator
/**
* @brief Returns the current time point using std::chrono::high_resolution_clock.
* @return The current time point.
*/
[[nodiscard]] TimePoint now() const override;
};
//--------------------------------------------------------------
/* Default constructor */
inline Timer::Timer()
{
reset();
}
//--------------------------------------------------------------
/* Get the current timepoint */
inline Timer::TimePoint Timer::now() const
{
return Clock::now();
}
//--------------------------------------------------------------
} // namespace sdi_toolBox::dateTime

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,176 @@
// __ _____ _____ _____
// __| | __| | | | JSON for Modern C++
// | | |__ | | | | | | version 3.11.3
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT
#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
#include <cstdint> // int64_t, uint64_t
#include <map> // map
#include <memory> // allocator
#include <string> // string
#include <vector> // vector
// #include <nlohmann/detail/abi_macros.hpp>
// __ _____ _____ _____
// __| | __| | | | JSON for Modern C++
// | | |__ | | | | | | version 3.11.3
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT
// This file contains all macro definitions affecting or depending on the ABI
#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
#if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH)
#if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 3
#warning "Already included a different version of the library!"
#endif
#endif
#endif
#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum)
#define NLOHMANN_JSON_VERSION_MINOR 11 // NOLINT(modernize-macro-to-enum)
#define NLOHMANN_JSON_VERSION_PATCH 3 // NOLINT(modernize-macro-to-enum)
#ifndef JSON_DIAGNOSTICS
#define JSON_DIAGNOSTICS 0
#endif
#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0
#endif
#if JSON_DIAGNOSTICS
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
#else
#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS
#endif
#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
#define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp
#else
#define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON
#endif
#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
#endif
// Construct the namespace ABI tags component
#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b
#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \
NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b)
#define NLOHMANN_JSON_ABI_TAGS \
NLOHMANN_JSON_ABI_TAGS_CONCAT( \
NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON)
// Construct the namespace version component
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
_v ## major ## _ ## minor ## _ ## patch
#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
#if NLOHMANN_JSON_NAMESPACE_NO_VERSION
#define NLOHMANN_JSON_NAMESPACE_VERSION
#else
#define NLOHMANN_JSON_NAMESPACE_VERSION \
NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
NLOHMANN_JSON_VERSION_MINOR, \
NLOHMANN_JSON_VERSION_PATCH)
#endif
// Combine namespace components
#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b
#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \
NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
#ifndef NLOHMANN_JSON_NAMESPACE
#define NLOHMANN_JSON_NAMESPACE \
nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
NLOHMANN_JSON_ABI_TAGS, \
NLOHMANN_JSON_NAMESPACE_VERSION)
#endif
#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
#define NLOHMANN_JSON_NAMESPACE_BEGIN \
namespace nlohmann \
{ \
inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
NLOHMANN_JSON_ABI_TAGS, \
NLOHMANN_JSON_NAMESPACE_VERSION) \
{
#endif
#ifndef NLOHMANN_JSON_NAMESPACE_END
#define NLOHMANN_JSON_NAMESPACE_END \
} /* namespace (inline namespace) NOLINT(readability/namespace) */ \
} // namespace nlohmann
#endif
/*!
@brief namespace for Niels Lohmann
@see https://github.com/nlohmann
@since version 1.0.0
*/
NLOHMANN_JSON_NAMESPACE_BEGIN
/*!
@brief default JSONSerializer template argument
This serializer ignores the template arguments and uses ADL
([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
for serialization.
*/
template<typename T = void, typename SFINAE = void>
struct adl_serializer;
/// a class to store JSON values
/// @sa https://json.nlohmann.me/api/basic_json/
template<template<typename U, typename V, typename... Args> class ObjectType =
std::map,
template<typename U, typename... Args> class ArrayType = std::vector,
class StringType = std::string, class BooleanType = bool,
class NumberIntegerType = std::int64_t,
class NumberUnsignedType = std::uint64_t,
class NumberFloatType = double,
template<typename U> class AllocatorType = std::allocator,
template<typename T, typename SFINAE = void> class JSONSerializer =
adl_serializer,
class BinaryType = std::vector<std::uint8_t>, // cppcheck-suppress syntaxError
class CustomBaseClass = void>
class basic_json;
/// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document
/// @sa https://json.nlohmann.me/api/json_pointer/
template<typename RefStringType>
class json_pointer;
/*!
@brief default specialization
@sa https://json.nlohmann.me/api/json/
*/
using json = basic_json<>;
/// @brief a minimal map-like container that preserves insertion order
/// @sa https://json.nlohmann.me/api/ordered_map/
template<class Key, class T, class IgnoredLess, class Allocator>
struct ordered_map;
/// @brief specialization that maintains the insertion order of object keys
/// @sa https://json.nlohmann.me/api/ordered_json/
using ordered_json = basic_json<nlohmann::ordered_map>;
NLOHMANN_JSON_NAMESPACE_END
#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_

View File

@@ -0,0 +1,105 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <array>
#include <cstdint>
#include <optional>
namespace sdi_toolBox::generic
{
//--------------------------------------------------------------
template<class T, size_t BUFFER_SIZE>
class CircularBuffer final
{
public:
CircularBuffer() = default; // Constructor
~CircularBuffer() = default; // Destructor
CircularBuffer(const CircularBuffer &other) = delete; // Copy constructor
CircularBuffer(CircularBuffer &&other) noexcept = delete; // Move constructor
CircularBuffer &operator=(const CircularBuffer &other) = delete; // Copy assignment
CircularBuffer &operator=(CircularBuffer &&other) noexcept = delete; // Move assignment
bool push(const T &item); // Add an element to the buffer
std::optional<T> pop(); // Retrieve an element from the buffer
bool isEmpty() const; // Check if the buffer is empty
bool isFull() const; // Check if the buffer is full
size_t size() const; // Get the current number of elements
protected:
std::array<T, BUFFER_SIZE> m_buffer;
volatile size_t m_head = 0; // Index for the next write (push)
volatile size_t m_tail = 0; // Index for the next read (pop)
volatile size_t m_size = 0; // Current number of elements stored
};
//--------------------------------------------------------------
//--------------------------------------------------------------
/* Add an element to the buffer */
template<class T, size_t BUFFER_SIZE>
inline bool CircularBuffer<T, BUFFER_SIZE>::push(const T &item)
{
if (isFull())
return false; // Buffer is full
// Write the item at the current head position
m_buffer[m_head] = item;
// Move head pointer, wrapping around using modulo
m_head = (m_head + 1) % BUFFER_SIZE;
// Increase the current size of the data in the buffer
m_size = m_size + 1;
return true;
}
//--------------------------------------------------------------
/* Retrieve an element from the buffer */
template<class T, size_t BUFFER_SIZE>
inline std::optional<T> CircularBuffer<T, BUFFER_SIZE>::pop()
{
if (isEmpty())
return {}; // Buffer is empty, cannot pop
// Read (copy) the item at the current tail position
T item = m_buffer[m_tail];
// Move tail pointer, wrapping around using modulo
m_tail = (m_tail + 1) % BUFFER_SIZE;
// Decrease the current size of the data in the buffer
m_size = m_size - 1;
return item;
}
//--------------------------------------------------------------
/* Check if the buffer is empty */
template<class T, size_t BUFFER_SIZE>
inline bool CircularBuffer<T, BUFFER_SIZE>::isEmpty() const
{
return m_size == 0;
}
//--------------------------------------------------------------
/* Check if the buffer is full */
template<class T, size_t BUFFER_SIZE>
inline bool CircularBuffer<T, BUFFER_SIZE>::isFull() const
{
return m_size == BUFFER_SIZE;
}
//--------------------------------------------------------------
/* Get the current number of elements */
template<class T, size_t BUFFER_SIZE>
inline size_t CircularBuffer<T, BUFFER_SIZE>::size() const
{
return m_size;
}
//--------------------------------------------------------------
} // namespace sdi_toolBox::generic

View File

@@ -0,0 +1,163 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <cstdint>
#include <span>
namespace sdi_ToolBox::generic
{
//--------------------------------------------------------------
/**
* @class CRC16_modbus
* @brief CRC16 calculator for the Modbus protocol.
*
* Provides both static and incremental interfaces to compute the CRC16 checksum
* as used in the Modbus protocol (polynomial 0xA001, initial value 0xFFFF).
*
* Usage examples:
* @code
* // One-shot CRC calculation
* std::array<uint8_t, 8> data = { ... };
* uint16_t crc = Crc16_modbus::computeCRC(data);
*
* // Incremental CRC calculation
* Crc16_modbus crcHandle;
* crcHandle.init();
* for (uint8_t b : data) {
* crcHandle.update(b);
* }
* uint16_t crc = crcHandle.finalize();
* @endcode
*/
class CRC16_modbus
{
static constexpr uint16_t INITIAL_VALUE = 0xFFFF;
public:
/**
* @brief Computes the CRC16 of the given data in one call.
* @param data The data buffer to compute the CRC for.
* @return The computed CRC16 value.
*/
static uint16_t computeCRC(const std::span<const uint8_t> &data);
public:
CRC16_modbus() = default; // Default constructor
virtual ~CRC16_modbus() = default; // Default destructor
CRC16_modbus(const CRC16_modbus &other) = default; // Copy constructor
CRC16_modbus(CRC16_modbus &&other) noexcept = default; // Move constructor
CRC16_modbus &operator=(const CRC16_modbus &other) = default; // Copy assignment
CRC16_modbus &operator=(CRC16_modbus &&other) noexcept = default; // Move assignment
/**
* @brief Constructs and initializes the CRC with the given data.
* @param data The data buffer to initialize and update the CRC with.
*/
explicit CRC16_modbus(const std::span<const uint8_t> &data);
/**
* @brief Initializes or re-initializes the CRC to the default value (0xFFFF).
*/
void init();
/**
* @brief Updates the CRC with a single byte.
* @param val The byte value to update the CRC with.
*/
void update(const uint8_t &val);
/**
* @brief Updates the CRC with a data buffer.
* @param data The data buffer to update the CRC with.
*/
void update(const std::span<const uint8_t> &data);
/**
* @brief Finalizes the CRC calculation and returns the CRC value.
* @return The finalized CRC16 value.
*/
uint16_t finalize() const;
/**
* @brief Returns the current CRC value.
* @return The current CRC16 value.
*/
[[nodiscard]] uint16_t getCRC() const;
protected:
uint16_t m_crc = INITIAL_VALUE; // Current CRC value
};
//--------------------------------------------------------------
//--------------------------------------------------------------
/* Compute CRC in one go */
inline uint16_t CRC16_modbus::computeCRC(const std::span<const uint8_t> &data)
{
const CRC16_modbus crc(data);
return crc.finalize();
}
//--------------------------------------------------------------
/* Constructor */
inline CRC16_modbus::CRC16_modbus(const std::span<const uint8_t> &data)
{
init();
update(data);
}
//--------------------------------------------------------------
/* Reinit crc handle */
inline void CRC16_modbus::init()
{
m_crc = INITIAL_VALUE;
}
//--------------------------------------------------------------
/* Update CRC */
inline void CRC16_modbus::update(const uint8_t &val)
{
constexpr uint16_t PolynomialValue = 0xA001;
m_crc ^= static_cast<uint16_t>(val); // XOR byte into least sig. byte of crc
for (int i = 8; i != 0; i--) // Loop over each bit
{
if ((m_crc & 0x0001) != 0) // If the LSB is set
{
m_crc >>= 1; // Shift right and XOR PolynomialValue
m_crc ^= PolynomialValue;
}
else // Else LSB is not set
{
m_crc >>= 1; // Just shift right
}
}
}
//--------------------------------------------------------------
/* Update CRC */
inline void CRC16_modbus::update(const std::span<const uint8_t> &data)
{
for (const auto &c : data)
update(c);
}
//--------------------------------------------------------------
/* Finalize and return CRC value */
inline uint16_t CRC16_modbus::finalize() const
{
return getCRC();
}
//--------------------------------------------------------------
/* Return CRC value */
inline uint16_t CRC16_modbus::getCRC() const
{
return m_crc;
}
//--------------------------------------------------------------
} // namespace sdi_ToolBox::generic

View File

@@ -0,0 +1,79 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <boost/uuid/uuid.hpp> // Pour boost::uuids::uuid
#include <boost/uuid/uuid_generators.hpp> // Pour boost::uuids::random_generator
#include <boost/uuid/uuid_io.hpp> // Pour boost::uuids::to_string
#include <format>
#include <string>
namespace sdi_toolBox::generic
{
//--------------------------------------------------------------
class UuidGenerator
{
public:
static std::string uuid_v4(); // Generate a random UUID v4 string
static std::string uniqid(bool moreEntropy = false); // Generate a unique identifier string (as in PHP)
protected:
UuidGenerator() = default; // Default constructor
~UuidGenerator() = default; // Default destructor
UuidGenerator(const UuidGenerator &) = default; // Copy constructor
UuidGenerator(UuidGenerator &&) noexcept = default; // Move constructor
UuidGenerator &operator=(const UuidGenerator &) = default; // Copy assignment operator
UuidGenerator &operator=(UuidGenerator &&) noexcept = default; // Move assignment operator
};
//--------------------------------------------------------------
/* Generate a random UUID v4 string */
inline std::string UuidGenerator::uuid_v4()
{
boost::uuids::random_generator gen; // Create a random UUID generator
boost::uuids::uuid u = gen(); // Generate a random UUID
return boost::uuids::to_string(u); // Convert the UUID to a string and return it
}
//--------------------------------------------------------------
/* Generate a unique identifier string (as in PHP) */
inline std::string UuidGenerator::uniqid(const bool moreEntropy)
{
const auto now = std::chrono::high_resolution_clock::now(); // Get current time point
const auto epoch = now.time_since_epoch(); // Get duration since epoch
const auto us_since_epoch = std::chrono::duration_cast<std::chrono::microseconds>(epoch).count();
// Format the time part into a hexadecimal string
const auto time_part = us_since_epoch / 16;
std::string result = std::format("{0:x}", time_part);
// PHP's uniqid pads the result to 13 characters if needed. We replicate the core logic.
// If the time part is shorter than 13 characters (highly unlikely today), it should be padded.
if (result.length() < 13)
result.insert(0, 13 - result.length(), '0');
// Add more entropy if requested (similar to PHP's second argument = true)
if (moreEntropy)
{
// Generate 5 bytes of random data (10 characters hex)
static std::random_device rd;
static std::mt19937 generator(rd());
unsigned int rand_val = generator(); // Generate a random 32-bit number and use a portion of a second random number
// Append the random data in hexadecimal format
result = result + std::format(".{0:08x}", rand_val);
}
return result;
}
//--------------------------------------------------------------
} // namespace sdi_toolBox::generic

View File

@@ -0,0 +1,531 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "../console/ansi.h"
#ifdef _WIN32
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN // Disable windows mess
# endif
# ifndef NOMINMAX
# define NOMINMAX
# endif
# include <Windows.h>
# undef GetMessage // To avoid conflict with other libraries
#endif
#include <chrono>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <map>
#include <mutex>
#include <source_location>
#include <sstream>
#include <string>
/*
* Usage :
*
* {
* int value = 42;
* std::string user = "Alice";
*
* // Usage example:
* LogMessage() << "System ready" << std::endl;
* LogDebug() << "Checking configuration file..." << std::endl;
* LogInfo() << "User " << user << " logged in. (Value: " << value << ")" << std::endl;
* LogWarning() << "Device connection lost..." << std::endl;
* LogError() << "Failed to connect to server on port " << 8080 << "!" << std::endl;
* LogComm() << "<< 0123456789" << std::endl;
* LogDev() << "<< 0123456789" << std::endl;
* }
*/
namespace sdi_toolBox::logs
{
//--------------------------------------------------------------
enum class LogLevel : uint8_t
{
None,
Dev,
Comm,
Debug,
Info,
Warning,
Error,
Message,
};
//--------------------------------------------------------------
//--------------------------------------------------------------
class ReLog
{
public:
struct Log
{
LogLevel level;
std::chrono::system_clock::time_point timestamp;
std::string message;
};
using ColorLogMap = std::map<LogLevel, std::string>;
using VisibleLogMap = std::map<LogLevel, bool>;
static VisibleLogMap getVisibleLogMap(); // Return the map of visible log messages
static void setVisibleLogMap(const VisibleLogMap &logMap); // Define the map of visible log messages
static ReLog &systemInit(const std::filesystem::path &filepath = ""); // Initialize log system
static ReLog &getInstance(); // Gets singleton instance
public:
virtual ~ReLog() = default; // Default destructor
ReLog(const ReLog &obj) = delete; // Copy constructor
ReLog(ReLog &&obj) noexcept = delete; // Move constructor
ReLog &operator=(const ReLog &obj) = delete; // Copy assignment operator
ReLog &operator=(ReLog &&obj) noexcept = delete; // Move assignment operator
void openFile(const std::filesystem::path &filepath); // Open or create log file
void closeFile(); // Close log file
void log(const Log &log); // Core log method
void printColorTest() const; // Print the different configurations and colors on the terminal
protected:
ReLog(); // Default constructor
bool m_vtModeEnabled = false;
std::mutex m_mtx;
std::ofstream m_file;
static inline ColorLogMap m_colorLogMap;
static inline VisibleLogMap m_visibleLogMap;
private:
void enableVTMode();
static void init(); // Settings initialization
static std::string createLogMessage(const Log &log, const bool isFile = false); // Print log messages
void printDate();
void saveToFile(const std::string &message); // Save log messages in file
};
//--------------------------------------------------------------
/* --- */
//--------------------------------------------------------------
/* Return the map of visible log messages */
inline ReLog::VisibleLogMap ReLog::getVisibleLogMap()
{
return m_visibleLogMap;
}
//--------------------------------------------------------------
/* Define the map of visible log messages */
inline void ReLog::setVisibleLogMap(const VisibleLogMap &logMap)
{
m_visibleLogMap = logMap;
}
//--------------------------------------------------------------
/* Initialize log system */
inline ReLog &ReLog::systemInit(const std::filesystem::path &filepath)
{
auto &logSystem = getInstance();
// Post initialization
if (!filepath.empty())
logSystem.openFile(filepath);
logSystem.printDate();
return logSystem;
}
//--------------------------------------------------------------
/* Gets singleton instance */
inline ReLog &ReLog::getInstance()
{
static ReLog instance;
return instance;
}
//--------------------------------------------------------------
/* Constructor */
inline ReLog::ReLog()
{
// Initialization
init();
enableVTMode();
// Test on debug mode
#ifdef DEBUG
// printColorTest();
#endif
}
//--------------------------------------------------------------
/* Open or create log file */
inline void ReLog::openFile(const std::filesystem::path &filepath)
{
std::lock_guard lock(m_mtx);
m_file = std::ofstream(filepath, std::ofstream::out | std::ofstream::app | std::ofstream::binary);
if (!m_file)
throw std::runtime_error("unable to open log file");
m_file << "\n-----------------------------------------------------------------" << std::endl;
}
//--------------------------------------------------------------
/* Close log file */
inline void ReLog::closeFile()
{
std::lock_guard lock(m_mtx);
if (m_file.is_open())
m_file.close();
}
//--------------------------------------------------------------
/* Core log method */
inline void ReLog::log(const Log &log)
{
std::lock_guard lock(m_mtx);
const auto termMessage = createLogMessage(log);
if (!termMessage.empty())
{
if (log.level == LogLevel::Error)
std::cerr << termMessage << std::endl;
else
std::cout << termMessage << std::endl;
}
const auto fileMessage = createLogMessage(log, true);
if (!fileMessage.empty())
saveToFile(fileMessage);
}
//--------------------------------------------------------------
/* Print the different configurations and colors on the terminal */
inline void ReLog::printColorTest() const
{
const auto coutTest = [&](const auto &color, const std::string &label)
{
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, sdi_toolBox::console::ANSI::EscapeCommand::UNDERLINE) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, sdi_toolBox::console::ANSI::EscapeCommand::DIM | sdi_toolBox::console::ANSI::EscapeCommand::UNDERLINE) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, sdi_toolBox::console::ANSI::EscapeCommand::LIGHT | sdi_toolBox::console::ANSI::EscapeCommand::UNDERLINE) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, sdi_toolBox::console::ANSI::EscapeCommand::LIGHT) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, sdi_toolBox::console::ANSI::EscapeCommand::BLINK) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, sdi_toolBox::console::ANSI::EscapeCommand::BRIGHT) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, sdi_toolBox::console::ANSI::EscapeCommand::DIM) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, sdi_toolBox::console::ANSI::EscapeCommand::REVERSE) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << " | ";
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, 0, sdi_toolBox::console::ANSI::EscapeCommand::Color::Black) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, 0, sdi_toolBox::console::ANSI::EscapeCommand::Color::Red) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, 0, sdi_toolBox::console::ANSI::EscapeCommand::Color::Green) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, 0, sdi_toolBox::console::ANSI::EscapeCommand::Color::Yellow) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, 0, sdi_toolBox::console::ANSI::EscapeCommand::Color::Blue) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, 0, sdi_toolBox::console::ANSI::EscapeCommand::Color::Magenta) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, 0, sdi_toolBox::console::ANSI::EscapeCommand::Color::Cyan) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, 0, sdi_toolBox::console::ANSI::EscapeCommand::Color::White) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << " | ";
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, 0, sdi_toolBox::console::ANSI::EscapeCommand::Color::Black, sdi_toolBox::console::ANSI::EscapeCommand::LIGHT) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, 0, sdi_toolBox::console::ANSI::EscapeCommand::Color::Red, sdi_toolBox::console::ANSI::EscapeCommand::LIGHT) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, 0, sdi_toolBox::console::ANSI::EscapeCommand::Color::Green, sdi_toolBox::console::ANSI::EscapeCommand::LIGHT) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, 0, sdi_toolBox::console::ANSI::EscapeCommand::Color::Yellow, sdi_toolBox::console::ANSI::EscapeCommand::LIGHT) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, 0, sdi_toolBox::console::ANSI::EscapeCommand::Color::Blue, sdi_toolBox::console::ANSI::EscapeCommand::LIGHT) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, 0, sdi_toolBox::console::ANSI::EscapeCommand::Color::Magenta, sdi_toolBox::console::ANSI::EscapeCommand::LIGHT) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, 0, sdi_toolBox::console::ANSI::EscapeCommand::Color::Cyan, sdi_toolBox::console::ANSI::EscapeCommand::LIGHT) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << sdi_toolBox::console::ANSI::EscapeCommand::get(color, 0, sdi_toolBox::console::ANSI::EscapeCommand::Color::White, sdi_toolBox::console::ANSI::EscapeCommand::LIGHT) << label << sdi_toolBox::console::ANSI::EscapeCommand::clear();
std::cout << std::endl;
};
coutTest(sdi_toolBox::console::ANSI::EscapeCommand::Color::Black, " B ");
coutTest(sdi_toolBox::console::ANSI::EscapeCommand::Color::Red, " R ");
coutTest(sdi_toolBox::console::ANSI::EscapeCommand::Color::Green, " G ");
coutTest(sdi_toolBox::console::ANSI::EscapeCommand::Color::Yellow, " Y ");
coutTest(sdi_toolBox::console::ANSI::EscapeCommand::Color::Blue, " B ");
coutTest(sdi_toolBox::console::ANSI::EscapeCommand::Color::Magenta, " M ");
coutTest(sdi_toolBox::console::ANSI::EscapeCommand::Color::Cyan, " C ");
coutTest(sdi_toolBox::console::ANSI::EscapeCommand::Color::White, " W ");
std::cout << std::endl;
}
//--------------------------------------------------------------
inline void ReLog::enableVTMode()
{
if (m_vtModeEnabled)
return;
m_vtModeEnabled = false;
// 1. Get the handle to the standard output
const HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut == INVALID_HANDLE_VALUE)
return;
// 2. Get the current console mode
DWORD dwMode = 0;
if (!GetConsoleMode(hOut, &dwMode))
return;
// 3. Set the ENABLE_VIRTUAL_TERMINAL_PROCESSING flag (using bitwise OR)
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
// 4. Apply the new console mode
if (!SetConsoleMode(hOut, dwMode)) // This is often the point of failure on older Windows versions (pre-Win10 v1511)
return;
m_vtModeEnabled = true;
}
//--------------------------------------------------------------
/* Settings initialization */
inline void ReLog::init()
{
m_colorLogMap[LogLevel::None] = sdi_toolBox::console::ANSI::EscapeCommand::clear();
m_colorLogMap[LogLevel::Dev] = sdi_toolBox::console::ANSI::EscapeCommand::get(sdi_toolBox::console::ANSI::EscapeCommand::Color::Green, sdi_toolBox::console::ANSI::EscapeCommand::DIM);
m_colorLogMap[LogLevel::Comm] = sdi_toolBox::console::ANSI::EscapeCommand::get(sdi_toolBox::console::ANSI::EscapeCommand::Color::Magenta);
m_colorLogMap[LogLevel::Debug] = sdi_toolBox::console::ANSI::EscapeCommand::get(sdi_toolBox::console::ANSI::EscapeCommand::Color::Yellow, sdi_toolBox::console::ANSI::EscapeCommand::DIM);
m_colorLogMap[LogLevel::Info] = sdi_toolBox::console::ANSI::EscapeCommand::get(sdi_toolBox::console::ANSI::EscapeCommand::Color::White);
m_colorLogMap[LogLevel::Warning] = sdi_toolBox::console::ANSI::EscapeCommand::get(sdi_toolBox::console::ANSI::EscapeCommand::Color::Yellow);
m_colorLogMap[LogLevel::Error] = sdi_toolBox::console::ANSI::EscapeCommand::get(sdi_toolBox::console::ANSI::EscapeCommand::Color::Red, sdi_toolBox::console::ANSI::EscapeCommand::LIGHT | sdi_toolBox::console::ANSI::EscapeCommand::BRIGHT);
m_colorLogMap[LogLevel::Message] = sdi_toolBox::console::ANSI::EscapeCommand::get(sdi_toolBox::console::ANSI::EscapeCommand::Color::White, sdi_toolBox::console::ANSI::EscapeCommand::LIGHT);
m_visibleLogMap[LogLevel::Dev] = true;
m_visibleLogMap[LogLevel::Comm] = true;
m_visibleLogMap[LogLevel::Debug] = true;
m_visibleLogMap[LogLevel::Info] = true;
m_visibleLogMap[LogLevel::Warning] = true;
m_visibleLogMap[LogLevel::Error] = true;
m_visibleLogMap[LogLevel::Message] = true;
}
//--------------------------------------------------------------
/* Print log messages */
inline std::string ReLog::createLogMessage(const Log &log, const bool isFile)
{
// Check if the message should be visible or not
if (m_visibleLogMap.contains(log.level) && m_visibleLogMap[log.level] == false)
return "";
std::ostringstream stream;
// Prepare message color
const auto levelStyle = (m_colorLogMap.contains(log.level)) ? m_colorLogMap[log.level] : sdi_toolBox::console::ANSI::EscapeCommand::clear();
const auto messageStyle = (!isFile) ? levelStyle : "";
if (!log.message.empty())
{
switch (log.level)
{
case LogLevel::Error:
stream << messageStyle << "[E] ";
break;
case LogLevel::Warning:
stream << messageStyle << "[W] ";
break;
case LogLevel::Info:
stream << messageStyle << "[I] ";
break;
case LogLevel::Debug:
stream << messageStyle << "[D] ";
break;
case LogLevel::Comm:
stream << messageStyle << "[C] ";
break;
case LogLevel::Dev:
stream << messageStyle << "[-] ";
break;
case LogLevel::Message:
default:;
stream << messageStyle;
break;
}
if (log.level != LogLevel::Message)
{
const auto local_tz = std::chrono::current_zone();
const auto local_time = std::chrono::zoned_time(local_tz, log.timestamp);
stream << std::format("{0:%T} - ", local_time);
}
}
// Print message
stream << log.message;
// Reset style
if (!messageStyle.empty())
stream << sdi_toolBox::console::ANSI::EscapeCommand::clear();
return stream.str();
}
//--------------------------------------------------------------
inline void ReLog::printDate()
{
const auto now = std::chrono::system_clock::now();
const auto local_tz = std::chrono::current_zone();
const auto local_time = std::chrono::zoned_time(local_tz, now);
const Log logMessage{ .level = LogLevel::Info,
.timestamp = now,
.message = std::format("current date: {0:%F}", local_time) };
log(logMessage);
}
//--------------------------------------------------------------
/* Save log messages in file */
inline void ReLog::saveToFile(const std::string &message)
{
// Remove escape sequences
std::string messageResult;
bool in_escape_sequence = false;
constexpr char ANSI_ESCAPE_CHAR = '\x1b';
for (const char c : message)
{
if (in_escape_sequence)
{
if (c == 'm')
in_escape_sequence = false; // End of the escape sequence
}
else if (c == ANSI_ESCAPE_CHAR)
in_escape_sequence = true; // Begin of the escape sequence
else
messageResult += c;
}
if (m_file.is_open())
m_file << messageResult << "\n";
}
//--------------------------------------------------------------
/* --- */
//--------------------------------------------------------------
class ReLogStreamProxy
{
public:
ReLogStreamProxy() = delete; // Constructor
explicit ReLogStreamProxy(const LogLevel &level); // Constructor
virtual ~ReLogStreamProxy(); // Destructor
ReLogStreamProxy(ReLogStreamProxy &obj) = delete; // Copy constructor
ReLogStreamProxy(ReLogStreamProxy &&obj) = delete; // Move constructor
ReLogStreamProxy &operator=(const ReLogStreamProxy &obj) = delete; // Copy assignment operator
ReLogStreamProxy &operator=(ReLogStreamProxy &&obj) = delete; // Move assignment operator
template<typename T>
ReLogStreamProxy &operator<<(const T &data); // Overload for various data types (int, string, double, etc.)
ReLogStreamProxy &operator<<(std::ostream &(*manip)(std::ostream &)); // Overload for std::endl and other manipulators
protected:
LogLevel m_level;
std::chrono::system_clock::time_point m_timestamp;
std::stringstream m_buffer;
private:
void flush(); // Pass the buffered content to the central Logger
};
//--------------------------------------------------------------
/* Constructor */
inline ReLogStreamProxy::ReLogStreamProxy(const LogLevel &level)
{
// Initialization
m_level = level;
}
//--------------------------------------------------------------
/* Destructor */
inline ReLogStreamProxy::~ReLogStreamProxy()
{
if (!m_buffer.str().empty())
flush();
}
//--------------------------------------------------------------
/* Overload for various data types (int, string, double, etc.) */
template<typename T>
inline ReLogStreamProxy &ReLogStreamProxy::operator<<(const T &data)
{
const auto now = std::chrono::system_clock::now();
if (m_buffer.str().empty())
m_timestamp = now;
m_buffer << data;
return *this;
}
//--------------------------------------------------------------
/* Overload for std::endl and other manipulators */
inline ReLogStreamProxy &ReLogStreamProxy::operator<<(std::ostream &(*manip)(std::ostream &))
{
if (manip == static_cast<std::ostream &(*)(std::ostream &)>(std::endl))
{
flush();
}
else
{
// Handle other manipulators if necessary (e.g., std::hex)
m_buffer << manip;
}
return *this;
}
//--------------------------------------------------------------
/* Pass the buffered content to the central Logger */
inline void ReLogStreamProxy::flush()
{
// Pass the buffered content to the central Logger
ReLog::getInstance().log(ReLog::Log{ .level = m_level,
.timestamp = m_timestamp,
.message = m_buffer.str() });
// Reset stream content
m_buffer.str("");
m_buffer.clear();
}
//--------------------------------------------------------------
} // namespace sdi_toolBox::logs
//--------------------------------------------------------------
/*
* User interface
*/
inline sdi_toolBox::logs::ReLogStreamProxy LogError()
{
return sdi_toolBox::logs::ReLogStreamProxy(sdi_toolBox::logs::LogLevel::Error);
}
//--------------------------------------------------------------
inline sdi_toolBox::logs::ReLogStreamProxy LogWarning()
{
return sdi_toolBox::logs::ReLogStreamProxy(sdi_toolBox::logs::LogLevel::Warning);
}
//--------------------------------------------------------------
inline sdi_toolBox::logs::ReLogStreamProxy LogInfo()
{
return sdi_toolBox::logs::ReLogStreamProxy(sdi_toolBox::logs::LogLevel::Info);
}
//--------------------------------------------------------------
inline sdi_toolBox::logs::ReLogStreamProxy LogDebug()
{
return sdi_toolBox::logs::ReLogStreamProxy(sdi_toolBox::logs::LogLevel::Debug);
}
//--------------------------------------------------------------
inline sdi_toolBox::logs::ReLogStreamProxy LogComm()
{
return sdi_toolBox::logs::ReLogStreamProxy(sdi_toolBox::logs::LogLevel::Comm);
}
//--------------------------------------------------------------
inline sdi_toolBox::logs::ReLogStreamProxy LogMessage()
{
return sdi_toolBox::logs::ReLogStreamProxy(sdi_toolBox::logs::LogLevel::Message);
}
//--------------------------------------------------------------
inline sdi_toolBox::logs::ReLogStreamProxy LogDev()
{
return sdi_toolBox::logs::ReLogStreamProxy(sdi_toolBox::logs::LogLevel::Dev);
}
//--------------------------------------------------------------
inline void LogCode(const std::string &msg = "", const std::source_location &location = std::source_location::current())
{
LogDev() << msg << ((!msg.empty()) ? " - " : "") << "(" << location.file_name() << " l." << location.line() << ")" << std::endl;
}
//--------------------------------------------------------------

View File

@@ -0,0 +1,6 @@
#pragma once
/**
* @namespace sdi_ToolBox
* @brief Root namespace for SD-Innovation ToolBox utilities.
*/

View File

@@ -0,0 +1,94 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <wx/statline.h>
#include <wx/wx.h>
//--------------------------------------------------------------
inline wxStaticText *createTitleCtrl(wxWindow *parentWindow, const wxString &title, const long style = 0)
{
const auto ctrl = new wxStaticText(parentWindow,
wxID_ANY,
title,
wxDefaultPosition,
wxDefaultSize,
style);
ctrl->SetFont(ctrl->GetFont().Italic());
return ctrl;
}
//--------------------------------------------------------------
inline wxStaticText *createLabelCtrl(wxWindow *parentWindow, const wxString &title = wxEmptyString, const long style = 0)
{
const auto ctrl = new wxStaticText(parentWindow,
wxID_ANY,
title,
wxDefaultPosition,
wxDefaultSize,
style);
return ctrl;
}
//--------------------------------------------------------------
inline wxTextCtrl *createTextCtrl(wxWindow *parentWindow, const wxString &value = wxEmptyString, const long style = 0)
{
const auto ctrl = new wxTextCtrl(parentWindow,
wxID_ANY,
value,
wxDefaultPosition,
wxDefaultSize,
style);
return ctrl;
}
//--------------------------------------------------------------
inline wxButton *createButtonCtrl(wxWindow *parentWindow, const wxString &label, const long style = 0)
{
const auto ctrl = new wxButton(parentWindow,
wxID_ANY,
label,
wxDefaultPosition,
wxDefaultSize,
style);
return ctrl;
}
//--------------------------------------------------------------
inline wxBitmapButton *createBitmapButtonCtrl(wxWindow *parentWindow, const wxBitmap &bmp, const long style = 0)
{
const auto ctrl = new wxBitmapButton(parentWindow,
wxID_ANY,
bmp,
wxDefaultPosition,
wxDefaultSize,
style);
return ctrl;
}
//--------------------------------------------------------------
inline wxStaticLine *createVLineCtrl(wxWindow *parentWindow)
{
const auto ctrl = new wxStaticLine(parentWindow,
wxID_ANY,
wxDefaultPosition,
wxDefaultSize,
wxVERTICAL);
return ctrl;
}
//--------------------------------------------------------------
inline wxStaticLine *createHLineCtrl(wxWindow *parentWindow)
{
const auto ctrl = new wxStaticLine(parentWindow,
wxID_ANY,
wxDefaultPosition,
wxDefaultSize,
wxHORIZONTAL);
return ctrl;
}
//--------------------------------------------------------------

View File

@@ -0,0 +1,45 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "ICommBus.h"
#include <chrono>
#include <expected>
#include <span>
namespace sdi_uToolBox::comm
{
//--------------------------------------------------------------
class I2CBus : public ICommBus
{
public:
using ReadBuf = std::span<uint8_t>;
using WriteBuf = std::span<const uint8_t>;
using Timeout = std::chrono::milliseconds;
using ReturnType = std::expected<size_t, ReturnStatus>;
public:
I2CBus() = default; // Default constructor
virtual ~I2CBus() override = default; // Default destructor
I2CBus(const I2CBus &) = delete; // Copy constructor
I2CBus(I2CBus &&) = delete; // Move constructor
I2CBus &operator=(const I2CBus &) = delete; // Copy assignment operator
I2CBus &operator=(I2CBus &&) = delete; // Move assignment operator
virtual ReturnType write(uint8_t address, WriteBuf buf, Timeout timeout) const = 0; // Write data to I2C device
virtual ReturnType read(uint8_t address, ReadBuf buf, Timeout timeout) const = 0; // Read data from I2C device
virtual ReturnStatus isDeviceReady(uint8_t address) const = 0; // Check if I2C device is ready
};
//--------------------------------------------------------------
} // namespace sdi_uToolBox::comm

View File

@@ -0,0 +1,62 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "I2CBus.h"
#include "ICommDevice.h"
namespace sdi_uToolBox::comm
{
//--------------------------------------------------------------
class I2CDevice : public ICommDevice
{
public:
I2CDevice() = delete; // Default constructor
explicit I2CDevice(I2CBus &bus, uint8_t address); // Constructor
virtual ~I2CDevice() override = default; // Default destructor
I2CDevice(const I2CDevice &) = delete; // Copy constructor
I2CDevice &operator=(const I2CDevice &) = delete; // Copy assignment operator
I2CDevice(I2CDevice &&) = delete; // Move constructor
I2CDevice &operator=(I2CDevice &&) = delete; // Move assignment operator
ReturnType write(WriteBuf buf, Timeout timeout) override; // Write data to device
ReturnType read(ReadBuf buf, Timeout timeout) override; // Read data from device
protected:
I2CBus &m_bus; // Reference to I2C bus
uint8_t m_address; // I2C device address
};
//--------------------------------------------------------------
//--------------------------------------------------------------
/* Constructor */
inline I2CDevice::I2CDevice(I2CBus &bus, const uint8_t address)
: m_bus(bus)
, m_address(address)
{
// Nothing to do
}
//--------------------------------------------------------------
/* Write data to device */
inline ICommDevice::ReturnType I2CDevice::write(const WriteBuf buf, const Timeout timeout)
{
return m_bus.write(m_address, buf, timeout);
}
//--------------------------------------------------------------
/* Read data from device */
inline ICommDevice::ReturnType I2CDevice::read(const ReadBuf buf, const Timeout timeout)
{
return m_bus.read(m_address, buf, timeout);
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::comm

View File

@@ -0,0 +1,34 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "../defs.h"
namespace sdi_uToolBox::comm
{
//--------------------------------------------------------------
class ICommBus
{
public:
ICommBus() = default; // Default constructor
virtual ~ICommBus() = default; // Default destructor
ICommBus(const ICommBus &) = delete; // Copy constructor
ICommBus &operator=(const ICommBus &) = delete; // Copy assignment operator
ICommBus(ICommBus &&) = delete; // Move constructor
ICommBus &operator=(ICommBus &&) = delete; // Move assignment operator
virtual ReturnStatus open() = 0; // Open communication bus
virtual ReturnStatus close() = 0; // Close communication bus
};
//--------------------------------------------------------------
} // namespace sdi_uToolBox::comm

View File

@@ -0,0 +1,46 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "../defs.h"
#include <chrono>
#include <expected>
#include <span>
namespace sdi_uToolBox::comm
{
//--------------------------------------------------------------
class ICommDevice
{
public:
using ReadBuf = std::span<uint8_t>;
using WriteBuf = std::span<const uint8_t>;
using Timeout = std::chrono::milliseconds;
using ReturnType = std::expected<size_t, ReturnStatus>;
static constexpr auto INFINITE_DURATION = Timeout(-1);
public:
ICommDevice() = default; // Default constructor
virtual ~ICommDevice() = default; // Default destructor
ICommDevice(const ICommDevice &) = delete; // Copy constructor
ICommDevice &operator=(const ICommDevice &) = delete; // Copy assignment operator
ICommDevice(ICommDevice &&) = delete; // Move constructor
ICommDevice &operator=(ICommDevice &&) = delete; // Move assignment operator
virtual ReturnType write(WriteBuf buf, Timeout timeout = INFINITE_DURATION) = 0; // Write data to device
virtual ReturnType read(ReadBuf buf, Timeout timeout = INFINITE_DURATION) = 0; // Read data from device
};
//--------------------------------------------------------------
} // namespace sdi_uToolBox::comm

View File

@@ -0,0 +1,47 @@
//{{copyright}}
//{{version}}
//{{license}}
#pragma once
#include "ICommBus.h"
#include <chrono>
#include <expected>
#include <span>
namespace sdi_uToolBox::comm
{
//--------------------------------------------------------------
class SerialBus : public ICommBus
{
public:
using ReadBuf = std::span<uint8_t>;
using WriteBuf = std::span<const uint8_t>;
using Timeout = std::chrono::milliseconds;
using ReturnType = std::expected<size_t, ReturnStatus>;
public:
SerialBus() = default; // Default constructor
virtual ~SerialBus() override = default; // Default destructor
SerialBus(const SerialBus&) = delete; // Copy constructor
SerialBus(SerialBus&&) = delete; // Move constructor
SerialBus& operator=(const SerialBus&) = delete; // Copy assignment operator
SerialBus& operator=(SerialBus&&) = delete; // Move assignment operator
virtual ReturnType write(WriteBuf buf, Timeout timeout) const = 0; // Write data to UART device
virtual ReturnType read(ReadBuf buf, Timeout timeout) const = 0; // Read data from UART device
virtual ReturnType readUntilIdle(ReadBuf buf, Timeout timeout) const; // Read data until IDLE event
};
//--------------------------------------------------------------
/* Read data until IDLE event */
inline SerialBus::ReturnType SerialBus::readUntilIdle(ReadBuf buf, Timeout timeout) const
{
return std::unexpected(ReturnStatus::IncompatibleBaseType);
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::comm

View File

@@ -0,0 +1,51 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "ICommBus.h"
#include <chrono>
#include <expected>
#include <span>
namespace sdi_uToolBox::comm
{
//--------------------------------------------------------------
class UARTBus : public ICommBus
{
public:
using ReadBuf = std::span<uint8_t>;
using WriteBuf = std::span<const uint8_t>;
using Timeout = std::chrono::milliseconds;
using ReturnType = std::expected<size_t, ReturnStatus>;
public:
UARTBus() = default; // Default constructor
virtual ~UARTBus() override = default; // Default destructor
UARTBus(const UARTBus &) = delete; // Copy constructor
UARTBus(UARTBus &&) = delete; // Move constructor
UARTBus &operator=(const UARTBus &) = delete; // Copy assignment operator
UARTBus &operator=(UARTBus &&) = delete; // Move assignment operator
virtual ReturnType write(WriteBuf buf, Timeout timeout) const = 0; // Write data to UART device
virtual ReturnType read(ReadBuf buf, Timeout timeout) const = 0; // Read data from UART device
virtual ReturnType readUntilIdle(ReadBuf buf, Timeout timeout) const; // Read data until IDLE event
};
//--------------------------------------------------------------
/* Read data until IDLE event */
inline UARTBus::ReturnType UARTBus::readUntilIdle(ReadBuf buf, Timeout timeout) const
{
return std::unexpected(ReturnStatus::IncompatibleBaseType);
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::comm

View File

@@ -0,0 +1,58 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <FreeRTOSHeaders.h>
#include <sdi_toolBox/dateTime/iPause.h>
namespace sdi_uToolBox::dateTime::FreeRTOS
{
//--------------------------------------------------------------
/**
* @brief FreeRTOS pause implementation.
*
* Implements IPause to provide a non-blocking pause using vTaskDelay
* in FreeRTOS environments.
*/
class Pause : public sdi_toolBox::dateTime::IPause
{
public:
Pause() = default; // Default constructor
~Pause() = default; // Default destructor
Pause(const Pause &obj) = default; // Copy constructor
Pause(Pause &&obj) noexcept = default; // Move constructor
Pause &operator=(const Pause &obj) = default; // Copy assignment operator
Pause &operator=(Pause &&obj) noexcept = default; // Move assignment operator
explicit Pause(const Duration &duration); // Constructor
/**
* @brief Pause execution for the specified duration using vTaskDelay.
* @param duration Duration of the pause.
*/
void wait(const Duration &duration) const override;
};
//--------------------------------------------------------------
/* Constructor */
inline Pause::Pause(const Duration &duration)
{
wait(duration);
}
//--------------------------------------------------------------
/* Pause execution for the specified duration */
inline void Pause::wait(const Duration &duration) const
{
vTaskDelay(pdMS_TO_TICKS(duration.count()));
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::dateTime::FreeRTOS

View File

@@ -0,0 +1,57 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <FreeRTOSHeaders.h>
#include <sdi_toolBox/dateTime/iTimer.h>
namespace sdi_uToolBox::dateTime::FreeRTOS
{
//--------------------------------------------------------------
/**
* @brief FreeRTOS timer implementation using the RTOS tick count.
*
* Implements ITimer for FreeRTOS environments, using xTaskGetTickCount()
* to provide timing based on the RTOS tick counter.
*/
class Timer : public sdi_toolBox::dateTime::ITimer
{
public:
Timer(); // Default constructor
~Timer() = default; // Default destructor
Timer(const Timer &obj) = default; // Copy constructor
Timer(Timer &&obj) noexcept = default; // Move constructor
Timer &operator=(const Timer &obj) = default; // Copy assignment operator
Timer &operator=(Timer &&obj) noexcept = default; // Move assignment operator
/**
* @brief Returns the current time point using the FreeRTOS tick count.
* @return The current time point.
*/
[[nodiscard]] TimePoint now() const override;
};
//--------------------------------------------------------------
/* Default constructor */
inline Timer::Timer()
{
reset();
}
//--------------------------------------------------------------
/* Get the current timepoint */
inline Timer::TimePoint Timer::now() const
{
const auto ms = xTaskGetTickCount() * portTICK_PERIOD_MS;
return TimePoint(Duration(ms));
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::dateTime::FreeRTOS

View File

@@ -0,0 +1,58 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <STM32Headers.h>
#include <sdi_toolBox/dateTime/iPause.h>
namespace sdi_uToolBox::dateTime
{
//--------------------------------------------------------------
/**
* @brief STM32 pause implementation.
*
* Implements IPause to provide a blocking pause using HAL_Delay
* on STM32 platforms.
*/
class Pause : public sdi_toolBox::dateTime::IPause
{
public:
Pause() = default; // Default constructor
~Pause() = default; // Default destructor
Pause(const Pause &obj) = default; // Copy constructor
Pause(Pause &&obj) noexcept = default; // Move constructor
Pause &operator=(const Pause &obj) = default; // Copy assignment operator
Pause &operator=(Pause &&obj) noexcept = default; // Move assignment operator
explicit Pause(const Duration &duration); // Constructor
/**
* @brief Pause execution for the specified duration using HAL_Delay.
* @param duration Duration of the pause.
*/
void wait(const Duration &duration) const override;
};
//--------------------------------------------------------------
/* Constructor */
inline Pause::Pause(const Duration &duration)
{
wait(duration);
}
//--------------------------------------------------------------
/* Pause execution for the specified duration */
inline void Pause::wait(const Duration &duration) const
{
HAL_Delay(duration.count());
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::dateTime

View File

@@ -0,0 +1,57 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <STM32Headers.h>
#include <sdi_toolBox/dateTime/iTimer.h>
namespace sdi_uToolBox::dateTime
{
//--------------------------------------------------------------
/**
* @brief STM32 timer implementation using HAL_GetTick().
*
* Implements ITimer for STM32 platforms, using HAL_GetTick() to
* provide millisecond-precision timing since system startup.
*/
class Timer : public sdi_toolBox::dateTime::ITimer
{
public:
Timer(); // Default constructor
~Timer() = default; // Default destructor
Timer(const Timer &obj) = default; // Copy constructor
Timer(Timer &&obj) noexcept = default; // Move constructor
Timer &operator=(const Timer &obj) = default; // Copy assignment operator
Timer &operator=(Timer &&obj) noexcept = default; // Move assignment operator
/**
* @brief Returns the current time point using HAL_GetTick().
* @return The current time point.
*/
[[nodiscard]] TimePoint now() const override;
};
//--------------------------------------------------------------
/* Default constructor */
inline Timer::Timer()
{
reset();
}
//--------------------------------------------------------------
/* Get the current timepoint */
inline Timer::TimePoint Timer::now() const
{
const auto ms = HAL_GetTick();
return TimePoint(Duration(ms));
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::dateTime

View File

@@ -0,0 +1,26 @@
//{{copyright}}
//{{version}}
//{{license}}
#pragma once
#include <cstdint>
namespace sdi_uToolBox
{
//--------------------------------------------------------------
/* Return status enumeration */
enum class ReturnStatus : uint8_t
{
Ok,
Busy,
Timeout,
Error,
IncompatibleBaseType,
InvalidHandle,
BufferOverflow,
};
//--------------------------------------------------------------
} // namespace sdi_uToolBox

View File

@@ -0,0 +1,154 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <FreeRTOSHeaders.h>
#include <chrono>
#include <mutex>
namespace sdi_uToolBox::generic::FreeRTOS
{
//--------------------------------------------------------------
class Mutex
{
public:
Mutex(); // Constructor
~Mutex(); // Destructor
Mutex(const Mutex &other) = delete; // Copy constructor
Mutex(Mutex &&other) = delete; // Move constructor
Mutex &operator=(const Mutex &other) = delete; // Copy assignment
Mutex &operator=(Mutex &&other) = delete; // Move assignment
void lock() const; // Locks the mutex, blocks if the mutex is not available
void unlock() const; // Unlocks the mutex
bool try_lock() const; // Tries to lock the mutex, returns if the mutex is not available
bool try_lock_for(const std::chrono::milliseconds &duration) const; // Attempts to lock the mutex, returns if the mutex is not available
protected:
SemaphoreHandle_t m_xSemaphore = nullptr;
};
//--------------------------------------------------------------
//--------------------------------------------------------------
/* Constructor */
inline Mutex::Mutex()
{
m_xSemaphore = xSemaphoreCreateMutex();
configASSERT(m_xSemaphore);
}
//--------------------------------------------------------------
/* Destructor */
inline Mutex::~Mutex()
{
if (!m_xSemaphore)
vSemaphoreDelete(m_xSemaphore);
}
//--------------------------------------------------------------
/* Locks the mutex, blocks if the mutex is not available */
inline void Mutex::lock() const
{
if (xSemaphoreTake(m_xSemaphore, portMAX_DELAY) != pdTRUE)
configASSERT(0);
}
//--------------------------------------------------------------
/* Unlocks the mutex */
inline void Mutex::unlock() const
{
xSemaphoreGive(m_xSemaphore);
}
//--------------------------------------------------------------
/* Tries to lock the mutex, returns if the mutex is not available */
inline bool Mutex::try_lock() const
{
return try_lock_for(std::chrono::milliseconds(0));
}
//--------------------------------------------------------------
/* Attempts to lock the mutex, returns if the mutex has been unavailable for the specified time duration */
inline bool Mutex::try_lock_for(const std::chrono::milliseconds &duration) const
{
const auto waitDelay = pdMS_TO_TICKS(duration.count());
if (xSemaphoreTakeRecursive(m_xSemaphore, waitDelay) == pdTRUE)
return true;
return false;
}
//--------------------------------------------------------------
/* --- */
//--------------------------------------------------------------
class RecursiveMutex
{
public:
RecursiveMutex(); // Constructor
~RecursiveMutex(); // Destructor
RecursiveMutex(const RecursiveMutex &other) = delete; // Copy constructor
RecursiveMutex(RecursiveMutex &&other) = delete; // Move constructor
RecursiveMutex &operator=(const RecursiveMutex &other) = delete; // Copy assignment
RecursiveMutex &operator=(RecursiveMutex &&other) = delete; // Move assignment
void lock() const; // Locks the mutex, blocks if the mutex is not available
void unlock() const; // Unlocks the mutex
bool try_lock() const; // Tries to lock the mutex, returns if the mutex is not available
bool try_lock_for(const std::chrono::milliseconds &duration) const; // Attempts to lock the mutex, returns if the mutex is not available
protected:
SemaphoreHandle_t m_xSemaphore = nullptr;
};
//--------------------------------------------------------------
//--------------------------------------------------------------
/* Constructor */
inline RecursiveMutex::RecursiveMutex()
{
m_xSemaphore = xSemaphoreCreateRecursiveMutex();
configASSERT(m_xSemaphore);
}
//--------------------------------------------------------------
/* Destructor */
inline RecursiveMutex::~RecursiveMutex()
{
if (!m_xSemaphore)
vSemaphoreDelete(m_xSemaphore);
}
//--------------------------------------------------------------
/* Locks the mutex, blocks if the mutex is not available */
inline void RecursiveMutex::lock() const
{
if (xSemaphoreTakeRecursive(m_xSemaphore, portMAX_DELAY) != pdTRUE)
configASSERT(0);
}
//--------------------------------------------------------------
/* Unlocks the mutex */
inline void RecursiveMutex::unlock() const
{
xSemaphoreGiveRecursive(m_xSemaphore);
}
//--------------------------------------------------------------
/* Tries to lock the mutex, returns if the mutex is not available */
inline bool RecursiveMutex::try_lock() const
{
return try_lock_for(std::chrono::milliseconds(0));
}
//--------------------------------------------------------------
/* Attempts to lock the mutex, returns if the mutex has been unavailable for the specified time duration */
inline bool RecursiveMutex::try_lock_for(const std::chrono::milliseconds &duration) const
{
const auto waitDelay = pdMS_TO_TICKS(duration.count());
if (xSemaphoreTakeRecursive(m_xSemaphore, waitDelay) == pdTRUE)
return true;
return false;
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::generic::FreeRTOS

View File

@@ -0,0 +1,127 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <FreeRTOSHeaders.h>
#include <chrono>
namespace sdi_uToolBox::generic::FreeRTOS
{
//--------------------------------------------------------------
class Semaphore
{
using Timeout = std::chrono::milliseconds;
public:
Semaphore() = delete; // Default constructor
~Semaphore(); // Default destructor
Semaphore(const Semaphore &other) = delete; // Copy constructor
Semaphore(Semaphore &&other) = delete; // Move constructor
Semaphore &operator=(const Semaphore &other) = delete; // Copy assignment
Semaphore &operator=(Semaphore &&other) = delete; // Move assignment
explicit Semaphore(size_t maxCount = 1, size_t initialCount = 0); // Constructor
bool give() const; // Give/release the semaphore
bool giveFromISR() const; // Give/release the semaphore from ISR
bool take(Timeout timeout) const; // Take/acquire the semaphore with timeout
bool take() const; // Take/acquire the semaphore without timeout (blocking)
protected:
SemaphoreHandle_t m_xSemaphore = nullptr;
};
//--------------------------------------------------------------
/* Constructor */
inline Semaphore::Semaphore(const size_t maxCount, const size_t initialCount)
{
if (maxCount == 1)
{
// Binary semaphore
m_xSemaphore = xSemaphoreCreateBinary();
if (m_xSemaphore && initialCount > 0)
xSemaphoreGive(m_xSemaphore);
}
else
{
// Counting semaphore
m_xSemaphore = xSemaphoreCreateCounting(maxCount, initialCount);
}
configASSERT(m_xSemaphore);
}
//--------------------------------------------------------------
/* Default destructor */
inline Semaphore::~Semaphore()
{
if (m_xSemaphore)
vSemaphoreDelete(m_xSemaphore);
}
//--------------------------------------------------------------
/* Give/release the semaphore */
inline bool Semaphore::give() const
{
return xSemaphoreGive(m_xSemaphore) == pdTRUE;
}
//--------------------------------------------------------------
/* Give/release the semaphore from ISR */
inline bool Semaphore::giveFromISR() const
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
const bool result = xSemaphoreGiveFromISR(m_xSemaphore, &xHigherPriorityTaskWoken) == pdTRUE;
portYIELD_FROM_ISR(xHigherPriorityTaskWoken); // Request a context switch if needed
return result;
}
//--------------------------------------------------------------
/* Take/acquire the semaphore with timeout */
inline bool Semaphore::take(const Timeout timeout) const
{
const TickType_t xTicksToWait = (timeout.count() == 0) ? 0 : pdMS_TO_TICKS(timeout.count());
return xSemaphoreTake(m_xSemaphore, xTicksToWait) == pdTRUE;
}
//--------------------------------------------------------------
/* Take/acquire the semaphore without timeout (blocking) */
inline bool Semaphore::take() const
{
return xSemaphoreTake(m_xSemaphore, portMAX_DELAY) == pdTRUE;
}
//--------------------------------------------------------------
/* --- */
//--------------------------------------------------------------
/* Binary Semaphore helper class */
class BinarySemaphore : public Semaphore
{
public:
explicit BinarySemaphore(const bool initialState = false)
: Semaphore(1, initialState ? 1 : 0)
{
}
};
//--------------------------------------------------------------
/* --- */
//--------------------------------------------------------------
class CountingSemaphore : public Semaphore
{
/* Counting Semaphore helper class */
public:
explicit CountingSemaphore(const uint32_t maxCount, const uint32_t initialCount = 0)
: Semaphore(maxCount, initialCount)
{
}
};
//--------------------------------------------------------------
} // namespace sdi_uToolBox::generic::FreeRTOS

View File

@@ -0,0 +1,154 @@
//{{copyright}}
//{{version}}
//{{license}}
#pragma once
#include <FreeRTOSHeaders.h>
#include <string>
namespace sdi_uToolBox::generic::FreeRTOS
{
//--------------------------------------------------------------
class Task
{
public:
Task() = default; // Constructor
virtual ~Task(); // Destructor
Task(const Task &other) = delete; // Copy constructor
Task(Task &&other) noexcept = delete; // Move constructor
Task &operator=(const Task &other) = delete; // Copy assignment
Task &operator=(Task &&other) noexcept = delete; // Move assignment
bool startTask(); // Create and start a FreeRTOS task
void stopTask(); // Stop and destroy the task
[[nodiscard]] bool isTaskRunning() const; // Return true if the task is running
[[nodiscard]] TaskHandle_t getTaskHandle() const; // Return the task handle
protected:
TaskHandle_t m_taskHandle = nullptr;
virtual void on_taskCreated(); // Function called after successful task creation (before execution)
virtual void on_taskStarted(); // Function called after task starts
virtual void on_taskStopped(); // Function called before task stops
private:
virtual void processTask() = 0; // Task implementation
[[nodiscard]] virtual std::string getTaskName() const; // Return a name for the task
[[nodiscard]] virtual size_t getTaskStackSize() const; // Return stack size in words, not bytes
[[nodiscard]] virtual size_t getTaskPriority() const; // Return priority at which the task is created
bool m_runningFlag = false;
static void taskCode(void *pThis); // Task implementation
};
//--------------------------------------------------------------
//--------------------------------------------------------------
/* Destructor */
inline Task::~Task()
{
stopTask();
}
//--------------------------------------------------------------
/* Create and start a FreeRTOS task */
inline bool Task::startTask()
{
if (isTaskRunning())
return true;
const auto xReturned = xTaskCreate(taskCode, // Function that implements the task
getTaskName().c_str(), // Text name for the task
getTaskStackSize(), // Stack size in words, not bytes
(void *)this, // Parameter passed into the task
getTaskPriority(), // Priority at which the task is created
&m_taskHandle); // Used to pass out the created task's handle
m_runningFlag = (xReturned == pdPASS);
if (m_runningFlag)
on_taskCreated();
return m_runningFlag;
}
//--------------------------------------------------------------
/* Stop and destroy the task */
inline void Task::stopTask()
{
if (m_taskHandle)
vTaskDelete(m_taskHandle);
m_taskHandle = nullptr;
m_runningFlag = false;
}
//--------------------------------------------------------------
/* Return true if the task is running */
inline bool Task::isTaskRunning() const
{
return m_runningFlag;
}
//--------------------------------------------------------------
/* Return the task handle */
inline TaskHandle_t Task::getTaskHandle() const
{
return m_taskHandle;
}
//--------------------------------------------------------------
/* Function called after successful task creation (before execution) */
inline void Task::on_taskCreated()
{
// Nothing to do...
}
//--------------------------------------------------------------
/* Function called after task starts */
inline void Task::on_taskStarted()
{
// Nothing to do...
}
//--------------------------------------------------------------
/* Function called after before stops */
inline void Task::on_taskStopped()
{
// Nothing to do...
}
//--------------------------------------------------------------
/* Return a name for the task */
inline std::string Task::getTaskName() const
{
return "";
}
//--------------------------------------------------------------
/* Return stack size in words, not bytes */
inline size_t Task::getTaskStackSize() const
{
return configMINIMAL_STACK_SIZE;
}
//--------------------------------------------------------------
/* Return priority at which the task is created */
inline size_t Task::getTaskPriority() const
{
return tskIDLE_PRIORITY + 1;
}
//--------------------------------------------------------------
/* Task implementation */
inline void Task::taskCode(void *pThis)
{
const auto task = static_cast<Task *>(pThis);
// At task starts
if (task->m_runningFlag)
task->on_taskStarted();
// Main task loop
while (task->m_runningFlag)
task->processTask();
// At task stops
task->on_taskStopped();
task->stopTask();
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::generic::FreeRTOS

View File

@@ -0,0 +1,187 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "../../defs.h"
#include <FreeRTOSHeaders.h>
#include <algorithm>
#include <span>
namespace sdi_uToolBox::generic::FreeRTOS
{
//--------------------------------------------------------------
/**
* @class TaskInspector
* @brief Utility class for inspecting FreeRTOS task statistics and runtime information.
*
* This class provides static methods to retrieve information about tasks,
* such as their name, priority, runtime statistics, and stack usage.
* It is designed for embedded systems and avoids dynamic memory allocation.
*
* @note Required FreeRTOSConfig.h options:
* - configUSE_TRACE_FACILITY must be set to 1
* - configUSE_RECURSIVE_MUTEXES must be set to 1
*/
class TaskInspector
{
static constexpr size_t MAX_TASKS = 16;
public:
/**
* @struct TaskInfo
* @brief Structure holding detailed information about a FreeRTOS task.
*/
struct TaskInfo
{
const char *taskName = nullptr; // Task name
UBaseType_t currentPriority = 0; // Task current priority
UBaseType_t basePriority = 0; // Task base priority
uint32_t runTimeCounter = 0; // Total run time counter
eTaskState currentState = eInvalid; // Task state
UBaseType_t stackHighWaterMark = 0; // Stack high watermark
};
/**
* @struct RuntimeStats
* @brief Structure holding global runtime statistics for all tasks.
*/
struct RuntimeStats
{
uint32_t totalRunTime = 0; // Total run time of all tasks
uint32_t numberOfTasks = 0; // Number of tasks
};
/**
* @struct TaskRuntimeStat
* @brief Structure holding runtime statistics for a single task.
*/
struct TaskRuntimeStat
{
const char *taskName = nullptr; // Task name
uint32_t runTimeCounter = 0; // Total run time counter
Real cpuUsage = 0.0f; // CPU usage percentage
};
public:
TaskInspector() = delete; // Default constructor
~TaskInspector() = default; // Default destructor
TaskInspector(const TaskInspector &obj) = delete; // Copy constructor
TaskInspector(TaskInspector &&obj) noexcept = delete; // Move constructor
TaskInspector &operator=(const TaskInspector &obj) = delete; // Copy assignment operator
TaskInspector &operator=(TaskInspector &&obj) noexcept = delete; // Move assignment operator
/**
* @brief Retrieves information about a specific task or the current task if no handle is provided.
* @param taskHandle The handle of the task to inspect (optional).
* @return TaskInfo structure with the task's information.
*/
[[nodiscard]] static TaskInfo getTaskInfo(TaskHandle_t taskHandle = nullptr);
/**
* @brief Retrieves global runtime statistics for all tasks.
* @return RuntimeStats structure with the global runtime statistics.
*/
[[nodiscard]] static RuntimeStats GetRuntimeStats();
/**
* @brief Retrieves the number of tasks currently running.
* @return The number of tasks.
*/
[[nodiscard]] static size_t GetTaskCount();
/**
* @brief Retrieves runtime statistics for all tasks.
* @param statsArray A span to an array where task runtime statistics will be stored.
* @return The number of tasks for which statistics were retrieved.
*/
[[nodiscard]] static size_t GetTasksRuntimeStats(std::span<TaskRuntimeStat> statsArray);
};
//--------------------------------------------------------------
/* Retrieves information about the current task */
inline TaskInspector::TaskInfo TaskInspector::getTaskInfo(TaskHandle_t taskHandle)
{
#if (configUSE_RECURSIVE_MUTEXES != 1)
# error "configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h"
#endif
#if (configUSE_TRACE_FACILITY != 1)
# error "configUSE_TRACE_FACILITY must be set to 1 in FreeRTOSConfig.h"
#endif
TaskInfo taskInfo;
if (!taskHandle)
{
taskHandle = xTaskGetCurrentTaskHandle();
if (!taskHandle)
return taskInfo;
}
// Get task info
TaskStatus_t taskStatus;
vTaskGetInfo(taskHandle, &taskStatus, pdTRUE, eInvalid);
// Fill task info structure
taskInfo.taskName = taskStatus.pcTaskName;
taskInfo.currentPriority = taskStatus.uxCurrentPriority;
taskInfo.basePriority = taskStatus.uxBasePriority;
taskInfo.runTimeCounter = taskStatus.ulRunTimeCounter;
taskInfo.currentState = taskStatus.eCurrentState;
taskInfo.stackHighWaterMark = taskStatus.usStackHighWaterMark;
return taskInfo;
}
//--------------------------------------------------------------
/* Retrieves global runtime statistics for all tasks */
inline TaskInspector::RuntimeStats TaskInspector::GetRuntimeStats()
{
#if (configUSE_TRACE_FACILITY != 1)
# error "configUSE_TRACE_FACILITY must be set to 1 in FreeRTOSConfig.h"
#endif
RuntimeStats stats;
stats.numberOfTasks = uxTaskGetNumberOfTasks();
uxTaskGetSystemState(nullptr, 0, &stats.totalRunTime);
return stats;
}
//--------------------------------------------------------------
/* Retrieves the number of tasks */
inline size_t TaskInspector::GetTaskCount()
{
return uxTaskGetNumberOfTasks();
}
//--------------------------------------------------------------
/* Retrieves runtime statistics for all tasks */
inline size_t TaskInspector::GetTasksRuntimeStats(std::span<TaskRuntimeStat> statsArray)
{
#if (configUSE_TRACE_FACILITY != 1)
# error "configUSE_TRACE_FACILITY must be set to 1 in FreeRTOSConfig.h"
#endif
size_t numTasks = uxTaskGetNumberOfTasks();
numTasks = std::min({ numTasks, statsArray.size(), MAX_TASKS });
TaskStatus_t statusArray[MAX_TASKS];
uint32_t totalRunTime = 0;
uxTaskGetSystemState(statusArray, numTasks, &totalRunTime);
for (size_t i = 0; i < numTasks; i++)
{
auto &stat = statsArray[i];
stat.taskName = statusArray[i].pcTaskName;
stat.runTimeCounter = statusArray[i].ulRunTimeCounter;
stat.cpuUsage = (totalRunTime > 0) ? (100.0f * static_cast<Real>(stat.runTimeCounter) / static_cast<Real>(totalRunTime)) : 0.0f;
}
return numTasks;
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::generic::FreeRTOS

View File

@@ -0,0 +1,73 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <functional>
namespace sdi_uToolBox::generic
{
//--------------------------------------------------------------
class IGPIO
{
public:
enum class PinType
{
Invalid,
Input,
ReversedInput,
Output, // HIGH level to enable
ReversedOutput, // LOW level to enable
};
public:
IGPIO() = default; // Constructor
virtual ~IGPIO() = default; // Destructor
IGPIO(const IGPIO &other) = delete; // Copy constructor
IGPIO(IGPIO &&other) noexcept = delete; // Move constructor
IGPIO &operator=(const IGPIO &other) = delete; // Copy assignment
IGPIO &operator=(IGPIO &&other) noexcept = delete; // Move assignment
virtual void set(bool enable = true) const = 0; // Sets/Resets IO state
void reset() const; // Resets IO state
virtual bool get() const = 0; // Returns IO state
virtual void toggle() const; // Flips IO state
using Callback = std::function<void()>;
void setITCallback(const Callback &callback); // Defines the callback function for a possible interruption
protected:
Callback m_itCallback = nullptr;
};
//--------------------------------------------------------------
//--------------------------------------------------------------
/* Resets IO state */
inline void IGPIO::reset() const
{
set(false);
}
//--------------------------------------------------------------
/* Flips IO state */
inline void IGPIO::toggle() const
{
const auto newValue = !get();
set(newValue);
}
//--------------------------------------------------------------
/* Defines the callback function for a possible interruption */
inline void IGPIO::setITCallback(const Callback &callback)
{
m_itCallback = callback;
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::generic

View File

@@ -0,0 +1,69 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <cstdint>
#include <span>
namespace sdi_uToolBox::generic
{
//--------------------------------------------------------------
class II2CBus
{
public:
enum class I2CStatus
{
Ok,
Timeout,
Error,
Busy,
};
public:
II2CBus() = default; // Constructor
virtual ~II2CBus() = default; // Destructor
II2CBus(const II2CBus &other) = delete; // Copy constructor
II2CBus(II2CBus &&other) noexcept = delete; // Move constructor
II2CBus &operator=(const II2CBus &other) = delete; // Copy assignment
II2CBus &operator=(II2CBus &&other) noexcept = delete; // Move assignment
virtual I2CStatus read(const uint8_t chipAddress, const std::span<uint8_t> &buffer) = 0; // Read data from I2C device
I2CStatus read(const uint8_t chipAddress, uint8_t &value); // Read data from I2C device
virtual I2CStatus write(const uint8_t chipAddress, const std::span<const uint8_t> &buffer) = 0; // Write data to I2C device
I2CStatus write(const uint8_t chipAddress, const uint8_t &value); // Write data to I2C device
// virtual I2CStatus readEeprom(const uint8_t chipAddress, const uint32_t memoryAddress, const std::span<uint8_t> &buffer) = 0; // Read data from I2C memory device
// virtual I2CStatus writeEeprom(const uint8_t chipAddress, const uint32_t memoryAddress, const std::span<const uint8_t> &buffer) = 0; // Write data to I2C memory device
virtual I2CStatus isDeviceReady(const uint8_t chipAddress) = 0; // Check device readiness
};
//--------------------------------------------------------------
//--------------------------------------------------------------
inline II2CBus::I2CStatus II2CBus::read(const uint8_t chipAddress, uint8_t &value)
{
// Create a std::span pointing to the single byte 'value'
std::span<uint8_t, 1> single_byte_span{ &value, 1 };
return read(chipAddress, single_byte_span);
}
//--------------------------------------------------------------
inline II2CBus::I2CStatus II2CBus::write(const uint8_t chipAddress, const uint8_t &value)
{
// Create a std::span pointing to the single byte 'value'
std::span<const uint8_t, 1> single_byte_span{ &value, 1 };
return write(chipAddress, single_byte_span);
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::generic

View File

@@ -0,0 +1,47 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <chrono>
#include <cstdint>
#include <span>
namespace sdi_uToolBox::generic
{
//--------------------------------------------------------------
class IStream
{
public:
IStream() = default; // Constructor
virtual ~IStream() = default; // Destructor
IStream(const IStream &other) = delete; // Copy constructor
IStream(IStream &&other) noexcept = delete; // Move constructor
IStream &operator=(const IStream &other) = delete; // Copy assignment
IStream &operator=(IStream &&other) noexcept = delete; // Move assignment
virtual size_t write(const std::span<const uint8_t> buffer) = 0; // Writes a block of data to the stream
virtual size_t read(const std::span<uint8_t> buffer) = 0; // Reads a block of data from the stream
virtual size_t read(const std::span<uint8_t> buffer, const std::chrono::milliseconds ms); // If available, wait for block of data from the stream
virtual bool isDataAvailable() const = 0; // Checks if the stream has data available for reading
};
//--------------------------------------------------------------
//--------------------------------------------------------------
/* If available, wait for block of data from the stream */
inline size_t IStream::read(const std::span<uint8_t> buffer, const std::chrono::milliseconds ms)
{
return read(buffer);
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::generic

View File

@@ -0,0 +1,113 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "../../generic/FreeRTOS/mutex.h"
#include "../HIDBus.h"
namespace sdi_uToolBox::stm32::FreeRTOS
{
//--------------------------------------------------------------
template<size_t QUEUE_SIZE>
class HIDBus : public stm32::HIDBus<0>
{
public:
HIDBus(); // Constructor
~HIDBus() override = default; // Destructor
HIDBus(const HIDBus &other) = delete; // Copy constructor
HIDBus(HIDBus &&other) noexcept = delete; // Move constructor
HIDBus &operator=(const HIDBus &other) = delete; // Copy assignment
HIDBus &operator=(HIDBus &&other) noexcept = delete; // Move assignment
void onReceiveData(std::span<const uint8_t> buf) override;
size_t write(const std::span<const uint8_t> buffer) override;
size_t read(const std::span<uint8_t> buffer) override; // Reads a block of data from the stream
size_t read(const std::span<uint8_t> buffer, const std::chrono::milliseconds ms) override; // If available, wait for block of data from the stream
bool isDataAvailable() const override; // Checks if the stream has data available for reading
protected:
sdi_uToolBox::generic::FreeRTOS::Mutex m_mtx;
QueueHandle_t m_uartRxQueue = nullptr;
};
//--------------------------------------------------------------
//--------------------------------------------------------------
/* Constructor */
template<size_t QUEUE_SIZE>
inline HIDBus<QUEUE_SIZE>::HIDBus()
{
// Initialization of FreeRTOS queue
m_uartRxQueue = xQueueCreate(QUEUE_SIZE, sizeof(uint8_t));
}
//--------------------------------------------------------------
/* Receive data from interuption */
template<size_t QUEUE_SIZE>
void HIDBus<QUEUE_SIZE>::onReceiveData(std::span<const uint8_t> buf)
{
auto xHigherPriorityTaskWoken = pdFALSE;
// Copy each bytes into the queue
for (const auto byte : buf)
{
xQueueSendFromISR(m_uartRxQueue,
&byte,
&xHigherPriorityTaskWoken);
// If the data reception has woken up a higher priority task,
// force a context switch immediately after the ISR
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
//--------------------------------------------------------------
template<size_t QUEUE_SIZE>
size_t HIDBus<QUEUE_SIZE>::write(const std::span<const uint8_t> buffer)
{
std::lock_guard lock(m_mtx);
return stm32::HIDBus<0>::write(buffer);
}
//--------------------------------------------------------------
/* Reads a block of data from the stream */
template<size_t QUEUE_SIZE>
inline size_t HIDBus<QUEUE_SIZE>::read(const std::span<uint8_t> buffer)
{
return read(buffer, std::chrono::milliseconds(0));
}
//--------------------------------------------------------------
/* If available, wait for block of data from the stream */
template<size_t QUEUE_SIZE>
inline size_t HIDBus<QUEUE_SIZE>::read(const std::span<uint8_t> buffer, const std::chrono::milliseconds ms)
{
for (size_t i = 0; i < buffer.size(); i++)
{
uint8_t received_byte;
if (xQueueReceive(m_uartRxQueue,
&received_byte,
pdMS_TO_TICKS(ms.count())) != pdPASS)
return i;
buffer[i] = received_byte;
}
return buffer.size();
}
//--------------------------------------------------------------
/* Checks if the stream has data available for reading */
template<size_t QUEUE_SIZE>
inline bool HIDBus<QUEUE_SIZE>::isDataAvailable() const
{
const auto count = uxQueueMessagesWaiting(m_uartRxQueue);
return count > 0;
}
//--------------------------------------------------------------
//--------------------------------------------------------------
} // namespace sdi_uToolBox::stm32::FreeRTOS

View File

@@ -0,0 +1,131 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "../generic/iGPIO.h"
#include <STM32Headers.h>
#include <array>
namespace sdi_uToolBox::stm32
{
//--------------------------------------------------------------
class GPIO : public sdi_uToolBox::generic::IGPIO
{
public:
struct GpioDefs
{
GPIO_TypeDef *port = nullptr;
uint16_t pin = 0;
PinType type = PinType::Invalid;
};
public:
void configure(const GpioDefs &gpioDefs); // GPIO configuration
[[nodiscard]] GPIO_TypeDef *getPort() const; // Returns IO port
[[nodiscard]] uint16_t getPin() const; // Returns IO pin
[[nodiscard]] PinType getType() const; // Returns IO type
void set(bool enable = true) const override; // Sets/Resets IO state
[[nodiscard]] bool get() const override; // Returns IO state
void toggle() const override; // Flips IO state
void enableEvent(bool enable = true); // Adds / remove GPIO handle in the indexed pin event handle list
static void on_GpioIT(uint16_t pin); // Checks GPIO IT
protected:
GpioDefs m_gpioDefs;
static inline std::array<GPIO *, 16> m_ITListHdl{}; // List of indexed pin IT handles
};
//--------------------------------------------------------------
//--------------------------------------------------------------
/* GPIO configuration */
inline void GPIO::configure(const GpioDefs &gpioDefs)
{
m_gpioDefs = gpioDefs;
}
//--------------------------------------------------------------
/* Return IO port */
inline GPIO_TypeDef *GPIO::getPort() const
{
return m_gpioDefs.port;
}
//--------------------------------------------------------------
/* Return IO pin */
inline uint16_t GPIO::getPin() const
{
return m_gpioDefs.pin;
}
//--------------------------------------------------------------
/* Return IO type */
inline GPIO::PinType GPIO::getType() const
{
return m_gpioDefs.type;
}
//--------------------------------------------------------------
/* Set/Reset logical IO state */
inline void GPIO::set(bool enable) const
{
if (m_gpioDefs.type == PinType::ReversedOutput)
enable = !enable;
HAL_GPIO_WritePin(m_gpioDefs.port,
m_gpioDefs.pin,
(enable) ? GPIO_PIN_SET : GPIO_PIN_RESET);
}
//--------------------------------------------------------------
/* Return logical IO state */
inline bool GPIO::get() const
{
const auto state = (GPIO_PIN_SET == HAL_GPIO_ReadPin(m_gpioDefs.port, m_gpioDefs.pin));
if (m_gpioDefs.type == PinType::ReversedOutput || m_gpioDefs.type == PinType::ReversedInput)
return !state;
return state;
}
//--------------------------------------------------------------
/* Flip IO state */
inline void GPIO::toggle() const
{
HAL_GPIO_TogglePin(m_gpioDefs.port, m_gpioDefs.pin);
}
//--------------------------------------------------------------
/* Add / remove GPIO handle in the indexed pin event handle list */
inline void GPIO::enableEvent(bool enable)
{
const size_t pinIndex = __builtin_clz(m_gpioDefs.pin);
if (pinIndex >= m_ITListHdl.size())
return;
if (enable)
m_ITListHdl[pinIndex] = this;
else
m_ITListHdl[pinIndex] = nullptr;
}
//--------------------------------------------------------------
/* Check GPIO IT
*/
inline void GPIO::on_GpioIT(uint16_t pin)
{
const size_t pinIndex = __builtin_clz(pin);
if (pinIndex < m_ITListHdl.size())
{
if (m_ITListHdl[pinIndex] && m_ITListHdl[pinIndex]->getPin() == pin)
m_ITListHdl[pinIndex]->m_itCallback();
}
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::stm32

View File

@@ -0,0 +1,102 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "../generic/iStream.h"
#include <STM32Headers.h>
namespace sdi_uToolBox::stm32
{
//--------------------------------------------------------------
template<size_t QUEUE_SIZE>
class HIDBus : public sdi_uToolBox::generic::IStream
{
public:
HIDBus() = default; // Constructor
~HIDBus() override = default; // Destructor
HIDBus(const HIDBus &other) = delete; // Copy constructor
HIDBus(HIDBus &&HIDBus) noexcept = delete; // Move constructor
HIDBus &operator=(const HIDBus &other) = delete; // Copy assignment
HIDBus &operator=(HIDBus &&other) noexcept = delete; // Move assignment
void configure(USBD_HandleTypeDef *usbdHdl); // Bus configuration
[[nodiscard]] USBD_HandleTypeDef *getBus() const; // Returns bus handle
virtual void onReceiveData(std::span<const uint8_t> buf); // Read data
size_t write(const std::span<const uint8_t> buffer) override;
size_t read(const std::span<uint8_t> buffer) override;
bool isDataAvailable() const override;
protected:
USBD_HandleTypeDef *m_usbdHdl = nullptr;
sdi_toolBox::generic::CircularBuffer<uint8_t, QUEUE_SIZE> m_rxBuffer;
};
//--------------------------------------------------------------
//--------------------------------------------------------------
/* Bus configuration */
template<size_t QUEUE_SIZE>
inline void HIDBus<QUEUE_SIZE>::configure(USBD_HandleTypeDef *usbdHdl)
{
m_usbdHdl = usbdHdl;
}
//--------------------------------------------------------------
/* Returns bus handle */
template<size_t QUEUE_SIZE>
inline USBD_HandleTypeDef *HIDBus<QUEUE_SIZE>::getBus() const
{
return m_usbdHdl;
}
//--------------------------------------------------------------
/* Read data from IT and restart the reading process */
template<size_t QUEUE_SIZE>
inline void HIDBus<QUEUE_SIZE>::onReceiveData(const std::span<const uint8_t> buf)
{
for (const auto &c : buf)
m_rxBuffer.push(c);
}
//--------------------------------------------------------------
template<size_t QUEUE_SIZE>
size_t HIDBus<QUEUE_SIZE>::write(const std::span<const uint8_t> buffer)
{
USBD_CUSTOM_HID_SendReport(m_usbdHdl, const_cast<uint8_t*>(buffer.data()), buffer.size());
return 0;//TODO: correct return value
}
template<size_t QUEUE_SIZE>
size_t HIDBus<QUEUE_SIZE>::read(const std::span<uint8_t> buffer)
{
CriticalSection criticalSection;
for (size_t i = 0; i < buffer.size(); i++)
{
const auto data = m_rxBuffer.pop();
if (!data)
return i;
buffer[i] = *data;
}
return buffer.size();
}
template<size_t QUEUE_SIZE>
bool HIDBus<QUEUE_SIZE>::isDataAvailable() const
{
CriticalSection criticalSection;
return !m_rxBuffer.isEmpty();
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::stm32

View File

@@ -0,0 +1,117 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "../generic/iI2CBus.h"
#include <STM32Headers.h>
namespace sdi_uToolBox::stm32
{
//--------------------------------------------------------------
class I2CBus : public sdi_uToolBox::generic::II2CBus
{
public:
void configure(I2C_HandleTypeDef *i2cHdl, // Bus configuration
const uint32_t delay = HAL_MAX_DELAY);
[[nodiscard]] I2C_HandleTypeDef *getBus() const; // Returns bus handle
[[nodiscard]] uint32_t getDelay() const; // Returns timeout delay
I2CStatus write(const uint8_t chipAddress, const std::span<const uint8_t> &buffer) override; // Write data to I2C device
I2CStatus read(const uint8_t chipAddress, const std::span<uint8_t> &buffer) override; // Read data from I2C device
I2CStatus isDeviceReady(const uint8_t chipAddress) override; // Check device readiness
protected:
I2C_HandleTypeDef *m_i2cHandle = nullptr;
uint32_t m_delay = 0;
};
//--------------------------------------------------------------
//--------------------------------------------------------------
/* Bus configuration */
inline void I2CBus::configure(I2C_HandleTypeDef *i2cHdl, const uint32_t delay)
{
m_i2cHandle = i2cHdl;
m_delay = delay;
}
//--------------------------------------------------------------
/* Returns bus handle */
inline I2C_HandleTypeDef *I2CBus::getBus() const
{
return m_i2cHandle;
}
//--------------------------------------------------------------
/* Return IO pin */
inline uint32_t I2CBus::getDelay() const
{
return m_delay;
}
//--------------------------------------------------------------
/* Write data to I2C device */
inline I2CBus::I2CStatus I2CBus::write(const uint8_t chipAddress, const std::span<const uint8_t> &buffer)
{
const auto ret = HAL_I2C_Master_Transmit(m_i2cHandle,
chipAddress << 1,
const_cast<uint8_t *>(buffer.data()),
buffer.size(),
m_delay);
if (ret == HAL_OK)
return I2CStatus::Ok;
else if (ret == HAL_BUSY)
return I2CStatus::Busy;
else if (ret == HAL_ERROR && m_i2cHandle->ErrorCode == HAL_I2C_ERROR_TIMEOUT)
return I2CStatus::Timeout;
else
return I2CStatus::Error;
}
//--------------------------------------------------------------
/* Read data from I2C device */
inline I2CBus::I2CStatus I2CBus::read(const uint8_t chipAddress, const std::span<uint8_t> &buffer)
{
const auto ret = HAL_I2C_Master_Receive(m_i2cHandle,
chipAddress << 1,
buffer.data(),
buffer.size(),
m_delay);
if (ret == HAL_OK)
return I2CStatus::Ok;
else if (ret == HAL_BUSY)
return I2CStatus::Busy;
else if (ret == HAL_ERROR && m_i2cHandle->ErrorCode == HAL_I2C_ERROR_TIMEOUT)
return I2CStatus::Timeout;
else
return I2CStatus::Error;
}
//--------------------------------------------------------------
/* Check device readiness */
inline I2CBus::I2CStatus I2CBus::isDeviceReady(const uint8_t chipAddress)
{
const auto ret = HAL_I2C_IsDeviceReady(m_i2cHandle,
chipAddress << 1,
5,
m_delay);
if (ret == HAL_OK)
return I2CStatus::Ok;
else if (ret == HAL_BUSY)
return I2CStatus::Busy;
else if (ret == HAL_ERROR && m_i2cHandle->ErrorCode == HAL_I2C_ERROR_TIMEOUT)
return I2CStatus::Timeout;
else
return I2CStatus::Error;
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::stm32

View File

@@ -0,0 +1,83 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "../generic/iStream.h"
#include <STM32Headers.h>
#include <array>
#include <cstring>
namespace sdi_uToolBox::stm32
{
//--------------------------------------------------------------
template<size_t UART_RX_BUFFER_SIZE, size_t UART_TX_BUFFER_SIZE>
class UARTBus : public sdi_uToolBox::generic::IStream
{
public:
UARTBus() = default; // Constructor
~UARTBus() override = default; // Destructor
UARTBus(const UARTBus &other) = delete; // Copy constructor
UARTBus(UARTBus &&UARTBus) noexcept = delete; // Move constructor
UARTBus &operator=(const UARTBus &other) = delete; // Copy assignment
UARTBus &operator=(UARTBus &&other) noexcept = delete; // Move assignment
void configure(UART_HandleTypeDef *uartHdl); // Bus configuration
[[nodiscard]] UART_HandleTypeDef *getBus() const; // Returns bus handle
void onReceiveData_fromISR(const size_t size); // Read data from IT and restart the reading process
protected:
UART_HandleTypeDef *m_uartHdl = nullptr;
std::array<uint8_t, UART_RX_BUFFER_SIZE> m_uartRXBuffer;
std::array<uint8_t, UART_TX_BUFFER_SIZE> m_uartTXBuffer;
private:
virtual void initDevice() = 0; // Device initialization
virtual bool startReceiving() = 0; // Start specific receiving method (IT, DMA, ...)
virtual void receiveData_fromISR(const uint8_t *buffer, const size_t size) = 0; // Receive data from interuption
};
//--------------------------------------------------------------
//--------------------------------------------------------------
/* Bus configuration */
template<size_t UART_RX_BUFFER_SIZE, size_t UART_TX_BUFFER_SIZE>
inline void UARTBus<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE>::configure(UART_HandleTypeDef *uartHdl)
{
m_uartHdl = uartHdl;
}
//--------------------------------------------------------------
/* Returns bus handle */
template<size_t UART_RX_BUFFER_SIZE, size_t UART_TX_BUFFER_SIZE>
inline UART_HandleTypeDef *UARTBus<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE>::getBus() const
{
return m_uartHdl;
}
//--------------------------------------------------------------
/* Read data from IT and restart the reading process */
template<size_t UART_RX_BUFFER_SIZE, size_t UART_TX_BUFFER_SIZE>
inline void UARTBus<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE>::onReceiveData_fromISR(const size_t size)
{
// Read data
receiveData_fromISR(m_uartRXBuffer.data(), size);
// Restart receiving process
if (!startReceiving())
{
// Quick fix in case of failure to start the receiving process
initDevice();
startReceiving();
}
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::stm32

View File

@@ -0,0 +1,140 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "UARTBus.h"
#include "criticalSection.h"
#include <sdi_toolBox/generic/circularBuffer.h>
namespace sdi_uToolBox::stm32
{
//--------------------------------------------------------------
template<size_t UART_RX_BUFFER_SIZE, size_t UART_TX_BUFFER_SIZE, size_t QUEUE_SIZE>
class UARTBusIT : public sdi_uToolBox::stm32::UARTBus<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE>
{
public:
UARTBusIT() = default; // Constructor
~UARTBusIT() override = default; // Destructor
UARTBusIT(const UARTBusIT &other) = delete; // Copy constructor
UARTBusIT(UARTBusIT &&other) noexcept = delete; // Move constructor
UARTBusIT &operator=(const UARTBusIT &other) = delete; // Copy assignment
UARTBusIT &operator=(UARTBusIT &&other) noexcept = delete; // Move assignment
size_t write(const std::span<const uint8_t> buffer) override; // Writes a block of data to the stream
size_t read(const std::span<uint8_t> buffer) override; // Reads a block of data from the stream
bool isDataAvailable() const override; // Checks if the stream has data available for reading
bool isTxReady(); // Returns true if the TX stream is ready and available
void on_transmitComplete_fromISR(); // Interrupt-based transmission is over
protected:
volatile bool m_txBufferIsEmpty = true;
sdi_toolBox::generic::CircularBuffer<uint8_t, QUEUE_SIZE> m_rxBuffer;
private:
void initDevice() override; // Device initialization
bool startReceiving() override; // Start specific receiving method (IT, DMA, ...)
void receiveData_fromISR(const uint8_t *buffer, const size_t size) override; // Receive data from interuption
};
//--------------------------------------------------------------
//--------------------------------------------------------------
/* Writes a block of data to the stream */
template<size_t UART_RX_BUFFER_SIZE, size_t UART_TX_BUFFER_SIZE, size_t QUEUE_SIZE>
inline size_t UARTBusIT<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE, QUEUE_SIZE>::write(const std::span<const uint8_t> buffer)
{
if (!isTxReady())
return 0;
if (UARTBus<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE>::m_uartHdl->gState != HAL_UART_STATE_READY)
return 0;
const auto len = std::min(buffer.size(), UARTBus<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE>::m_uartTXBuffer.size());
std::memcpy(UARTBus<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE>::m_uartTXBuffer.data(),
buffer.data(),
len);
if (HAL_OK != HAL_UART_Transmit_IT(UARTBus<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE>::m_uartHdl,
UARTBus<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE>::m_uartRXBuffer.data(),
UARTBus<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE>::m_uartRXBuffer.size()))
return 0;
m_txBufferIsEmpty = false;
return len;
}
//--------------------------------------------------------------
/* Reads a block of data from the stream */
template<size_t UART_RX_BUFFER_SIZE, size_t UART_TX_BUFFER_SIZE, size_t QUEUE_SIZE>
inline size_t UARTBusIT<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE, QUEUE_SIZE>::read(const std::span<uint8_t> buffer)
{
CriticalSection criticalSection;
for (size_t i = 0; i < buffer.size(); i++)
{
const auto data = m_rxBuffer.pop();
if (!data)
return i;
buffer[i] = *data;
}
return buffer.size();
}
//--------------------------------------------------------------
/* Checks if the stream has data available for reading */
template<size_t UART_RX_BUFFER_SIZE, size_t UART_TX_BUFFER_SIZE, size_t QUEUE_SIZE>
inline bool UARTBusIT<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE, QUEUE_SIZE>::isDataAvailable() const
{
CriticalSection criticalSection;
return !m_rxBuffer.isEmpty();
}
//--------------------------------------------------------------
/* Returns true if the TX stream is ready and available */
template<size_t UART_RX_BUFFER_SIZE, size_t UART_TX_BUFFER_SIZE, size_t QUEUE_SIZE>
inline bool UARTBusIT<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE, QUEUE_SIZE>::isTxReady()
{
return m_txBufferIsEmpty;
}
//--------------------------------------------------------------
/* Interrupt-based transmission is over */
template<size_t UART_RX_BUFFER_SIZE, size_t UART_TX_BUFFER_SIZE, size_t QUEUE_SIZE>
inline void UARTBusIT<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE, QUEUE_SIZE>::on_transmitComplete_fromISR()
{
m_txBufferIsEmpty = true;
}
//--------------------------------------------------------------
/* Start specific receiving method (IT, DMA, ...) */
template<size_t UART_RX_BUFFER_SIZE, size_t UART_TX_BUFFER_SIZE, size_t QUEUE_SIZE>
inline bool UARTBusIT<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE, QUEUE_SIZE>::startReceiving()
{
return (HAL_OK != HAL_UARTEx_ReceiveToIdle_IT(UARTBus<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE>::m_uartHdl,
UARTBus<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE>::m_uartRXBuffer.data(),
UARTBus<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE>::m_uartRXBuffer.size()));
}
//--------------------------------------------------------------
/* Device initialization */
template<size_t UART_RX_BUFFER_SIZE, size_t UART_TX_BUFFER_SIZE, size_t QUEUE_SIZE>
void UARTBusIT<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE, QUEUE_SIZE>::initDevice()
{
// TODO
}
//--------------------------------------------------------------
/* Receive data from interuption */
template<size_t UART_RX_BUFFER_SIZE, size_t UART_TX_BUFFER_SIZE, size_t QUEUE_SIZE>
inline void UARTBusIT<UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE, QUEUE_SIZE>::receiveData_fromISR(const uint8_t *buffer, const size_t size)
{
// Operations performed within an interrupt routine are considered atomic
for (size_t i = 0; i < size; i++)
m_rxBuffer.push(buffer[i]);
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::stm32

View File

@@ -0,0 +1,89 @@
//{{copyright}}
//{{version}}
//{{license}}
#pragma once
#include "../HIDBus.h"
#include "../../../dateTime/FreeRTOS/timer.h"
#include <sdi_uToolBox/generic/FreeRTOS/mutex.h>
#include <sdi_uToolBox/generic/FreeRTOS/semaphore.h>
namespace sdi_uToolBox::stm32::comm::FreeRTOS
{
//--------------------------------------------------------------
class HIDBus : public comm::HIDBus
{
public:
using Mutex = generic::FreeRTOS::Mutex;
using BinarySemaphore = generic::FreeRTOS::BinarySemaphore;
public:
HIDBus(); // Default constructor
virtual ~HIDBus() = default; // Default destructor
HIDBus(const HIDBus &) = delete; // Copy constructor
HIDBus(HIDBus &&) = delete; // Move constructor
HIDBus &operator=(const HIDBus &) = delete; // Copy assignment operator
HIDBus &operator=(HIDBus &&) = delete; // Move assignment operator
ReturnStatus open() override; // Open UART bus
ReturnStatus close() override; // Close UART bus
ReturnType write(WriteBuf buf, Timeout timeout) const override; // Write data to UART device
ReturnType read(ReadBuf buf, Timeout timeout) const override; // Read data from UART device
void rxCompleteCallback(std::span<const uint8_t> buf) override;
protected:
mutable Mutex m_mtx;
mutable BinarySemaphore m_semaphore{false};
dateTime::FreeRTOS::Timer m_timer;
};
//--------------------------------------------------------------
inline HIDBus::HIDBus()
{
m_genericTimer = &m_timer;
}
//--------------------------------------------------------------
/* Open UART bus */
inline ReturnStatus HIDBus::open()
{
std::scoped_lock lock(m_mtx);
return comm::HIDBus::open();
}
//--------------------------------------------------------------
/* Close UART bus */
inline ReturnStatus HIDBus::close()
{
std::scoped_lock lock(m_mtx);
return comm::HIDBus::close();
}
//--------------------------------------------------------------
/* Write data to UART device */
inline HIDBus::ReturnType HIDBus::write(const WriteBuf buf, const Timeout timeout) const
{
std::scoped_lock lock(m_mtx);
return comm::HIDBus::write(buf, timeout);
}
//--------------------------------------------------------------
/* Read data from UART device */
inline HIDBus::ReturnType HIDBus::read(const ReadBuf buf, const Timeout timeout) const
{
if (!m_semaphore.take(timeout))
return std::unexpected(ReturnStatus::Timeout);
std::scoped_lock lock(m_mtx);
return comm::HIDBus::read(buf, std::chrono::milliseconds(0));
}
//--------------------------------------------------------------
inline void HIDBus::rxCompleteCallback(std::span<const uint8_t> buf)
{
comm::HIDBus::rxCompleteCallback(buf);
(void)m_semaphore.giveFromISR();
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::stm32::comm

View File

@@ -0,0 +1,91 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "../I2CBus.h"
#include <sdi_uToolBox/generic/FreeRTOS/mutex.h>
namespace sdi_uToolBox::stm32::comm::FreeRTOS
{
//--------------------------------------------------------------
class I2CBus : public stm32::comm::I2CBus
{
public:
using RecursiveMutex = generic::FreeRTOS::RecursiveMutex;
public:
I2CBus() = default; // Default constructor
virtual ~I2CBus() override = default; // Default destructor
I2CBus(const I2CBus &) = delete; // Copy constructor
I2CBus(I2CBus &&) = delete; // Move constructor
I2CBus &operator=(const I2CBus &) = delete; // Copy assignment operator
I2CBus &operator=(I2CBus &&) = delete; // Move assignment operator
ReturnStatus open() override; // Open I2C bus
ReturnStatus close() override; // Close I2C bus
std::unique_lock<RecursiveMutex> getLock() const; // Get unique lock for the bus
ReturnType write(uint8_t address, WriteBuf buf, Timeout timeout) const override; // Write data to I2C device
ReturnType read(uint8_t address, ReadBuf buf, Timeout timeout) const override; // Read data from I2C device
ReturnStatus isDeviceReady(uint8_t address) const override; // Check if I2C device is ready
protected:
mutable RecursiveMutex m_mtx; // Mutex for thread safety
};
//--------------------------------------------------------------
//--------------------------------------------------------------
/* Open I2C bus */
inline ReturnStatus I2CBus::open()
{
std::scoped_lock lock(m_mtx);
return stm32::comm::I2CBus::open();
}
//--------------------------------------------------------------
/* Close I2C bus */
inline ReturnStatus I2CBus::close()
{
std::scoped_lock lock(m_mtx);
return stm32::comm::I2CBus::close();
}
//--------------------------------------------------------------
/* Get unique lock for the bus */
inline std::unique_lock<I2CBus::RecursiveMutex> I2CBus::getLock() const
{
return std::unique_lock(m_mtx);
}
//--------------------------------------------------------------
/* Write data to I2C device */
inline I2CBus::ReturnType I2CBus::write(const uint8_t address, const WriteBuf buf, const Timeout timeout) const
{
std::scoped_lock lock(m_mtx);
return stm32::comm::I2CBus::write(address, buf, timeout);
}
//--------------------------------------------------------------
/* Read data from I2C device */
inline I2CBus::ReturnType I2CBus::read(const uint8_t address, const ReadBuf buf, const Timeout timeout) const
{
std::scoped_lock lock(m_mtx);
return stm32::comm::I2CBus::read(address, buf, timeout);
}
//--------------------------------------------------------------
/* Check if I2C device is ready */
inline ReturnStatus I2CBus::isDeviceReady(const uint8_t address) const
{
std::scoped_lock lock(m_mtx);
return stm32::comm::I2CBus::isDeviceReady(address);
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::stm32::comm::FreeRTOS

View File

@@ -0,0 +1,73 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "../UARTBus.h"
#include <sdi_uToolBox/generic/FreeRTOS/mutex.h>
namespace sdi_uToolBox::stm32::comm::FreeRTOS
{
//--------------------------------------------------------------
class UARTBus : public stm32::comm::UARTBus
{
public:
using Mutex = generic::FreeRTOS::Mutex;
public:
UARTBus() = default; // Default constructor
virtual ~UARTBus() override = default; // Default destructor
UARTBus(const UARTBus &) = delete; // Copy constructor
UARTBus(UARTBus &&) = delete; // Move constructor
UARTBus &operator=(const UARTBus &) = delete; // Copy assignment operator
UARTBus &operator=(UARTBus &&) = delete; // Move assignment operator
ReturnStatus open() override; // Open UART bus
ReturnStatus close() override; // Close UART bus
ReturnType write(WriteBuf buf, Timeout timeout) const override; // Write data to UART device
ReturnType read(ReadBuf buf, Timeout timeout) const override; // Read data from UART device
protected:
mutable Mutex m_mtx; // Mutex for thread safety
};
//--------------------------------------------------------------
/* Open UART bus */
inline ReturnStatus UARTBus::open()
{
std::scoped_lock lock(m_mtx);
return stm32::comm::UARTBus::open();
}
//--------------------------------------------------------------
/* Close UART bus */
inline ReturnStatus UARTBus::close()
{
std::scoped_lock lock(m_mtx);
return stm32::comm::UARTBus::close();
}
//--------------------------------------------------------------
/* Write data to UART device */
inline UARTBus::ReturnType UARTBus::write(const WriteBuf buf, const Timeout timeout) const
{
std::scoped_lock lock(m_mtx);
return stm32::comm::UARTBus::write(buf, timeout);
}
//--------------------------------------------------------------
/* Read data from UART device */
inline UARTBus::ReturnType UARTBus::read(const ReadBuf buf, const Timeout timeout) const
{
std::scoped_lock lock(m_mtx);
return stm32::comm::UARTBus::read(buf, timeout);
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::stm32::comm::FreeRTOS

View File

@@ -0,0 +1,283 @@
//{{copyright}}
//{{version}}
//{{license}}
#pragma once
#include "../UARTBus.h"
#include <atomic>
#include <sdi_uToolBox/generic/FreeRTOS/mutex.h>
#include <sdi_uToolBox/generic/FreeRTOS/semaphore.h>
namespace sdi_uToolBox::stm32::comm::FreeRTOS
{
//--------------------------------------------------------------
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
class UARTBusDMA : public stm32::comm::UARTBus
, public UARTBusCallback
{
public:
using Mutex = generic::FreeRTOS::Mutex;
using BinarySemaphore = generic::FreeRTOS::BinarySemaphore;
public:
UARTBusDMA() = default; // Default constructor
virtual ~UARTBusDMA(); // Default destructor
UARTBusDMA(const UARTBusDMA &) = delete; // Copy constructor
UARTBusDMA(UARTBusDMA &&) = delete; // Move constructor
UARTBusDMA &operator=(const UARTBusDMA &) = delete; // Copy assignment operator
UARTBusDMA &operator=(UARTBusDMA &&) = delete; // Move assignment operator
ReturnStatus configure(UART_HandleTypeDef *handle) override; // Configure UART bus with HAL handle
ReturnStatus open() override; // Open UART bus
ReturnStatus close() override; // Close UART bus
ReturnType write(WriteBuf buf, Timeout timeout) const override; // Write data to UART device
ReturnType read(ReadBuf buf, Timeout timeout) const override; // Read data from UART device
ReturnType readUntilIdle(ReadBuf buf, Timeout timeout) const override; // Read data until IDLE event
// Callback to be called from ISR when TX, RX is complete or error occurs
void txCompleteCallback() const override; // TX complete callback
void rxCompleteCallback() const override; // RX complete callback
void rxEventCallback(uint16_t size) const override; // IDLE line detected callback
void errorCallback() const override; // Error callback
protected:
mutable Mutex m_txMtx; // Mutex for TX thread safety
mutable Mutex m_rxMtx; // Mutex for RX thread safety
mutable BinarySemaphore m_txSemaphore{ false }; // Semaphore for TX completion
mutable BinarySemaphore m_rxSemaphore{ false }; // Semaphore for RX completion
alignas(32) mutable std::array<uint8_t, TX_BUFFER_SIZE> m_txBuffer; // Transmit buffer aligned for DMA
alignas(32) mutable std::array<uint8_t, RX_BUFFER_SIZE> m_rxBuffer; // Receive buffer aligned for DMA
mutable std::atomic<size_t> m_lastTxSize{ 0 };
mutable std::atomic<size_t> m_lastRxSize{ 0 };
mutable std::atomic<bool> m_txError{ false };
mutable std::atomic<bool> m_rxError{ false };
};
//--------------------------------------------------------------
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline UARTBusDMA<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::~UARTBusDMA()
{
UARTBusCallbackRegistry::unregisterInstance(this);
}
//--------------------------------------------------------------
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline ReturnStatus UARTBusDMA<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::configure(UART_HandleTypeDef *handle)
{
const auto ret = UARTBus::configure(handle);
if (ret != ReturnStatus::Ok)
return ret;
UARTBusCallbackRegistry::registerInstance(handle, this);
return ReturnStatus::Ok;
}
//--------------------------------------------------------------
/* Open UART bus */
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline ReturnStatus UARTBusDMA<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::open()
{
std::scoped_lock lock(m_txMtx, m_rxMtx);
return UARTBus::open();
}
//--------------------------------------------------------------
/* Close UART bus */
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline ReturnStatus UARTBusDMA<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::close()
{
std::scoped_lock lock(m_txMtx, m_rxMtx);
__HAL_UART_DISABLE_IT(m_uartHandle, UART_IT_IDLE); // Disable IDLE interrupt
HAL_UART_DMAStop(m_uartHandle); // Abort ongoing DMA operations
return UARTBus::close();
}
//--------------------------------------------------------------
/* Write data to UART device */
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline UARTBus::ReturnType UARTBusDMA<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::write(const WriteBuf buf, const Timeout timeout) const
{
std::scoped_lock lock(m_txMtx);
if (!m_uartHandle)
return std::unexpected(ReturnStatus::InvalidHandle);
if (buf.size() > TX_BUFFER_SIZE)
return std::unexpected(ReturnStatus::Error);
// Copy data to internal buffer
std::copy_n(buf.begin(), buf.size(), m_txBuffer.begin());
// Reset flags
m_txError = false;
m_lastTxSize = 0;
// Start transmission with DMA
const auto ret = HAL_UART_Transmit_DMA(m_uartHandle,
m_txBuffer.data(),
buf.size());
if (ret != HAL_OK)
{
if (ret == HAL_BUSY)
return std::unexpected(ReturnStatus::Busy);
return std::unexpected(ReturnStatus::Error);
}
// Wait for transmission to complete. The timeout is handled by the semaphore
// The task will be unblocked when the semaphore is given in the DMA ISR
if (!m_txSemaphore.take(timeout))
{
HAL_UART_AbortTransmit(m_uartHandle);
return std::unexpected(ReturnStatus::Timeout);
}
if (m_txError)
return std::unexpected(ReturnStatus::Error);
return m_lastTxSize; // Return number of bytes transmitted
}
//--------------------------------------------------------------
/* Read data from UART device */
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline UARTBus::ReturnType UARTBusDMA<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::read(const ReadBuf buf, const Timeout timeout) const
{
std::scoped_lock lock(m_rxMtx);
if (!m_uartHandle)
return std::unexpected(ReturnStatus::InvalidHandle);
if (buf.size() > RX_BUFFER_SIZE)
return std::unexpected(ReturnStatus::Error);
// Reset flags
m_rxError = false;
m_lastRxSize = 0;
// Start reception with DMA
const auto ret = HAL_UART_Receive_DMA(m_uartHandle,
m_rxBuffer.data(),
buf.size());
if (ret != HAL_OK)
{
if (ret == HAL_BUSY)
return std::unexpected(ReturnStatus::Busy);
return std::unexpected(ReturnStatus::Error);
}
// Wait for IDLE event or buffer full. The timeout is handled by the semaphore
// The task will be unblocked when the semaphore is given in the DMA ISR
if (!m_rxSemaphore.take(timeout))
{
HAL_UART_AbortReceive(m_uartHandle);
return std::unexpected(ReturnStatus::Timeout);
}
if (m_rxError)
return std::unexpected(ReturnStatus::Error);
// Copy received data to user buffer
std::copy_n(m_rxBuffer.begin(), m_lastRxSize.load(), buf.begin());
return m_lastRxSize; // Return number of bytes received
}
//--------------------------------------------------------------
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline UARTBus::ReturnType UARTBusDMA<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::readUntilIdle(ReadBuf buf, Timeout timeout) const
{
std::scoped_lock lock(m_rxMtx);
if (!m_uartHandle)
return std::unexpected(ReturnStatus::InvalidHandle);
if (buf.size() > RX_BUFFER_SIZE)
return std::unexpected(ReturnStatus::Error);
// Reset flags
m_rxError = false;
m_lastRxSize = 0;
// Start reception with DMA (buffer size is the maximum expected)
if (m_uartHandle->RxState != HAL_UART_STATE_READY)
HAL_UART_AbortReceive(m_uartHandle);
const auto ret = HAL_UARTEx_ReceiveToIdle_DMA(m_uartHandle,
m_rxBuffer.data(),
buf.size());
if (ret != HAL_OK)
{
if (ret == HAL_BUSY)
return std::unexpected(ReturnStatus::Busy);
return std::unexpected(ReturnStatus::Error);
}
// Wait for reception to complete or idled. The timeout is handled by the semaphore
// The task will be unblocked when the semaphore is given in the ISR
if (!m_rxSemaphore.take(timeout))
{
HAL_UART_AbortReceive(m_uartHandle);
return std::unexpected(ReturnStatus::Timeout);
}
if (m_rxError)
return std::unexpected(ReturnStatus::Error);
// Copy received data to user buffer
std::copy_n(m_rxBuffer.begin(), m_lastRxSize.load(), buf.begin());
return m_lastRxSize;
}
//--------------------------------------------------------------
/* TX complete callback */
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline void UARTBusDMA<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::txCompleteCallback() const
{
m_lastTxSize = m_uartHandle->TxXferSize - m_uartHandle->TxXferCount;
(void)m_txSemaphore.giveFromISR();
}
//--------------------------------------------------------------
/* RX complete callback */
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline void UARTBusDMA<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::rxCompleteCallback() const
{
m_lastRxSize = m_uartHandle->RxXferSize - m_uartHandle->RxXferCount;
(void)m_rxSemaphore.giveFromISR();
}
//--------------------------------------------------------------
/* IDLE line detected callback */
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline void UARTBusDMA<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::rxEventCallback(const uint16_t size) const
{
if (m_uartHandle->RxState == HAL_UART_STATE_READY)
{
// Stop DMA transfer
HAL_UART_AbortReceive(m_uartHandle);
// Calculate received bytes: total size - remaining count
// m_lastRxSize = m_uartHandle->RxXferSize - __HAL_DMA_GET_COUNTER(m_uartHandle->hdmarx);
m_lastRxSize = size;
(void)m_rxSemaphore.giveFromISR();
}
}
//--------------------------------------------------------------
/* Error callback */
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline void UARTBusDMA<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::errorCallback() const
{
if (m_uartHandle->gState == HAL_UART_STATE_BUSY_TX)
{
m_txError = true;
(void)m_txSemaphore.giveFromISR();
}
if (m_uartHandle->RxState == HAL_UART_STATE_BUSY_RX)
{
m_rxError = true;
(void)m_rxSemaphore.giveFromISR();
}
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::stm32::comm::FreeRTOS

View File

@@ -0,0 +1,280 @@
//{{copyright}}
//{{version}}
//{{license}}
#pragma once
#include "../UARTBus.h"
#include <atomic>
#include <sdi_uToolBox/generic/FreeRTOS/mutex.h>
#include <sdi_uToolBox/generic/FreeRTOS/semaphore.h>
namespace sdi_uToolBox::stm32::comm::FreeRTOS
{
//--------------------------------------------------------------
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
class UARTBusIT : public stm32::comm::UARTBus
, public UARTBusCallback
{
public:
using Mutex = generic::FreeRTOS::Mutex;
using BinarySemaphore = generic::FreeRTOS::BinarySemaphore;
public:
UARTBusIT() = default; // Default constructor
virtual ~UARTBusIT(); // Default destructor
UARTBusIT(const UARTBusIT &) = delete; // Copy constructor
UARTBusIT(UARTBusIT &&) = delete; // Move constructor
UARTBusIT &operator=(const UARTBusIT &) = delete; // Copy assignment operator
UARTBusIT &operator=(UARTBusIT &&) = delete; // Move assignment operator
ReturnStatus configure(UART_HandleTypeDef *handle) override; // Configure UART bus with HAL handle
ReturnStatus open() override; // Open UART bus
ReturnStatus close() override; // Close UART bus
ReturnType write(WriteBuf buf, Timeout timeout) const override; // Write data to UART device
ReturnType read(ReadBuf buf, Timeout timeout) const override; // Read data from UART device
ReturnType readUntilIdle(ReadBuf buf, Timeout timeout) const; // Read data until IDLE event
// Callback to be called from ISR when TX, RX is complete or error occurs
void txCompleteCallback() const override; // TX complete callback
void rxCompleteCallback() const override; // RX complete callback
void rxEventCallback(uint16_t size) const override; // IDLE line detected callback
void errorCallback() const override; // Error callback
protected:
mutable Mutex m_txMtx; // Mutex for TX thread safety
mutable Mutex m_rxMtx; // Mutex for RX thread safety
mutable BinarySemaphore m_txSemaphore{ false }; // Semaphore for TX completion
mutable BinarySemaphore m_rxSemaphore{ false }; // Semaphore for RX completion
mutable std::array<uint8_t, TX_BUFFER_SIZE> m_txBuffer;
mutable std::array<uint8_t, RX_BUFFER_SIZE> m_rxBuffer;
mutable std::atomic<size_t> m_lastTxSize{ 0 };
mutable std::atomic<size_t> m_lastRxSize{ 0 };
mutable std::atomic<bool> m_txError{ false };
mutable std::atomic<bool> m_rxError{ false };
};
//--------------------------------------------------------------
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline UARTBusIT<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::~UARTBusIT()
{
UARTBusCallbackRegistry::unregisterInstance(this);
}
//--------------------------------------------------------------
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline ReturnStatus UARTBusIT<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::configure(UART_HandleTypeDef *handle)
{
const auto ret = UARTBus::configure(handle);
if (ret != ReturnStatus::Ok)
return ret;
UARTBusCallbackRegistry::registerInstance(handle, this);
return ReturnStatus::Ok;
}
//--------------------------------------------------------------
/* Open UART bus */
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline ReturnStatus UARTBusIT<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::open()
{
std::scoped_lock lock(m_txMtx, m_rxMtx);
return UARTBus::open();
}
//--------------------------------------------------------------
/* Close UART bus */
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline ReturnStatus UARTBusIT<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::close()
{
std::scoped_lock lock(m_txMtx, m_rxMtx);
__HAL_UART_DISABLE_IT(m_uartHandle, UART_IT_IDLE); // Disable IDLE interrupt
return UARTBus::close();
}
//--------------------------------------------------------------
/* Write data to UART device */
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline UARTBus::ReturnType UARTBusIT<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::write(const WriteBuf buf, const Timeout timeout) const
{
std::scoped_lock lock(m_txMtx);
if (!m_uartHandle)
return std::unexpected(ReturnStatus::InvalidHandle);
if (buf.size() > TX_BUFFER_SIZE)
return std::unexpected(ReturnStatus::Error);
// Copy data to internal buffer
std::copy_n(buf.begin(), buf.size(), m_txBuffer.begin());
// Reset flags
m_txError = false;
m_lastTxSize = 0;
// Start transmission with interrupt
const auto ret = HAL_UART_Transmit_IT(m_uartHandle,
m_txBuffer.data(),
buf.size());
if (ret != HAL_OK)
{
if (ret == HAL_BUSY)
return std::unexpected(ReturnStatus::Busy);
return std::unexpected(ReturnStatus::Error);
}
// Wait for transmission to complete. The timeout is handled by the semaphore
// The task will be unblocked when the semaphore is given in the ISR
if (!m_txSemaphore.take(timeout))
{
HAL_UART_AbortTransmit(m_uartHandle);
return std::unexpected(ReturnStatus::Timeout);
}
if (m_txError)
return std::unexpected(ReturnStatus::Error);
return m_lastTxSize; // Return number of bytes transmitted
}
//--------------------------------------------------------------
/* Read data from UART device */
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline UARTBus::ReturnType UARTBusIT<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::read(const ReadBuf buf, const Timeout timeout) const
{
std::scoped_lock lock(m_rxMtx);
if (!m_uartHandle)
return std::unexpected(ReturnStatus::InvalidHandle);
if (buf.size() > RX_BUFFER_SIZE)
return std::unexpected(ReturnStatus::Error);
// Reset flags
m_rxError = false;
m_lastRxSize = 0;
// Start reception with interrupt
const auto ret = HAL_UART_Receive_IT(m_uartHandle,
m_rxBuffer.data(),
buf.size());
if (ret != HAL_OK)
{
if (ret == HAL_BUSY)
return std::unexpected(ReturnStatus::Busy);
return std::unexpected(ReturnStatus::Error);
}
// Wait for reception to complete. The timeout is handled by the semaphore
// The task will be unblocked when the semaphore is given in the ISR
if (!m_rxSemaphore.take(timeout))
{
HAL_UART_AbortReceive(m_uartHandle);
return std::unexpected(ReturnStatus::Timeout);
}
if (m_rxError)
return std::unexpected(ReturnStatus::Error);
// Copy received data to user buffer
std::copy_n(m_rxBuffer.begin(), m_lastRxSize.load(), buf.begin());
return m_lastRxSize; // Return number of bytes received
}
//--------------------------------------------------------------
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline UARTBus::ReturnType UARTBusIT<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::readUntilIdle(ReadBuf buf, Timeout timeout) const
{
std::scoped_lock lock(m_rxMtx);
if (!m_uartHandle)
return std::unexpected(ReturnStatus::InvalidHandle);
if (buf.size() > RX_BUFFER_SIZE)
return std::unexpected(ReturnStatus::Error);
// Reset flags
m_rxError = false;
m_lastRxSize = 0;
// Start reception with interrupt
const auto ret = HAL_UART_ReceiveToIdle_IT(m_uartHandle,
m_rxBuffer.data(),
buf.size());
if (ret != HAL_OK)
{
if (ret == HAL_BUSY)
return std::unexpected(ReturnStatus::Busy);
return std::unexpected(ReturnStatus::Error);
}
// Wait for reception to complete or idled. The timeout is handled by the semaphore
// The task will be unblocked when the semaphore is given in the ISR
if (!m_rxSemaphore.take(timeout))
{
HAL_UART_AbortReceive(m_uartHandle);
return std::unexpected(ReturnStatus::Timeout);
}
if (m_rxError)
return std::unexpected(ReturnStatus::Error);
// Copy received data to user buffer
std::copy_n(m_rxBuffer.begin(), m_lastRxSize.load(), buf.begin());
return m_lastRxSize; // Return number of bytes received
}
//--------------------------------------------------------------
/* TX complete callback */
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline void UARTBusIT<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::txCompleteCallback() const
{
m_lastTxSize = m_uartHandle->TxXferSize - m_uartHandle->TxXferCount;
(void)m_txSemaphore.giveFromISR();
}
//--------------------------------------------------------------
/* RX complete callback */
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline void UARTBusIT<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::rxCompleteCallback() const
{
m_lastRxSize = m_uartHandle->RxXferSize - m_uartHandle->RxXferCount;
(void)m_rxSemaphore.giveFromISR();
}
//--------------------------------------------------------------
/* IDLE line detected callback */
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline void UARTBusIT<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::rxEventCallback(const uint16_t size) const
{
if (m_uartHandle->RxState == HAL_UART_STATE_BUSY_RX)
{
// Stop IT transfer
HAL_UART_AbortReceive_IT(m_uartHandle);
// Calculate received bytes
//m_lastRxSize = m_uartHandle->RxXferSize - m_uartHandle->RxXferCount;
m_lastRxSize = size;
(void)m_rxSemaphore.giveFromISR();
}
}
//--------------------------------------------------------------
/* Error callback */
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline void UARTBusIT<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::errorCallback() const
{
if (m_uartHandle->gState == HAL_UART_STATE_BUSY_TX)
{
m_txError = true;
(void)m_txSemaphore.giveFromISR();
}
if (m_uartHandle->RxState == HAL_UART_STATE_BUSY_RX)
{
m_rxError = true;
(void)m_rxSemaphore.giveFromISR();
}
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::stm32::comm::FreeRTOS

View File

@@ -0,0 +1,131 @@
//{{copyright}}
//{{version}}
//{{license}}
#pragma once
#include "../../comm/SerialBus.h"
#include "../criticalSection.h"
#include "../../dateTime/timer.h"
#include <STM32Headers.h>
#include <chrono>
#include <expected>
#include <span>
namespace sdi_uToolBox::stm32::comm
{
//--------------------------------------------------------------
class HIDBus : public sdi_uToolBox::comm::SerialBus
{
public:
using ReadBuf = std::span<uint8_t>;
using WriteBuf = std::span<const uint8_t>;
using Timeout = std::chrono::milliseconds;
using ReturnType = std::expected<size_t, ReturnStatus>;
public:
HIDBus(); // Default constructor
virtual ~HIDBus() = default; // Default destructor
HIDBus(const HIDBus &) = delete; // Copy constructor
HIDBus(HIDBus &&) = delete; // Move constructor
HIDBus &operator=(const HIDBus &) = delete; // Copy assignment operator
HIDBus &operator=(HIDBus &&) = delete; // Move assignment operator
virtual ReturnStatus configure(USBD_HandleTypeDef *handle); // Configure UART bus with HAL handle
ReturnStatus open() override; // Open UART bus
ReturnStatus close() override; // Close UART bus
ReturnType write(WriteBuf buf, Timeout timeout) const override; // Write data to UART device
ReturnType read(ReadBuf buf, Timeout timeout) const override; // Read data from UART device
virtual void rxCompleteCallback(std::span<const uint8_t> buf);
protected:
USBD_HandleTypeDef *m_hidHandle = nullptr; // HAL UART handle
sdi_uToolBox::dateTime::Timer m_timer;
sdi_toolBox::dateTime::ITimer* m_genericTimer = nullptr;
mutable std::span<const uint8_t> m_rxBuffer;
};
//--------------------------------------------------------------
inline HIDBus::HIDBus()
{
m_genericTimer = &m_timer;
}
//--------------------------------------------------------------
/* Configure UART bus with HAL handle */
inline ReturnStatus HIDBus::configure(USBD_HandleTypeDef *handle)
{
if (!handle)
return ReturnStatus::InvalidHandle;
m_hidHandle = handle;
return ReturnStatus::Ok;
}
//--------------------------------------------------------------
/* Open UART bus */
inline ReturnStatus HIDBus::open()
{
if (!m_hidHandle)
return ReturnStatus::InvalidHandle;
return ReturnStatus::Error;
}
//--------------------------------------------------------------
/* Close UART bus */
inline ReturnStatus HIDBus::close()
{
if (!m_hidHandle)
return ReturnStatus::InvalidHandle;
return ReturnStatus::Error;
}
//--------------------------------------------------------------
/* Write data to UART device */
inline HIDBus::ReturnType HIDBus::write(const WriteBuf buf, const Timeout timeout) const
{
const auto ret = USBD_CUSTOM_HID_SendReport(m_hidHandle,
const_cast<uint8_t *>(buf.data()),
buf.size());
if (ret == USBD_OK)
return buf.size();
if (ret == USBD_BUSY)
return std::unexpected(ReturnStatus::Busy);
return std::unexpected(ReturnStatus::Error);
}
//--------------------------------------------------------------
/* Read data from UART device */
inline HIDBus::ReturnType HIDBus::read(const ReadBuf buf, const Timeout timeout) const
{
m_genericTimer->reset();
while (!m_genericTimer->isElapsed(timeout))
{
CriticalSection criticalSection;
if (m_rxBuffer.empty())
continue;
if (m_rxBuffer.size() > buf.size())
return std::unexpected(ReturnStatus::BufferOverflow);
std::copy_n(m_rxBuffer.begin(), m_rxBuffer.size(), buf.begin());
m_rxBuffer = {};
return m_rxBuffer.size();
}
return std::unexpected(ReturnStatus::Timeout);
}
//--------------------------------------------------------------
inline void HIDBus::rxCompleteCallback(const std::span<const uint8_t> buf)
{
CriticalSection criticalSection;
m_rxBuffer = buf;
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::stm32::comm

View File

@@ -0,0 +1,134 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "../../comm/I2CBus.h"
#include <STM32Headers.h>
#include <chrono>
#include <expected>
#include <span>
namespace sdi_uToolBox::stm32::comm
{
//--------------------------------------------------------------
class I2CBus : public sdi_uToolBox::comm::I2CBus
{
public:
using ReadBuf = std::span<uint8_t>;
using WriteBuf = std::span<const uint8_t>;
using Timeout = std::chrono::milliseconds;
using ReturnType = std::expected<size_t, ReturnStatus>;
public:
I2CBus() = default; // Default constructor
virtual ~I2CBus() = default; // Default destructor
I2CBus(const I2CBus &) = delete; // Copy constructor
I2CBus(I2CBus &&) = delete; // Move constructor
I2CBus &operator=(const I2CBus &) = delete; // Copy assignment operator
I2CBus &operator=(I2CBus &&) = delete; // Move assignment operator
ReturnStatus configure(I2C_HandleTypeDef *handle); // Configure I2C bus with HAL handle
ReturnStatus open() override; // Open I2C bus
ReturnStatus close() override; // Close I2C bus
ReturnType write(uint8_t address, WriteBuf buf, Timeout timeout) const override; // Write data to I2C device
ReturnType read(uint8_t address, ReadBuf buf, Timeout timeout) const override; // Read data from I2C device
ReturnStatus isDeviceReady(uint8_t address) const override; // Check if I2C device is ready
protected:
I2C_HandleTypeDef *m_i2cHandle = nullptr; // HAL I2C handle
};
//--------------------------------------------------------------
//--------------------------------------------------------------
/* Configure I2C bus with HAL handle */
inline ReturnStatus I2CBus::configure(I2C_HandleTypeDef *handle)
{
if (!handle)
return ReturnStatus::InvalidHandle;
m_i2cHandle = handle;
return ReturnStatus::Ok;
}
//--------------------------------------------------------------
/* Open I2C bus */
inline ReturnStatus I2CBus::open()
{
return ReturnStatus::Error;
}
//--------------------------------------------------------------
/* Close I2C bus */
inline ReturnStatus I2CBus::close()
{
return ReturnStatus::Error;
}
//--------------------------------------------------------------
/* Write data to I2C device */
inline I2CBus::ReturnType I2CBus::write(const uint8_t address, const WriteBuf buf, const Timeout timeout) const
{
const auto ret = HAL_I2C_Master_Transmit(m_i2cHandle,
address << 1,
const_cast<uint8_t *>(buf.data()),
buf.size(),
timeout.count());
if (ret == HAL_OK)
return buf.size();
if (ret == HAL_BUSY)
return std::unexpected(ReturnStatus::Busy);
if (ret == HAL_ERROR && m_i2cHandle->ErrorCode == HAL_I2C_ERROR_TIMEOUT)
return std::unexpected(ReturnStatus::Timeout);
return std::unexpected(ReturnStatus::Error);
}
//--------------------------------------------------------------
/* Read data from I2C device */
inline I2CBus::ReturnType I2CBus::read(const uint8_t address, const ReadBuf buf, const Timeout timeout) const
{
const auto ret = HAL_I2C_Master_Receive(m_i2cHandle,
address << 1,
buf.data(),
buf.size(),
timeout.count());
if (ret == HAL_OK)
return buf.size();
if (ret == HAL_BUSY)
return std::unexpected(ReturnStatus::Busy);
if (ret == HAL_ERROR && m_i2cHandle->ErrorCode == HAL_I2C_ERROR_TIMEOUT)
return std::unexpected(ReturnStatus::Timeout);
return std::unexpected(ReturnStatus::Error);
}
//--------------------------------------------------------------
/* Check if I2C device is ready */
inline ReturnStatus I2CBus::isDeviceReady(const uint8_t address) const
{
const auto ret = HAL_I2C_IsDeviceReady(m_i2cHandle,
address << 1,
5,
100);
if (ret == HAL_OK)
return ReturnStatus::Ok;
if (ret == HAL_BUSY)
return ReturnStatus::Busy;
if (ret == HAL_ERROR && m_i2cHandle->ErrorCode == HAL_I2C_ERROR_TIMEOUT)
return ReturnStatus::Timeout;
return ReturnStatus::Error;
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::stm32::comm

View File

@@ -0,0 +1,201 @@
//{{copyright}}
//{{version}}
//{{license}}
#pragma once
#include "../../comm/SerialBus.h"
#include <STM32Headers.h>
#include <chrono>
#include <expected>
#include <span>
namespace sdi_uToolBox::stm32::comm
{
//--------------------------------------------------------------
class UARTBus : public sdi_uToolBox::comm::SerialBus
{
public:
using ReadBuf = std::span<uint8_t>;
using WriteBuf = std::span<const uint8_t>;
using Timeout = std::chrono::milliseconds;
using ReturnType = std::expected<size_t, ReturnStatus>;
public:
UARTBus() = default; // Default constructor
virtual ~UARTBus() = default; // Default destructor
UARTBus(const UARTBus &) = delete; // Copy constructor
UARTBus(UARTBus &&) = delete; // Move constructor
UARTBus &operator=(const UARTBus &) = delete; // Copy assignment operator
UARTBus &operator=(UARTBus &&) = delete; // Move assignment operator
virtual ReturnStatus configure(UART_HandleTypeDef *handle); // Configure UART bus with HAL handle
ReturnStatus open() override; // Open UART bus
ReturnStatus close() override; // Close UART bus
ReturnType write(WriteBuf buf, Timeout timeout) const override; // Write data to UART device
ReturnType read(ReadBuf buf, Timeout timeout) const override; // Read data from UART device
protected:
UART_HandleTypeDef *m_uartHandle = nullptr; // HAL UART handle
};
//--------------------------------------------------------------
/* Configure UART bus with HAL handle */
inline ReturnStatus UARTBus::configure(UART_HandleTypeDef *handle)
{
if (!handle)
return ReturnStatus::InvalidHandle;
m_uartHandle = handle;
return ReturnStatus::Ok;
}
//--------------------------------------------------------------
/* Open UART bus */
inline ReturnStatus UARTBus::open()
{
if (!m_uartHandle)
return ReturnStatus::InvalidHandle;
return ReturnStatus::Error;
}
//--------------------------------------------------------------
/* Close UART bus */
inline ReturnStatus UARTBus::close()
{
if (!m_uartHandle)
return ReturnStatus::InvalidHandle;
// Abort ongoing operations
HAL_UART_AbortTransmit(m_uartHandle);
HAL_UART_AbortReceive(m_uartHandle);
return ReturnStatus::Error;
}
//--------------------------------------------------------------
/* Write data to UART device */
inline UARTBus::ReturnType UARTBus::write(const WriteBuf buf, const Timeout timeout) const
{
const auto ret = HAL_UART_Transmit(m_uartHandle,
const_cast<uint8_t *>(buf.data()),
buf.size(),
timeout.count());
if (ret == HAL_OK)
return buf.size();
if (ret == HAL_BUSY)
return std::unexpected(ReturnStatus::Busy);
if (ret == HAL_TIMEOUT)
return std::unexpected(ReturnStatus::Timeout);
return std::unexpected(ReturnStatus::Error);
}
//--------------------------------------------------------------
/* Read data from UART device */
inline UARTBus::ReturnType UARTBus::read(const ReadBuf buf, const Timeout timeout) const
{
const auto ret = HAL_UART_Receive(m_uartHandle,
buf.data(),
buf.size(),
timeout.count());
if (ret == HAL_OK)
return buf.size();
if (ret == HAL_BUSY)
return std::unexpected(ReturnStatus::Busy);
if (ret == HAL_TIMEOUT)
return std::unexpected(ReturnStatus::Timeout);
return std::unexpected(ReturnStatus::Error);
}
//--------------------------------------------------------------
/* --- */
//--------------------------------------------------------------
class UARTBusCallback
{
friend class UARTBusCallbackRegistry;
public:
UARTBusCallback() = default; // Default constructor
virtual ~UARTBusCallback() = default; // Default destructor
UARTBusCallback(const UARTBusCallback &) = default; // Copy constructor
UARTBusCallback &operator=(const UARTBusCallback &) = default; // Copy assignment operator
UARTBusCallback(UARTBusCallback &&) = default; // Move constructor
UARTBusCallback &operator=(UARTBusCallback &&) = default; // Move assignment operator
virtual void txCompleteCallback() const = 0;
virtual void rxCompleteCallback() const = 0;
virtual void rxEventCallback(uint16_t size) const = 0;
virtual void errorCallback() const = 0;
protected:
struct RegistryEntry
{
const UART_HandleTypeDef *handle = nullptr;
const UARTBusCallback *instance = nullptr;
};
};
//--------------------------------------------------------------
/* --- */
//--------------------------------------------------------------
class UARTBusCallbackRegistry
{
static constexpr size_t MAX_UART_INSTANCES = 4;
public:
static bool registerInstance(const UART_HandleTypeDef *handle, const UARTBusCallback *instance); // Register instance with UART handle
static void unregisterInstance(const UARTBusCallback *instance); // Unregister instance with UART handle
static const UARTBusCallback *getInstance(const UART_HandleTypeDef *handle); // Get instance from UART handle
protected:
static inline std::array<UARTBusCallback::RegistryEntry, MAX_UART_INSTANCES> s_registry;
};
//--------------------------------------------------------------
/* Register instance with UART handle */
inline bool UARTBusCallbackRegistry::registerInstance(const UART_HandleTypeDef *handle, const UARTBusCallback *instance)
{
for (auto &entry : s_registry)
{
if (!entry.handle)
{
entry.handle = handle;
entry.instance = instance;
return true; // Successfully registered
}
}
return false; // Registry full
}
//--------------------------------------------------------------
/* Unregister instance with UART handle */
inline void UARTBusCallbackRegistry::unregisterInstance(const UARTBusCallback *instance)
{
for (auto &entry : s_registry)
{
if (entry.instance == instance)
{
entry.handle = nullptr;
entry.instance = nullptr;
}
}
}
//--------------------------------------------------------------
/* Get instance from UART handle */
inline const UARTBusCallback *UARTBusCallbackRegistry::getInstance(const UART_HandleTypeDef *handle)
{
for (const auto &entry : s_registry)
{
if (entry.handle == handle)
return entry.instance;
}
return nullptr;
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::stm32::comm

View File

@@ -0,0 +1,198 @@
/* ---
* FONCTIONNEMENT PAS TRES CLAIR, A REVOIR
*/
//{{copyright}}
//{{version}}
//{{license}}
#pragma once
#include "UARTBus.h"
#include <atomic>
namespace sdi_uToolBox::stm32::comm
{
//--------------------------------------------------------------
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
class UARTBusIT : public stm32::comm::UARTBus
{
public:
UARTBusIT() = default; // Default constructor
virtual ~UARTBusIT() override = default; // Default destructor
UARTBusIT(const UARTBusIT &) = delete; // Copy constructor
UARTBusIT(UARTBusIT &&) = delete; // Move constructor
UARTBusIT &operator=(const UARTBusIT &) = delete; // Copy assignment operator
UARTBusIT &operator=(UARTBusIT &&) = delete; // Move assignment operator
ReturnType write(WriteBuf buf, Timeout timeout) const override; // Write data to UART device
ReturnType read(ReadBuf buf, Timeout timeout) const override; // Read data from UART device
// Callback to be called from ISR when TX, RX is complete or error occurs
void txCompleteCallback() const; // TX complete callback
void rxCompleteCallback() const; // RX complete callback
void errorCallback() const; // Error callback
protected:
mutable std::array<uint8_t, TX_BUFFER_SIZE> m_txBuffer;
mutable std::array<uint8_t, RX_BUFFER_SIZE> m_rxBuffer;
mutable std::atomic<bool> m_txComplete{ false };
mutable std::atomic<bool> m_rxComplete{ false };
mutable std::atomic<bool> m_txError{ false };
mutable std::atomic<bool> m_rxError{ false };
mutable std::atomic<size_t> m_lastTxSize{ 0 };
mutable std::atomic<size_t> m_lastRxSize{ 0 };
static bool waitForFlag(const std::atomic<bool> &flag, Timeout timeout);
};
//--------------------------------------------------------------
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline UARTBus::ReturnType UARTBusIT<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::write(const WriteBuf buf, const Timeout timeout) const
{
if (!m_uartHandle)
return std::unexpected(ReturnStatus::InvalidHandle);
if (buf.size() > TX_BUFFER_SIZE)
return std::unexpected(ReturnStatus::Error);
// Copy data to internal buffer
std::copy(buf.begin(), buf.end(), m_txBuffer.begin());
// Reset flags
m_txComplete.store(false, std::memory_order_release);
m_txError.store(false, std::memory_order_release);
m_lastTxSize.store(0, std::memory_order_release);
// Start transmission with interrupt
const auto ret = HAL_UART_Transmit_IT(m_uartHandle,
const_cast<uint8_t *>(m_txBuffer.data()),
buf.size());
if (ret != HAL_OK)
{
if (ret == HAL_BUSY)
return std::unexpected(ReturnStatus::Busy);
return std::unexpected(ReturnStatus::Error);
}
// Wait for transmission to complete
if (!waitForFlag(m_txComplete, timeout))
{
HAL_UART_AbortTransmit(m_uartHandle);
return std::unexpected(ReturnStatus::Timeout);
}
// Check for errors
if (m_txError.load(std::memory_order_acquire))
return std::unexpected(ReturnStatus::Error);
return m_lastTxSize.load(std::memory_order_acquire);
}
//--------------------------------------------------------------
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline UARTBus::ReturnType UARTBusIT<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::read(ReadBuf buf, const Timeout timeout) const
{
if (!m_uartHandle)
return std::unexpected(ReturnStatus::InvalidHandle);
if (buf.size() > RX_BUFFER_SIZE)
return std::unexpected(ReturnStatus::Error);
// Reset flags
m_rxComplete.store(false, std::memory_order_release);
m_rxError.store(false, std::memory_order_release);
m_lastRxSize.store(0, std::memory_order_release);
// Start reception with interrupt
const auto ret = HAL_UART_Receive_IT(m_uartHandle,
m_rxBuffer.data(),
buf.size());
if (ret != HAL_OK)
{
if (ret == HAL_BUSY)
return std::unexpected(ReturnStatus::Busy);
return std::unexpected(ReturnStatus::Error);
}
// Wait for reception to complete
if (!waitForFlag(m_rxComplete, timeout))
{
HAL_UART_AbortReceive(m_uartHandle);
return std::unexpected(ReturnStatus::Timeout);
}
// Check for errors
if (m_rxError.load(std::memory_order_acquire))
return std::unexpected(ReturnStatus::Error);
// Copy data from internal buffer to output buffer
const size_t receivedSize = m_lastRxSize.load(std::memory_order_acquire);
std::copy_n(m_rxBuffer.begin(), receivedSize, buf.begin());
return receivedSize;
}
//--------------------------------------------------------------
/* TX complete callback */
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline void UARTBusIT<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::txCompleteCallback() const
{
m_lastTxSize.store(m_uartHandle->TxXferSize - m_uartHandle->TxXferCount,
std::memory_order_release);
m_txComplete.store(true, std::memory_order_release);
}
//--------------------------------------------------------------
/* RX complete callback */
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline void UARTBusIT<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::rxCompleteCallback() const
{
m_lastRxSize.store(m_uartHandle->RxXferSize - m_uartHandle->RxXferCount,
std::memory_order_release);
m_rxComplete.store(true, std::memory_order_release);
}
//--------------------------------------------------------------
/* Error callback */
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline void UARTBusIT<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::errorCallback() const
{
if (m_uartHandle->gState == HAL_UART_STATE_BUSY_TX ||
m_uartHandle->gState == HAL_UART_STATE_BUSY_TX_RX)
{
m_txError.store(true, std::memory_order_release);
m_txComplete.store(true, std::memory_order_release);
}
if (m_uartHandle->RxState == HAL_UART_STATE_BUSY_RX ||
m_uartHandle->gState == HAL_UART_STATE_BUSY_TX_RX)
{
m_rxError.store(true, std::memory_order_release);
m_rxComplete.store(true, std::memory_order_release);
}
}
//--------------------------------------------------------------
template<size_t TX_BUFFER_SIZE, size_t RX_BUFFER_SIZE>
inline bool UARTBusIT<TX_BUFFER_SIZE, RX_BUFFER_SIZE>::waitForFlag(const std::atomic<bool> &flag, Timeout timeout)
{
const auto startTime = std::chrono::steady_clock::now();
while (!flag.load(std::memory_order_acquire))
{
const auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - startTime);
if (elapsed >= timeout)
return false;
// Small delay to avoid busy waiting consuming too much CPU
for (volatile int i = 0; i < 1000; ++i)
;
}
return true;
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::stm32::comm

View File

@@ -0,0 +1,52 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <array>
#include <cstdint>
#include <optional>
namespace sdi_uToolBox::stm32
{
//--------------------------------------------------------------
class CriticalSection final
{
public:
CriticalSection(); // Constructor
~CriticalSection(); // Destructor
CriticalSection(const CriticalSection &other) = delete; // Copy constructor
CriticalSection(CriticalSection &&other) noexcept = delete; // Move constructor
CriticalSection &operator=(const CriticalSection &other) = delete; // Copy assignment
CriticalSection &operator=(CriticalSection &&other) noexcept = delete; // Move assignment
protected:
uint32_t m_primask;
};
//--------------------------------------------------------------
//--------------------------------------------------------------
/* Constructor */
inline CriticalSection::CriticalSection()
{
m_primask = __get_PRIMASK();
__disable_irq();
}
//--------------------------------------------------------------
/* Destructor */
inline CriticalSection::~CriticalSection()
{
if ((m_primask & 0x01) == 0) // Only if interrupts were enabled
__enable_irq();
}
//--------------------------------------------------------------
} // namespace sdi_uToolBox::stm32

View File

@@ -0,0 +1,20 @@
#pragma once
#include <main.h>
//--------------------------------------------------------------
// Set a real type for FPU usage if available
#if defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)
# if defined(__FPU_DP) && (__FPU_DP == 1U)
// FPU with double precision support
using Real = double;
# else
// FPU with single precision only
using Real = float;
# endif
#else
// No FPU present. Floating point will be emulated
// (It is better to use a smaller type to be cheaper)
using Real = float;
#endif
//--------------------------------------------------------------

View File

@@ -0,0 +1,80 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>SDi toolsBox</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="custom_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">sdi_toolBox
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',false,false,'search.php','Search');
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div class="header">
<div class="headertitle"><div class="title">Class List</div></div>
</div><!--header-->
<div class="contents">
<div class="textblock">Here are the classes, structs, unions and interfaces with brief descriptions:</div><div class="directory">
<div class="levels">[detail level <span onclick="javascript:toggleLevel(1);">1</span><span onclick="javascript:toggleLevel(2);">2</span><span onclick="javascript:toggleLevel(3);">3</span><span onclick="javascript:toggleLevel(4);">4</span><span onclick="javascript:toggleLevel(5);">5</span>]</div><table class="directory">
<tr id="row_0_" class="even"><td class="entry"><span style="width:0px;display:inline-block;">&#160;</span><span id="arr_0_" class="arrow" onclick="toggleFolder('0_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespacesdi__toolBox.html" target="_self">sdi_toolBox</a></td><td class="desc">Root namespace for the <a class="el" href="namespacesdi__toolBox.html" title="Root namespace for the sdi_toolBox library.">sdi_toolBox</a> library </td></tr>
<tr id="row_0_0_" class="odd"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span id="arr_0_0_" class="arrow" onclick="toggleFolder('0_0_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespacesdi__toolBox_1_1common.html" target="_self">common</a></td><td class="desc">Cross-platform, reusable components shared across all <a class="el" href="namespacesdi__toolBox.html" title="Root namespace for the sdi_toolBox library.">sdi_toolBox</a> modules </td></tr>
<tr id="row_0_0_0_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span id="arr_0_0_0_" class="arrow" onclick="toggleFolder('0_0_0_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespacesdi__toolBox_1_1common_1_1utils.html" target="_self">utils</a></td><td class="desc">General-purpose utility functions shared across all <a class="el" href="namespacesdi__toolBox.html" title="Root namespace for the sdi_toolBox library.">sdi_toolBox</a> modules </td></tr>
<tr id="row_0_0_0_0_" class="odd"><td class="entry"><span style="width:64px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html" target="_self">CircularBuffer</a></td><td class="desc">Fixed-size circular buffer with compile-time capacity and no-overwrite behavior </td></tr>
<tr id="row_0_0_0_1_" class="even"><td class="entry"><span style="width:64px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html" target="_self">RingBuffer</a></td><td class="desc">Fixed-size ring (circular) buffer with compile-time capacity and overwrite-on-full behavior </td></tr>
<tr id="row_0_1_" class="odd"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span id="arr_0_1_" class="arrow" onclick="toggleFolder('0_1_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespacesdi__toolBox_1_1desktop.html" target="_self">desktop</a></td><td class="desc">Desktop-specific components of the <a class="el" href="namespacesdi__toolBox.html" title="Root namespace for the sdi_toolBox library.">sdi_toolBox</a> library </td></tr>
<tr id="row_0_1_0_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span id="arr_0_1_0_" class="arrow" onclick="toggleFolder('0_1_0_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html" target="_self">eventBus</a></td><td class="desc">Lightweight thread-safe event bus for decoupled message passing </td></tr>
<tr id="row_0_1_0_0_" class="odd"><td class="entry"><span style="width:64px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html" target="_self">Bus</a></td><td class="desc">Central message dispatcher for the event bus system </td></tr>
<tr id="row_0_1_0_1_" class="even"><td class="entry"><span style="width:64px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html" target="_self">INode</a></td><td class="desc">Abstract interface representing a subscriber node in the event bus system </td></tr>
<tr id="row_0_1_0_2_" class="odd"><td class="entry"><span style="width:64px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html" target="_self">Message</a></td><td class="desc">Base class for all messages dispatched through the event bus </td></tr>
<tr id="row_0_1_0_3_" class="even"><td class="entry"><span style="width:64px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" target="_self">Node</a></td><td class="desc">Concrete subscriber node in the event bus system </td></tr>
<tr id="row_0_1_1_" class="odd"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span id="arr_0_1_1_" class="arrow" onclick="toggleFolder('0_1_1_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1utils.html" target="_self">utils</a></td><td class="desc">General-purpose utility functions and helpers for desktop applications </td></tr>
<tr id="row_0_1_1_0_" class="even"><td class="entry"><span style="width:64px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html" target="_self">Base64</a></td><td class="desc">Utility class providing <a class="el" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html" title="Utility class providing Base64 encoding and decoding functionality.">Base64</a> encoding and decoding functionality </td></tr>
<tr id="row_0_1_2_" class="odd"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span id="arr_0_1_2_" class="arrow" onclick="toggleFolder('0_1_2_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1wxWidgets.html" target="_self">wxWidgets</a></td><td class="desc">Namespace containing desktop UI utilities built on top of the <a class="el" href="namespacesdi__toolBox_1_1desktop_1_1wxWidgets.html" title="Namespace containing desktop UI utilities built on top of the wxWidgets framework.">wxWidgets</a> framework </td></tr>
<tr id="row_0_1_2_0_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span id="arr_0_1_2_0_" class="arrow" onclick="toggleFolder('0_1_2_0_')">&#9660;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classsdi__toolBox_1_1desktop_1_1wxWidgets_1_1Wildcard.html" target="_self">Wildcard</a></td><td class="desc">Manages a list of file wildcard entries for use in <a class="el" href="namespacesdi__toolBox_1_1desktop_1_1wxWidgets.html" title="Namespace containing desktop UI utilities built on top of the wxWidgets framework.">wxWidgets</a> file dialogs </td></tr>
<tr id="row_0_1_2_0_0_" class="odd"><td class="entry"><span style="width:80px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="structsdi__toolBox_1_1desktop_1_1wxWidgets_1_1Wildcard_1_1WildcardEntry.html" target="_self">WildcardEntry</a></td><td class="desc">Represents a single wildcard filter entry </td></tr>
</table>
</div><!-- directory -->
</div><!-- contents -->
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
SDi toolsBox is licensed under the terms and conditions of the <a href="https://opensource.org/licenses/zlib-license.php" target="_blank">zlib/png license</a>
<br />
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE | ver: 2.x.x - build: 2026-04-28
<br />
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen" /></a> 1.9.8
</small>
</address>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View File

@@ -0,0 +1,108 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>SDi toolsBox</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="custom_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">sdi_toolBox
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',false,false,'search.php','Search');
});
/* @license-end */
</script>
<div id="main-nav"></div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_1635ad76f8180971a36e709fb0d71e5a.html">toolBox</a></li><li class="navelem"><a class="el" href="dir_a330ae4cda0dd4c6ab0e77aa921b4b70.html">sdi_toolBox</a></li><li class="navelem"><a class="el" href="dir_089392a25720db55834b493c7f458d0d.html">desktop</a></li><li class="navelem"><a class="el" href="dir_11c5793896b93cca99bb38bbe3ee2a48.html">utils</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="summary">
<a href="#nested-classes">Classes</a> &#124;
<a href="#namespaces">Namespaces</a> </div>
<div class="headertitle"><div class="title">base64.h File Reference</div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><code>#include &lt;optional&gt;</code><br />
<code>#include &lt;span&gt;</code><br />
<code>#include &lt;string&gt;</code><br />
<code>#include &lt;vector&gt;</code><br />
</div><div class="textblock"><div class="dynheader">
Include dependency graph for base64.h:</div>
<div class="dyncontent">
<div class="center"><img src="base64_8h__incl.png" border="0" usemap="#abase64_8h" alt=""/></div>
<map name="abase64_8h" id="abase64_8h">
<area shape="rect" title=" " alt="" coords="130,5,211,31"/>
<area shape="rect" title=" " alt="" coords="5,79,80,104"/>
<area shape="poly" title=" " alt="" coords="151,33,77,74,75,69,149,28"/>
<area shape="rect" title=" " alt="" coords="104,79,157,104"/>
<area shape="poly" title=" " alt="" coords="166,32,146,68,142,65,162,30"/>
<area shape="rect" title=" " alt="" coords="181,79,240,104"/>
<area shape="poly" title=" " alt="" coords="180,30,200,65,195,68,175,32"/>
<area shape="rect" title=" " alt="" coords="265,79,327,104"/>
<area shape="poly" title=" " alt="" coords="192,28,265,69,262,74,189,33"/>
</map>
</div>
</div>
<p><a href="base64_8h_source.html">Go to the source code of this file.</a></p>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="nested-classes" name="nested-classes"></a>
Classes</h2></td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html">Base64</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Utility class providing <a class="el" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html" title="Utility class providing Base64 encoding and decoding functionality.">Base64</a> encoding and decoding functionality. <a href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="namespaces" name="namespaces"></a>
Namespaces</h2></td></tr>
<tr class="memitem:namespacesdi__toolBox" id="r_namespacesdi__toolBox"><td class="memItemLeft" align="right" valign="top">namespace &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespacesdi__toolBox.html">sdi_toolBox</a></td></tr>
<tr class="memdesc:namespacesdi__toolBox"><td class="mdescLeft">&#160;</td><td class="mdescRight">Root namespace for the <a class="el" href="namespacesdi__toolBox.html" title="Root namespace for the sdi_toolBox library.">sdi_toolBox</a> library. <br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:namespacesdi__toolBox_1_1desktop" id="r_namespacesdi__toolBox_1_1desktop"><td class="memItemLeft" align="right" valign="top">namespace &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespacesdi__toolBox_1_1desktop.html">sdi_toolBox::desktop</a></td></tr>
<tr class="memdesc:namespacesdi__toolBox_1_1desktop"><td class="mdescLeft">&#160;</td><td class="mdescRight">Desktop-specific components of the <a class="el" href="namespacesdi__toolBox.html" title="Root namespace for the sdi_toolBox library.">sdi_toolBox</a> library. <br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:namespacesdi__toolBox_1_1desktop_1_1utils" id="r_namespacesdi__toolBox_1_1desktop_1_1utils"><td class="memItemLeft" align="right" valign="top">namespace &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1utils.html">sdi_toolBox::desktop::utils</a></td></tr>
<tr class="memdesc:namespacesdi__toolBox_1_1desktop_1_1utils"><td class="mdescLeft">&#160;</td><td class="mdescRight">General-purpose utility functions and helpers for desktop applications. <br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
</div><!-- contents -->
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
SDi toolsBox is licensed under the terms and conditions of the <a href="https://opensource.org/licenses/zlib-license.php" target="_blank">zlib/png license</a>
<br />
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE | ver: 2.x.x - build: 2026-04-28
<br />
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen" /></a> 1.9.8
</small>
</address>
</body>
</html>

View File

@@ -0,0 +1,11 @@
<map id="base64.h" name="base64.h">
<area shape="rect" id="Node000001" title=" " alt="" coords="130,5,211,31"/>
<area shape="rect" id="Node000002" title=" " alt="" coords="5,79,80,104"/>
<area shape="poly" id="edge1_Node000001_Node000002" title=" " alt="" coords="151,33,77,74,75,69,149,28"/>
<area shape="rect" id="Node000003" title=" " alt="" coords="104,79,157,104"/>
<area shape="poly" id="edge2_Node000001_Node000003" title=" " alt="" coords="166,32,146,68,142,65,162,30"/>
<area shape="rect" id="Node000004" title=" " alt="" coords="181,79,240,104"/>
<area shape="poly" id="edge3_Node000001_Node000004" title=" " alt="" coords="180,30,200,65,195,68,175,32"/>
<area shape="rect" id="Node000005" title=" " alt="" coords="265,79,327,104"/>
<area shape="poly" id="edge4_Node000001_Node000005" title=" " alt="" coords="192,28,265,69,262,74,189,33"/>
</map>

View File

@@ -0,0 +1 @@
ead93328ecd2c7e45c0deccd102428a5

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

@@ -0,0 +1,267 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>SDi toolsBox</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="custom_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">sdi_toolBox
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',false,false,'search.php','Search');
});
/* @license-end */
</script>
<div id="main-nav"></div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(document).ready(function() { init_codefold(0); });
/* @license-end */
</script>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_1635ad76f8180971a36e709fb0d71e5a.html">toolBox</a></li><li class="navelem"><a class="el" href="dir_a330ae4cda0dd4c6ab0e77aa921b4b70.html">sdi_toolBox</a></li><li class="navelem"><a class="el" href="dir_089392a25720db55834b493c7f458d0d.html">desktop</a></li><li class="navelem"><a class="el" href="dir_11c5793896b93cca99bb38bbe3ee2a48.html">utils</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle"><div class="title">base64.h</div></div>
</div><!--header-->
<div class="contents">
<a href="base64_8h.html">Go to the documentation of this file.</a><div class="fragment"><div class="line"><a id="l00001" name="l00001"></a><span class="lineno"> 1</span><span class="comment">/*</span></div>
<div class="line"><a id="l00002" name="l00002"></a><span class="lineno"> 2</span><span class="comment"> Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE</span></div>
<div class="line"><a id="l00003" name="l00003"></a><span class="lineno"> 3</span><span class="comment">*/</span></div>
<div class="line"><a id="l00004" name="l00004"></a><span class="lineno"> 4</span> </div>
<div class="line"><a id="l00005" name="l00005"></a><span class="lineno"> 5</span><span class="comment">/*</span></div>
<div class="line"><a id="l00006" name="l00006"></a><span class="lineno"> 6</span><span class="comment">ver: 2.x.x - build: 2026-04-28</span></div>
<div class="line"><a id="l00007" name="l00007"></a><span class="lineno"> 7</span><span class="comment">*/</span></div>
<div class="line"><a id="l00008" name="l00008"></a><span class="lineno"> 8</span> </div>
<div class="line"><a id="l00009" name="l00009"></a><span class="lineno"> 9</span><span class="comment">/*</span></div>
<div class="line"><a id="l00010" name="l00010"></a><span class="lineno"> 10</span><span class="comment">The zlib License
Copyright (c) 2026 SD-Innovation S.A.S.
This software is provided as-is, without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
</span></div>
<div class="line"><a id="l00011" name="l00011"></a><span class="lineno"> 11</span><span class="comment">*/</span></div>
<div class="line"><a id="l00012" name="l00012"></a><span class="lineno"> 12</span> </div>
<div class="line"><a id="l00013" name="l00013"></a><span class="lineno"> 13</span><span class="preprocessor">#pragma once</span></div>
<div class="line"><a id="l00014" name="l00014"></a><span class="lineno"> 14</span> </div>
<div class="line"><a id="l00015" name="l00015"></a><span class="lineno"> 15</span><span class="preprocessor">#include &lt;optional&gt;</span></div>
<div class="line"><a id="l00016" name="l00016"></a><span class="lineno"> 16</span><span class="preprocessor">#include &lt;span&gt;</span></div>
<div class="line"><a id="l00017" name="l00017"></a><span class="lineno"> 17</span><span class="preprocessor">#include &lt;string&gt;</span></div>
<div class="line"><a id="l00018" name="l00018"></a><span class="lineno"> 18</span><span class="preprocessor">#include &lt;vector&gt;</span></div>
<div class="line"><a id="l00019" name="l00019"></a><span class="lineno"> 19</span> </div>
<div class="foldopen" id="foldopen00020" data-start="{" data-end="}">
<div class="line"><a id="l00020" name="l00020"></a><span class="lineno"><a class="line" href="namespacesdi__toolBox_1_1desktop_1_1utils.html"> 20</a></span><span class="keyword">namespace </span><a class="code hl_namespace" href="namespacesdi__toolBox_1_1desktop_1_1utils.html">sdi_toolBox::desktop::utils</a></div>
<div class="line"><a id="l00021" name="l00021"></a><span class="lineno"> 21</span>{</div>
<div class="line"><a id="l00022" name="l00022"></a><span class="lineno"> 22</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="foldopen" id="foldopen00052" data-start="{" data-end="};">
<div class="line"><a id="l00052" name="l00052"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html"> 52</a></span><span class="keyword">class </span><a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html">Base64</a></div>
<div class="line"><a id="l00053" name="l00053"></a><span class="lineno"> 53</span>{</div>
<div class="line"><a id="l00054" name="l00054"></a><span class="lineno"> 54</span> <span class="keyword">public</span>:</div>
<div class="line"><a id="l00058" name="l00058"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#a2e146328e4ebf4dfbb018ec1609ffb0d"> 58</a></span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#a2e146328e4ebf4dfbb018ec1609ffb0d">Base64</a>() = <span class="keyword">delete</span>;</div>
<div class="line"><a id="l00059" name="l00059"></a><span class="lineno"> 59</span> </div>
<div class="line"><a id="l00062" name="l00062"></a><span class="lineno"> 62</span> </div>
<div class="line"><a id="l00069" name="l00069"></a><span class="lineno"> 69</span> [[nodiscard]] <span class="keyword">static</span> std::string <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#aa3aa7a6ab01dfcb27b4b54248288d863">encode</a>(std::span&lt;const std::uint8_t&gt; data);</div>
<div class="line"><a id="l00070" name="l00070"></a><span class="lineno"> 70</span> </div>
<div class="line"><a id="l00077" name="l00077"></a><span class="lineno"> 77</span> [[nodiscard]] <span class="keyword">static</span> std::string <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#aa3aa7a6ab01dfcb27b4b54248288d863">encode</a>(std::string_view text);</div>
<div class="line"><a id="l00078" name="l00078"></a><span class="lineno"> 78</span> </div>
<div class="line"><a id="l00082" name="l00082"></a><span class="lineno"> 82</span> </div>
<div class="line"><a id="l00091" name="l00091"></a><span class="lineno"> 91</span> [[nodiscard]] <span class="keyword">static</span> std::optional&lt;std::vector&lt;std::uint8_t&gt;&gt; <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#a935d1f391f3f2f7225e8afb6e2d8b7c4">decode</a>(std::string_view input);</div>
<div class="line"><a id="l00092" name="l00092"></a><span class="lineno"> 92</span> </div>
<div class="line"><a id="l00101" name="l00101"></a><span class="lineno"> 101</span> [[nodiscard]] <span class="keyword">static</span> std::optional&lt;std::string&gt; <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#a9f119bd9a4f05b462ee53198bd7db5f6">decode_to_string</a>(std::string_view input);</div>
<div class="line"><a id="l00102" name="l00102"></a><span class="lineno"> 102</span> </div>
<div class="line"><a id="l00104" name="l00104"></a><span class="lineno"> 104</span> </div>
<div class="line"><a id="l00105" name="l00105"></a><span class="lineno"> 105</span> <span class="keyword">private</span>:</div>
<div class="line"><a id="l00108" name="l00108"></a><span class="lineno"> 108</span> </div>
<div class="line"><a id="l00116" name="l00116"></a><span class="lineno"> 116</span> [[nodiscard]] <span class="keyword">static</span> std::optional&lt;std::uint8_t&gt; decode_char(<span class="keywordtype">char</span> c) <span class="keyword">noexcept</span>;</div>
<div class="line"><a id="l00117" name="l00117"></a><span class="lineno"> 117</span> </div>
<div class="line"><a id="l00121" name="l00121"></a><span class="lineno"> 121</span> </div>
<div class="line"><a id="l00123" name="l00123"></a><span class="lineno"> 123</span> <span class="keyword">static</span> <span class="keyword">constexpr</span> std::string_view ENCODE_LOOKUP = <span class="stringliteral">&quot;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/&quot;</span>;</div>
<div class="line"><a id="l00124" name="l00124"></a><span class="lineno"> 124</span> </div>
<div class="line"><a id="l00126" name="l00126"></a><span class="lineno"> 126</span> <span class="keyword">static</span> <span class="keyword">constexpr</span> <span class="keywordtype">char</span> PADDING_CAR = <span class="charliteral">&#39;=&#39;</span>;</div>
<div class="line"><a id="l00127" name="l00127"></a><span class="lineno"> 127</span> </div>
<div class="line"><a id="l00129" name="l00129"></a><span class="lineno"> 129</span>};</div>
</div>
<div class="line"><a id="l00130" name="l00130"></a><span class="lineno"> 130</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00131" name="l00131"></a><span class="lineno"> 131</span> </div>
<div class="line"><a id="l00132" name="l00132"></a><span class="lineno"> 132</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00133" name="l00133"></a><span class="lineno"> 133</span><span class="comment">/* Encode binary data to Base64 string */</span></div>
<div class="foldopen" id="foldopen00134" data-start="{" data-end="}">
<div class="line"><a id="l00134" name="l00134"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#aa3aa7a6ab01dfcb27b4b54248288d863"> 134</a></span><span class="keyword">inline</span> std::string <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#aa3aa7a6ab01dfcb27b4b54248288d863">Base64::encode</a>(<span class="keyword">const</span> std::span&lt;const std::uint8_t&gt; data)</div>
<div class="line"><a id="l00135" name="l00135"></a><span class="lineno"> 135</span>{</div>
<div class="line"><a id="l00136" name="l00136"></a><span class="lineno"> 136</span> std::string result;</div>
<div class="line"><a id="l00137" name="l00137"></a><span class="lineno"> 137</span> result.reserve(((data.size() + 2) / 3) * 4);</div>
<div class="line"><a id="l00138" name="l00138"></a><span class="lineno"> 138</span> </div>
<div class="line"><a id="l00139" name="l00139"></a><span class="lineno"> 139</span> <span class="keywordflow">for</span> (std::size_t i = 0; i &lt; data.size(); i += 3)</div>
<div class="line"><a id="l00140" name="l00140"></a><span class="lineno"> 140</span> {</div>
<div class="line"><a id="l00141" name="l00141"></a><span class="lineno"> 141</span> <span class="keyword">const</span> std::uint32_t b0 = data[i];</div>
<div class="line"><a id="l00142" name="l00142"></a><span class="lineno"> 142</span> <span class="keyword">const</span> std::uint32_t b1 = (i + 1 &lt; data.size()) ? data[i + 1] : 0u;</div>
<div class="line"><a id="l00143" name="l00143"></a><span class="lineno"> 143</span> <span class="keyword">const</span> std::uint32_t b2 = (i + 2 &lt; data.size()) ? data[i + 2] : 0u;</div>
<div class="line"><a id="l00144" name="l00144"></a><span class="lineno"> 144</span> </div>
<div class="line"><a id="l00145" name="l00145"></a><span class="lineno"> 145</span> <span class="keyword">const</span> std::uint32_t triple = (b0 &lt;&lt; 16) | (b1 &lt;&lt; 8) | b2;</div>
<div class="line"><a id="l00146" name="l00146"></a><span class="lineno"> 146</span> </div>
<div class="line"><a id="l00147" name="l00147"></a><span class="lineno"> 147</span> result += ENCODE_LOOKUP[(triple &gt;&gt; 18) &amp; 0x3F];</div>
<div class="line"><a id="l00148" name="l00148"></a><span class="lineno"> 148</span> result += ENCODE_LOOKUP[(triple &gt;&gt; 12) &amp; 0x3F];</div>
<div class="line"><a id="l00149" name="l00149"></a><span class="lineno"> 149</span> result += (i + 1 &lt; data.size()) ? ENCODE_LOOKUP[(triple &gt;&gt; 6) &amp; 0x3F] : PADDING_CAR;</div>
<div class="line"><a id="l00150" name="l00150"></a><span class="lineno"> 150</span> result += (i + 2 &lt; data.size()) ? ENCODE_LOOKUP[(triple &gt;&gt; 0) &amp; 0x3F] : PADDING_CAR;</div>
<div class="line"><a id="l00151" name="l00151"></a><span class="lineno"> 151</span> }</div>
<div class="line"><a id="l00152" name="l00152"></a><span class="lineno"> 152</span> </div>
<div class="line"><a id="l00153" name="l00153"></a><span class="lineno"> 153</span> <span class="keywordflow">return</span> result;</div>
<div class="line"><a id="l00154" name="l00154"></a><span class="lineno"> 154</span>}</div>
</div>
<div class="line"><a id="l00155" name="l00155"></a><span class="lineno"> 155</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00156" name="l00156"></a><span class="lineno"> 156</span><span class="comment">/* Encode a text string to Base64 string */</span></div>
<div class="foldopen" id="foldopen00157" data-start="{" data-end="}">
<div class="line"><a id="l00157" name="l00157"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#a1894a56a676ed98e17066c4d185593b4"> 157</a></span><span class="keyword">inline</span> std::string <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#aa3aa7a6ab01dfcb27b4b54248288d863">Base64::encode</a>(<span class="keyword">const</span> std::string_view text)</div>
<div class="line"><a id="l00158" name="l00158"></a><span class="lineno"> 158</span>{</div>
<div class="line"><a id="l00159" name="l00159"></a><span class="lineno"> 159</span> <span class="keywordflow">return</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#aa3aa7a6ab01dfcb27b4b54248288d863">encode</a>(std::span(<span class="keyword">reinterpret_cast&lt;</span><span class="keyword">const </span>std::uint8_t *<span class="keyword">&gt;</span>(text.data()), text.size()));</div>
<div class="line"><a id="l00160" name="l00160"></a><span class="lineno"> 160</span>}</div>
</div>
<div class="line"><a id="l00161" name="l00161"></a><span class="lineno"> 161</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00162" name="l00162"></a><span class="lineno"> 162</span><span class="comment">/* Decode a Base64 string to binary data (returns std::nullopt if invalid) */</span></div>
<div class="foldopen" id="foldopen00163" data-start="{" data-end="}">
<div class="line"><a id="l00163" name="l00163"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#a935d1f391f3f2f7225e8afb6e2d8b7c4"> 163</a></span><span class="keyword">inline</span> std::optional&lt;std::vector&lt;std::uint8_t&gt;&gt; <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#a935d1f391f3f2f7225e8afb6e2d8b7c4">Base64::decode</a>(<span class="keyword">const</span> std::string_view input)</div>
<div class="line"><a id="l00164" name="l00164"></a><span class="lineno"> 164</span>{</div>
<div class="line"><a id="l00165" name="l00165"></a><span class="lineno"> 165</span> <span class="keywordflow">if</span> (input.size() % 4 != 0)</div>
<div class="line"><a id="l00166" name="l00166"></a><span class="lineno"> 166</span> <span class="keywordflow">return</span> std::nullopt;</div>
<div class="line"><a id="l00167" name="l00167"></a><span class="lineno"> 167</span> </div>
<div class="line"><a id="l00168" name="l00168"></a><span class="lineno"> 168</span> <span class="keywordflow">if</span> (input.empty())</div>
<div class="line"><a id="l00169" name="l00169"></a><span class="lineno"> 169</span> <span class="keywordflow">return</span> std::vector&lt;std::uint8_t&gt;{};</div>
<div class="line"><a id="l00170" name="l00170"></a><span class="lineno"> 170</span> </div>
<div class="line"><a id="l00171" name="l00171"></a><span class="lineno"> 171</span> <span class="comment">// Validate padding: &#39;=&#39; is only allowed in the last group, in position 2 or 3</span></div>
<div class="line"><a id="l00172" name="l00172"></a><span class="lineno"> 172</span> <span class="comment">// Valid forms: &quot;xxx=&quot; or &quot;xx==&quot;</span></div>
<div class="line"><a id="l00173" name="l00173"></a><span class="lineno"> 173</span> <span class="keywordflow">for</span> (std::size_t i = 0; i &lt; input.size() - 4; ++i)</div>
<div class="line"><a id="l00174" name="l00174"></a><span class="lineno"> 174</span> {</div>
<div class="line"><a id="l00175" name="l00175"></a><span class="lineno"> 175</span> <span class="keywordflow">if</span> (input[i] == PADDING_CAR)</div>
<div class="line"><a id="l00176" name="l00176"></a><span class="lineno"> 176</span> <span class="keywordflow">return</span> std::nullopt; <span class="comment">// &#39;=&#39; found outside the last group</span></div>
<div class="line"><a id="l00177" name="l00177"></a><span class="lineno"> 177</span> }</div>
<div class="line"><a id="l00178" name="l00178"></a><span class="lineno"> 178</span> </div>
<div class="line"><a id="l00179" name="l00179"></a><span class="lineno"> 179</span> <span class="keyword">const</span> std::string_view last = input.substr(input.size() - 4);</div>
<div class="line"><a id="l00180" name="l00180"></a><span class="lineno"> 180</span> <span class="comment">// &quot;xx==&quot; : positions 0,1 must be valid chars, positions 2,3 must be &#39;=&#39;</span></div>
<div class="line"><a id="l00181" name="l00181"></a><span class="lineno"> 181</span> <span class="comment">// &quot;xxx=&quot; : positions 0,1,2 must be valid chars, position 3 must be &#39;=&#39;</span></div>
<div class="line"><a id="l00182" name="l00182"></a><span class="lineno"> 182</span> <span class="comment">// &quot;xxxx&quot; : all positions must be valid chars</span></div>
<div class="line"><a id="l00183" name="l00183"></a><span class="lineno"> 183</span> <span class="keywordflow">if</span> (last[2] == PADDING_CAR &amp;&amp; last[3] != PADDING_CAR)</div>
<div class="line"><a id="l00184" name="l00184"></a><span class="lineno"> 184</span> <span class="keywordflow">return</span> std::nullopt; <span class="comment">// &quot;xx=x&quot; is invalid</span></div>
<div class="line"><a id="l00185" name="l00185"></a><span class="lineno"> 185</span> </div>
<div class="line"><a id="l00186" name="l00186"></a><span class="lineno"> 186</span> std::vector&lt;std::uint8_t&gt; result;</div>
<div class="line"><a id="l00187" name="l00187"></a><span class="lineno"> 187</span> result.reserve((input.size() / 4) * 3);</div>
<div class="line"><a id="l00188" name="l00188"></a><span class="lineno"> 188</span> </div>
<div class="line"><a id="l00189" name="l00189"></a><span class="lineno"> 189</span> <span class="keywordflow">for</span> (std::size_t i = 0; i &lt; input.size(); i += 4)</div>
<div class="line"><a id="l00190" name="l00190"></a><span class="lineno"> 190</span> {</div>
<div class="line"><a id="l00191" name="l00191"></a><span class="lineno"> 191</span> <span class="keyword">const</span> <span class="keyword">auto</span> v0 = decode_char(input[i]);</div>
<div class="line"><a id="l00192" name="l00192"></a><span class="lineno"> 192</span> <span class="keyword">const</span> <span class="keyword">auto</span> v1 = decode_char(input[i + 1]);</div>
<div class="line"><a id="l00193" name="l00193"></a><span class="lineno"> 193</span> <span class="keyword">const</span> <span class="keyword">auto</span> v2 = input[i + 2] == PADDING_CAR ? std::optional&lt;std::uint8_t&gt;{ 0 } : decode_char(input[i + 2]);</div>
<div class="line"><a id="l00194" name="l00194"></a><span class="lineno"> 194</span> <span class="keyword">const</span> <span class="keyword">auto</span> v3 = input[i + 3] == PADDING_CAR ? std::optional&lt;std::uint8_t&gt;{ 0 } : decode_char(input[i + 3]);</div>
<div class="line"><a id="l00195" name="l00195"></a><span class="lineno"> 195</span> </div>
<div class="line"><a id="l00196" name="l00196"></a><span class="lineno"> 196</span> <span class="keywordflow">if</span> (!v0 || !v1 || !v2 || !v3)</div>
<div class="line"><a id="l00197" name="l00197"></a><span class="lineno"> 197</span> <span class="keywordflow">return</span> std::nullopt;</div>
<div class="line"><a id="l00198" name="l00198"></a><span class="lineno"> 198</span> </div>
<div class="line"><a id="l00199" name="l00199"></a><span class="lineno"> 199</span> <span class="keyword">const</span> std::uint32_t triple =</div>
<div class="line"><a id="l00200" name="l00200"></a><span class="lineno"> 200</span> (<span class="keyword">static_cast&lt;</span>std::uint32_t<span class="keyword">&gt;</span>(*v0) &lt;&lt; 18) |</div>
<div class="line"><a id="l00201" name="l00201"></a><span class="lineno"> 201</span> (<span class="keyword">static_cast&lt;</span>std::uint32_t<span class="keyword">&gt;</span>(*v1) &lt;&lt; 12) |</div>
<div class="line"><a id="l00202" name="l00202"></a><span class="lineno"> 202</span> (<span class="keyword">static_cast&lt;</span>std::uint32_t<span class="keyword">&gt;</span>(*v2) &lt;&lt; 6) |</div>
<div class="line"><a id="l00203" name="l00203"></a><span class="lineno"> 203</span> (<span class="keyword">static_cast&lt;</span>std::uint32_t<span class="keyword">&gt;</span>(*v3));</div>
<div class="line"><a id="l00204" name="l00204"></a><span class="lineno"> 204</span> </div>
<div class="line"><a id="l00205" name="l00205"></a><span class="lineno"> 205</span> result.push_back(<span class="keyword">static_cast&lt;</span>std::uint8_t<span class="keyword">&gt;</span>((triple &gt;&gt; 16) &amp; 0xFF));</div>
<div class="line"><a id="l00206" name="l00206"></a><span class="lineno"> 206</span> <span class="keywordflow">if</span> (input[i + 2] != PADDING_CAR)</div>
<div class="line"><a id="l00207" name="l00207"></a><span class="lineno"> 207</span> result.push_back(<span class="keyword">static_cast&lt;</span>std::uint8_t<span class="keyword">&gt;</span>((triple &gt;&gt; 8) &amp; 0xFF));</div>
<div class="line"><a id="l00208" name="l00208"></a><span class="lineno"> 208</span> <span class="keywordflow">if</span> (input[i + 3] != PADDING_CAR)</div>
<div class="line"><a id="l00209" name="l00209"></a><span class="lineno"> 209</span> result.push_back(<span class="keyword">static_cast&lt;</span>std::uint8_t<span class="keyword">&gt;</span>((triple &gt;&gt; 0) &amp; 0xFF));</div>
<div class="line"><a id="l00210" name="l00210"></a><span class="lineno"> 210</span> }</div>
<div class="line"><a id="l00211" name="l00211"></a><span class="lineno"> 211</span> </div>
<div class="line"><a id="l00212" name="l00212"></a><span class="lineno"> 212</span> <span class="keywordflow">return</span> result;</div>
<div class="line"><a id="l00213" name="l00213"></a><span class="lineno"> 213</span>}</div>
</div>
<div class="line"><a id="l00214" name="l00214"></a><span class="lineno"> 214</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00215" name="l00215"></a><span class="lineno"> 215</span><span class="comment">/* Decode a Base64 string to a text string (returns std::nullopt if invalid) */</span></div>
<div class="foldopen" id="foldopen00216" data-start="{" data-end="}">
<div class="line"><a id="l00216" name="l00216"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#a9f119bd9a4f05b462ee53198bd7db5f6"> 216</a></span><span class="keyword">inline</span> std::optional&lt;std::string&gt; <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#a9f119bd9a4f05b462ee53198bd7db5f6">Base64::decode_to_string</a>(<span class="keyword">const</span> std::string_view input)</div>
<div class="line"><a id="l00217" name="l00217"></a><span class="lineno"> 217</span>{</div>
<div class="line"><a id="l00218" name="l00218"></a><span class="lineno"> 218</span> <span class="keyword">const</span> <span class="keyword">auto</span> bytes = <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#a935d1f391f3f2f7225e8afb6e2d8b7c4">decode</a>(input);</div>
<div class="line"><a id="l00219" name="l00219"></a><span class="lineno"> 219</span> <span class="keywordflow">if</span> (!bytes)</div>
<div class="line"><a id="l00220" name="l00220"></a><span class="lineno"> 220</span> <span class="keywordflow">return</span> std::nullopt;</div>
<div class="line"><a id="l00221" name="l00221"></a><span class="lineno"> 221</span> <span class="keywordflow">return</span> std::string(<span class="keyword">reinterpret_cast&lt;</span><span class="keyword">const </span><span class="keywordtype">char</span> *<span class="keyword">&gt;</span>(bytes-&gt;data()), bytes-&gt;size());</div>
<div class="line"><a id="l00222" name="l00222"></a><span class="lineno"> 222</span>}</div>
</div>
<div class="line"><a id="l00223" name="l00223"></a><span class="lineno"> 223</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00224" name="l00224"></a><span class="lineno"> 224</span><span class="comment">/* Helper to decode a single Base64 character to its 6-bit value (returns std::nullopt if invalid) */</span></div>
<div class="line"><a id="l00225" name="l00225"></a><span class="lineno"> 225</span><span class="keyword">inline</span> std::optional&lt;std::uint8_t&gt; Base64::decode_char(<span class="keyword">const</span> <span class="keywordtype">char</span> c) <span class="keyword">noexcept</span></div>
<div class="line"><a id="l00226" name="l00226"></a><span class="lineno"> 226</span>{</div>
<div class="line"><a id="l00227" name="l00227"></a><span class="lineno"> 227</span> <span class="keywordflow">if</span> (c &gt;= <span class="charliteral">&#39;A&#39;</span> &amp;&amp; c &lt;= <span class="charliteral">&#39;Z&#39;</span>)</div>
<div class="line"><a id="l00228" name="l00228"></a><span class="lineno"> 228</span> <span class="keywordflow">return</span> <span class="keyword">static_cast&lt;</span>std::uint8_t<span class="keyword">&gt;</span>(c - <span class="charliteral">&#39;A&#39;</span>);</div>
<div class="line"><a id="l00229" name="l00229"></a><span class="lineno"> 229</span> <span class="keywordflow">if</span> (c &gt;= <span class="charliteral">&#39;a&#39;</span> &amp;&amp; c &lt;= <span class="charliteral">&#39;z&#39;</span>)</div>
<div class="line"><a id="l00230" name="l00230"></a><span class="lineno"> 230</span> <span class="keywordflow">return</span> <span class="keyword">static_cast&lt;</span>std::uint8_t<span class="keyword">&gt;</span>(c - <span class="charliteral">&#39;a&#39;</span> + 26);</div>
<div class="line"><a id="l00231" name="l00231"></a><span class="lineno"> 231</span> <span class="keywordflow">if</span> (c &gt;= <span class="charliteral">&#39;0&#39;</span> &amp;&amp; c &lt;= <span class="charliteral">&#39;9&#39;</span>)</div>
<div class="line"><a id="l00232" name="l00232"></a><span class="lineno"> 232</span> <span class="keywordflow">return</span> <span class="keyword">static_cast&lt;</span>std::uint8_t<span class="keyword">&gt;</span>(c - <span class="charliteral">&#39;0&#39;</span> + 52);</div>
<div class="line"><a id="l00233" name="l00233"></a><span class="lineno"> 233</span> <span class="keywordflow">if</span> (c == <span class="charliteral">&#39;+&#39;</span>)</div>
<div class="line"><a id="l00234" name="l00234"></a><span class="lineno"> 234</span> <span class="keywordflow">return</span> 62;</div>
<div class="line"><a id="l00235" name="l00235"></a><span class="lineno"> 235</span> <span class="keywordflow">if</span> (c == <span class="charliteral">&#39;/&#39;</span>)</div>
<div class="line"><a id="l00236" name="l00236"></a><span class="lineno"> 236</span> <span class="keywordflow">return</span> 63;</div>
<div class="line"><a id="l00237" name="l00237"></a><span class="lineno"> 237</span> <span class="keywordflow">return</span> std::nullopt;</div>
<div class="line"><a id="l00238" name="l00238"></a><span class="lineno"> 238</span>}</div>
<div class="line"><a id="l00239" name="l00239"></a><span class="lineno"> 239</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00240" name="l00240"></a><span class="lineno"> 240</span>} <span class="comment">// namespace sdi_toolBox::desktop::utils</span></div>
</div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1utils_1_1Base64_html"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html">sdi_toolBox::desktop::utils::Base64</a></div><div class="ttdoc">Utility class providing Base64 encoding and decoding functionality.</div><div class="ttdef"><b>Definition</b> <a href="base64_8h_source.html#l00052">base64.h:53</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1utils_1_1Base64_html_a2e146328e4ebf4dfbb018ec1609ffb0d"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#a2e146328e4ebf4dfbb018ec1609ffb0d">sdi_toolBox::desktop::utils::Base64::Base64</a></div><div class="ttdeci">Base64()=delete</div><div class="ttdoc">Deleted default constructor - this class is not meant to be instantiated.</div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1utils_1_1Base64_html_a935d1f391f3f2f7225e8afb6e2d8b7c4"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#a935d1f391f3f2f7225e8afb6e2d8b7c4">sdi_toolBox::desktop::utils::Base64::decode</a></div><div class="ttdeci">static std::optional&lt; std::vector&lt; std::uint8_t &gt; &gt; decode(std::string_view input)</div><div class="ttdoc">Decodes a Base64 string into raw binary data.</div><div class="ttdef"><b>Definition</b> <a href="base64_8h_source.html#l00163">base64.h:163</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1utils_1_1Base64_html_a9f119bd9a4f05b462ee53198bd7db5f6"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#a9f119bd9a4f05b462ee53198bd7db5f6">sdi_toolBox::desktop::utils::Base64::decode_to_string</a></div><div class="ttdeci">static std::optional&lt; std::string &gt; decode_to_string(std::string_view input)</div><div class="ttdoc">Decodes a Base64 string into a text string.</div><div class="ttdef"><b>Definition</b> <a href="base64_8h_source.html#l00216">base64.h:216</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1utils_1_1Base64_html_aa3aa7a6ab01dfcb27b4b54248288d863"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html#aa3aa7a6ab01dfcb27b4b54248288d863">sdi_toolBox::desktop::utils::Base64::encode</a></div><div class="ttdeci">static std::string encode(std::span&lt; const std::uint8_t &gt; data)</div><div class="ttdoc">Encodes binary data into a Base64 string.</div><div class="ttdef"><b>Definition</b> <a href="base64_8h_source.html#l00134">base64.h:134</a></div></div>
<div class="ttc" id="anamespacesdi__toolBox_1_1desktop_1_1utils_html"><div class="ttname"><a href="namespacesdi__toolBox_1_1desktop_1_1utils.html">sdi_toolBox::desktop::utils</a></div><div class="ttdoc">General-purpose utility functions and helpers for desktop applications.</div><div class="ttdef"><b>Definition</b> <a href="base64_8h_source.html#l00020">base64.h:21</a></div></div>
</div><!-- fragment --></div><!-- contents -->
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
SDi toolsBox is licensed under the terms and conditions of the <a href="https://opensource.org/licenses/zlib-license.php" target="_blank">zlib/png license</a>
<br />
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE | ver: 2.x.x - build: 2026-04-28
<br />
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen" /></a> 1.9.8
</small>
</address>
</body>

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 635 B

View File

@@ -0,0 +1,138 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>SDi toolsBox</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="custom_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">sdi_toolBox
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',false,false,'search.php','Search');
});
/* @license-end */
</script>
<div id="main-nav"></div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_1635ad76f8180971a36e709fb0d71e5a.html">toolBox</a></li><li class="navelem"><a class="el" href="dir_a330ae4cda0dd4c6ab0e77aa921b4b70.html">sdi_toolBox</a></li><li class="navelem"><a class="el" href="dir_089392a25720db55834b493c7f458d0d.html">desktop</a></li><li class="navelem"><a class="el" href="dir_03a79da52393399f003ece50c2786062.html">eventBus</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="summary">
<a href="#nested-classes">Classes</a> &#124;
<a href="#namespaces">Namespaces</a> </div>
<div class="headertitle"><div class="title">bus.h File Reference</div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><code>#include &quot;<a class="el" href="defs_8h_source.html">defs.h</a>&quot;</code><br />
<code>#include &quot;<a class="el" href="inode_8h_source.html">inode.h</a>&quot;</code><br />
<code>#include &quot;<a class="el" href="message_8h_source.html">message.h</a>&quot;</code><br />
<code>#include &lt;chrono&gt;</code><br />
<code>#include &lt;memory&gt;</code><br />
<code>#include &lt;mutex&gt;</code><br />
<code>#include &lt;ranges&gt;</code><br />
<code>#include &lt;set&gt;</code><br />
<code>#include &lt;unordered_map&gt;</code><br />
</div><div class="textblock"><div class="dynheader">
Include dependency graph for bus.h:</div>
<div class="dyncontent">
<div class="center"><img src="bus_8h__incl.png" border="0" usemap="#abus_8h" alt=""/></div>
<map name="abus_8h" id="abus_8h">
<area shape="rect" title=" " alt="" coords="273,5,330,31"/>
<area shape="rect" href="defs_8h.html" title=" " alt="" coords="103,225,166,251"/>
<area shape="poly" title=" " alt="" coords="292,33,253,80,225,130,213,152,195,179,160,218,156,214,191,176,209,149,220,127,248,77,288,29"/>
<area shape="rect" title=" " alt="" coords="5,299,72,324"/>
<area shape="poly" title=" " alt="" coords="273,25,152,43,92,59,70,69,55,80,40,104,30,130,24,158,22,187,26,241,34,285,29,286,21,242,17,187,19,157,25,129,35,101,51,77,67,65,90,54,151,38,272,19"/>
<area shape="rect" href="inode_8h.html" title=" " alt="" coords="66,79,137,104"/>
<area shape="poly" title=" " alt="" coords="273,32,147,77,145,72,271,27"/>
<area shape="rect" href="message_8h.html" title=" " alt="" coords="88,152,181,177"/>
<area shape="poly" title=" " alt="" coords="280,33,245,54,208,81,178,112,153,142,149,139,174,108,205,77,242,49,278,28"/>
<area shape="rect" title=" " alt="" coords="263,79,340,104"/>
<area shape="poly" title=" " alt="" coords="304,31,304,65,299,65,299,31"/>
<area shape="rect" title=" " alt="" coords="364,79,428,104"/>
<area shape="poly" title=" " alt="" coords="318,29,371,68,368,72,315,33"/>
<area shape="rect" title=" " alt="" coords="452,79,519,104"/>
<area shape="poly" title=" " alt="" coords="331,28,444,71,442,76,329,33"/>
<area shape="rect" title=" " alt="" coords="543,79,585,104"/>
<area shape="poly" title=" " alt="" coords="331,23,530,76,529,81,329,29"/>
<area shape="rect" title=" " alt="" coords="610,79,734,104"/>
<area shape="poly" title=" " alt="" coords="331,22,600,74,599,79,330,27"/>
<area shape="poly" title=" " alt="" coords="121,253,67,292,64,288,118,249"/>
<area shape="rect" title=" " alt="" coords="101,299,168,324"/>
<area shape="poly" title=" " alt="" coords="137,251,137,285,132,285,132,251"/>
<area shape="poly" title=" " alt="" coords="109,103,126,139,121,141,104,105"/>
<area shape="poly" title=" " alt="" coords="137,178,137,212,132,212,132,178"/>
</map>
</div>
</div><div class="textblock"><div class="dynheader">
This graph shows which files directly or indirectly include this file:</div>
<div class="dyncontent">
<div class="center"><img src="bus_8h__dep__incl.png" border="0" usemap="#abus_8hdep" alt=""/></div>
<map name="abus_8hdep" id="abus_8hdep">
<area shape="rect" title=" " alt="" coords="10,5,67,31"/>
<area shape="rect" href="node_8h.html" title=" " alt="" coords="5,79,72,104"/>
<area shape="poly" title=" " alt="" coords="41,44,41,79,36,79,36,44"/>
</map>
</div>
</div>
<p><a href="bus_8h_source.html">Go to the source code of this file.</a></p>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="nested-classes" name="nested-classes"></a>
Classes</h2></td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Central message dispatcher for the event bus system. <a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="namespaces" name="namespaces"></a>
Namespaces</h2></td></tr>
<tr class="memitem:namespacesdi__toolBox" id="r_namespacesdi__toolBox"><td class="memItemLeft" align="right" valign="top">namespace &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespacesdi__toolBox.html">sdi_toolBox</a></td></tr>
<tr class="memdesc:namespacesdi__toolBox"><td class="mdescLeft">&#160;</td><td class="mdescRight">Root namespace for the <a class="el" href="namespacesdi__toolBox.html" title="Root namespace for the sdi_toolBox library.">sdi_toolBox</a> library. <br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:namespacesdi__toolBox_1_1desktop" id="r_namespacesdi__toolBox_1_1desktop"><td class="memItemLeft" align="right" valign="top">namespace &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespacesdi__toolBox_1_1desktop.html">sdi_toolBox::desktop</a></td></tr>
<tr class="memdesc:namespacesdi__toolBox_1_1desktop"><td class="mdescLeft">&#160;</td><td class="mdescRight">Desktop-specific components of the <a class="el" href="namespacesdi__toolBox.html" title="Root namespace for the sdi_toolBox library.">sdi_toolBox</a> library. <br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:namespacesdi__toolBox_1_1desktop_1_1eventBus" id="r_namespacesdi__toolBox_1_1desktop_1_1eventBus"><td class="memItemLeft" align="right" valign="top">namespace &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html">sdi_toolBox::desktop::eventBus</a></td></tr>
<tr class="memdesc:namespacesdi__toolBox_1_1desktop_1_1eventBus"><td class="mdescLeft">&#160;</td><td class="mdescRight">Lightweight thread-safe event bus for decoupled message passing. <br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
</div><!-- contents -->
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
SDi toolsBox is licensed under the terms and conditions of the <a href="https://opensource.org/licenses/zlib-license.php" target="_blank">zlib/png license</a>
<br />
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE | ver: 2.x.x - build: 2026-04-28
<br />
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen" /></a> 1.9.8
</small>
</address>
</body>
</html>

View File

@@ -0,0 +1,5 @@
<map id="bus.h" name="bus.h">
<area shape="rect" id="Node000001" title=" " alt="" coords="10,5,67,31"/>
<area shape="rect" id="Node000002" href="$node_8h.html" title=" " alt="" coords="5,79,72,104"/>
<area shape="poly" id="edge1_Node000001_Node000002" title=" " alt="" coords="41,44,41,79,36,79,36,44"/>
</map>

View File

@@ -0,0 +1 @@
01308bca61c42e9e37c65b0bc028d8e3

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1,26 @@
<map id="bus.h" name="bus.h">
<area shape="rect" id="Node000001" title=" " alt="" coords="273,5,330,31"/>
<area shape="rect" id="Node000002" href="$defs_8h.html" title=" " alt="" coords="103,225,166,251"/>
<area shape="poly" id="edge1_Node000001_Node000002" title=" " alt="" coords="292,33,253,80,225,130,213,152,195,179,160,218,156,214,191,176,209,149,220,127,248,77,288,29"/>
<area shape="rect" id="Node000003" title=" " alt="" coords="5,299,72,324"/>
<area shape="poly" id="edge8_Node000001_Node000003" title=" " alt="" coords="273,25,152,43,92,59,70,69,55,80,40,104,30,130,24,158,22,187,26,241,34,285,29,286,21,242,17,187,19,157,25,129,35,101,51,77,67,65,90,54,151,38,272,19"/>
<area shape="rect" id="Node000005" href="$inode_8h.html" title=" " alt="" coords="66,79,137,104"/>
<area shape="poly" id="edge4_Node000001_Node000005" title=" " alt="" coords="273,32,147,77,145,72,271,27"/>
<area shape="rect" id="Node000006" href="$message_8h.html" title=" " alt="" coords="88,152,181,177"/>
<area shape="poly" id="edge7_Node000001_Node000006" title=" " alt="" coords="280,33,245,54,208,81,178,112,153,142,149,139,174,108,205,77,242,49,278,28"/>
<area shape="rect" id="Node000007" title=" " alt="" coords="263,79,340,104"/>
<area shape="poly" id="edge9_Node000001_Node000007" title=" " alt="" coords="304,31,304,65,299,65,299,31"/>
<area shape="rect" id="Node000008" title=" " alt="" coords="364,79,428,104"/>
<area shape="poly" id="edge10_Node000001_Node000008" title=" " alt="" coords="318,29,371,68,368,72,315,33"/>
<area shape="rect" id="Node000009" title=" " alt="" coords="452,79,519,104"/>
<area shape="poly" id="edge11_Node000001_Node000009" title=" " alt="" coords="331,28,444,71,442,76,329,33"/>
<area shape="rect" id="Node000010" title=" " alt="" coords="543,79,585,104"/>
<area shape="poly" id="edge12_Node000001_Node000010" title=" " alt="" coords="331,23,530,76,529,81,329,29"/>
<area shape="rect" id="Node000011" title=" " alt="" coords="610,79,734,104"/>
<area shape="poly" id="edge13_Node000001_Node000011" title=" " alt="" coords="331,22,600,74,599,79,330,27"/>
<area shape="poly" id="edge2_Node000002_Node000003" title=" " alt="" coords="121,253,67,292,64,288,118,249"/>
<area shape="rect" id="Node000004" title=" " alt="" coords="101,299,168,324"/>
<area shape="poly" id="edge3_Node000002_Node000004" title=" " alt="" coords="137,251,137,285,132,285,132,251"/>
<area shape="poly" id="edge5_Node000005_Node000006" title=" " alt="" coords="109,103,126,139,121,141,104,105"/>
<area shape="poly" id="edge6_Node000006_Node000002" title=" " alt="" coords="137,178,137,212,132,212,132,178"/>
</map>

View File

@@ -0,0 +1 @@
a8d88937fc8d1309a42f3f072a7f5503

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -0,0 +1,434 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>SDi toolsBox</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="custom_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">sdi_toolBox
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',false,false,'search.php','Search');
});
/* @license-end */
</script>
<div id="main-nav"></div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(document).ready(function() { init_codefold(0); });
/* @license-end */
</script>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_1635ad76f8180971a36e709fb0d71e5a.html">toolBox</a></li><li class="navelem"><a class="el" href="dir_a330ae4cda0dd4c6ab0e77aa921b4b70.html">sdi_toolBox</a></li><li class="navelem"><a class="el" href="dir_089392a25720db55834b493c7f458d0d.html">desktop</a></li><li class="navelem"><a class="el" href="dir_03a79da52393399f003ece50c2786062.html">eventBus</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle"><div class="title">bus.h</div></div>
</div><!--header-->
<div class="contents">
<a href="bus_8h.html">Go to the documentation of this file.</a><div class="fragment"><div class="line"><a id="l00001" name="l00001"></a><span class="lineno"> 1</span><span class="comment">/*</span></div>
<div class="line"><a id="l00002" name="l00002"></a><span class="lineno"> 2</span><span class="comment"> Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE</span></div>
<div class="line"><a id="l00003" name="l00003"></a><span class="lineno"> 3</span><span class="comment">*/</span></div>
<div class="line"><a id="l00004" name="l00004"></a><span class="lineno"> 4</span> </div>
<div class="line"><a id="l00005" name="l00005"></a><span class="lineno"> 5</span><span class="comment">/*</span></div>
<div class="line"><a id="l00006" name="l00006"></a><span class="lineno"> 6</span><span class="comment">ver: 2.x.x - build: 2026-04-28</span></div>
<div class="line"><a id="l00007" name="l00007"></a><span class="lineno"> 7</span><span class="comment">*/</span></div>
<div class="line"><a id="l00008" name="l00008"></a><span class="lineno"> 8</span> </div>
<div class="line"><a id="l00009" name="l00009"></a><span class="lineno"> 9</span><span class="comment">/*</span></div>
<div class="line"><a id="l00010" name="l00010"></a><span class="lineno"> 10</span><span class="comment">The zlib License
Copyright (c) 2026 SD-Innovation S.A.S.
This software is provided as-is, without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
</span></div>
<div class="line"><a id="l00011" name="l00011"></a><span class="lineno"> 11</span><span class="comment">*/</span></div>
<div class="line"><a id="l00012" name="l00012"></a><span class="lineno"> 12</span> </div>
<div class="line"><a id="l00013" name="l00013"></a><span class="lineno"> 13</span><span class="preprocessor">#pragma once</span></div>
<div class="line"><a id="l00014" name="l00014"></a><span class="lineno"> 14</span> </div>
<div class="line"><a id="l00015" name="l00015"></a><span class="lineno"> 15</span><span class="preprocessor">#include &quot;<a class="code" href="defs_8h.html">defs.h</a>&quot;</span></div>
<div class="line"><a id="l00016" name="l00016"></a><span class="lineno"> 16</span><span class="preprocessor">#include &quot;<a class="code" href="inode_8h.html">inode.h</a>&quot;</span></div>
<div class="line"><a id="l00017" name="l00017"></a><span class="lineno"> 17</span><span class="preprocessor">#include &quot;<a class="code" href="message_8h.html">message.h</a>&quot;</span></div>
<div class="line"><a id="l00018" name="l00018"></a><span class="lineno"> 18</span> </div>
<div class="line"><a id="l00019" name="l00019"></a><span class="lineno"> 19</span><span class="preprocessor">#include &lt;chrono&gt;</span></div>
<div class="line"><a id="l00020" name="l00020"></a><span class="lineno"> 20</span><span class="preprocessor">#include &lt;memory&gt;</span></div>
<div class="line"><a id="l00021" name="l00021"></a><span class="lineno"> 21</span><span class="preprocessor">#include &lt;mutex&gt;</span></div>
<div class="line"><a id="l00022" name="l00022"></a><span class="lineno"> 22</span><span class="preprocessor">#include &lt;ranges&gt;</span></div>
<div class="line"><a id="l00023" name="l00023"></a><span class="lineno"> 23</span><span class="preprocessor">#include &lt;set&gt;</span></div>
<div class="line"><a id="l00024" name="l00024"></a><span class="lineno"> 24</span><span class="preprocessor">#include &lt;unordered_map&gt;</span></div>
<div class="line"><a id="l00025" name="l00025"></a><span class="lineno"> 25</span> </div>
<div class="foldopen" id="foldopen00026" data-start="{" data-end="}">
<div class="line"><a id="l00026" name="l00026"></a><span class="lineno"><a class="line" href="namespacesdi__toolBox_1_1desktop.html"> 26</a></span><span class="keyword">namespace </span><a class="code hl_namespace" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html">sdi_toolBox::desktop::eventBus</a></div>
<div class="line"><a id="l00027" name="l00027"></a><span class="lineno"> 27</span>{</div>
<div class="line"><a id="l00028" name="l00028"></a><span class="lineno"> 28</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="foldopen" id="foldopen00062" data-start="{" data-end="};">
<div class="line"><a id="l00062" name="l00062"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html"> 62</a></span><span class="keyword">class </span><a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> final</div>
<div class="line"><a id="l00063" name="l00063"></a><span class="lineno"> 63</span>{</div>
<div class="line"><a id="l00064" name="l00064"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a6db9d28bd448a131448276ee03de1e6d"> 64</a></span> <span class="keyword">friend</span> <span class="keyword">class </span><a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a>; </div>
<div class="line"><a id="l00065" name="l00065"></a><span class="lineno"> 65</span> </div>
<div class="line"><a id="l00066" name="l00066"></a><span class="lineno"> 66</span> <span class="keyword">using </span>VectorNode = std::vector&lt;INode *&gt;;</div>
<div class="line"><a id="l00067" name="l00067"></a><span class="lineno"> 67</span> </div>
<div class="line"><a id="l00068" name="l00068"></a><span class="lineno"> 68</span> <span class="keyword">public</span>:</div>
<div class="line"><a id="l00071" name="l00071"></a><span class="lineno"> 71</span> </div>
<div class="line"><a id="l00078" name="l00078"></a><span class="lineno"> 78</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a29358764c7d91cfcf3447e93b43bb20f">Bus</a>(); </div>
<div class="line"><a id="l00079" name="l00079"></a><span class="lineno"> 79</span> </div>
<div class="line"><a id="l00083" name="l00083"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#aaf1361cfa73ea4f24a5182e4aaf7f6e3"> 83</a></span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#aaf1361cfa73ea4f24a5182e4aaf7f6e3">~Bus</a>() = <span class="keywordflow">default</span>; </div>
<div class="line"><a id="l00084" name="l00084"></a><span class="lineno"> 84</span> </div>
<div class="line"><a id="l00090" name="l00090"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a472403c9840a1d19c264c55f00070a3e"> 90</a></span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a472403c9840a1d19c264c55f00070a3e">Bus</a>(<span class="keyword">const</span> <a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> &amp;obj) = <span class="keyword">delete</span>; </div>
<div class="line"><a id="l00091" name="l00091"></a><span class="lineno"> 91</span> </div>
<div class="line"><a id="l00097" name="l00097"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a422f08b55d205f02a11025e753679555"> 97</a></span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a422f08b55d205f02a11025e753679555">Bus</a>(<a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> &amp;&amp;obj) <span class="keyword">noexcept</span> = <span class="keyword">delete</span>; </div>
<div class="line"><a id="l00098" name="l00098"></a><span class="lineno"> 98</span> </div>
<div class="line"><a id="l00104" name="l00104"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#afc5179367040f25bcdb4e27d5682168b"> 104</a></span> <a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> &amp;<a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#afc5179367040f25bcdb4e27d5682168b">operator=</a>(<span class="keyword">const</span> <a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> &amp;obj) = <span class="keyword">delete</span>; </div>
<div class="line"><a id="l00105" name="l00105"></a><span class="lineno"> 105</span> </div>
<div class="line"><a id="l00111" name="l00111"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ad0f453f147d8e394a5b66b8494564a82"> 111</a></span> <a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> &amp;<a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ad0f453f147d8e394a5b66b8494564a82">operator=</a>(<a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> &amp;&amp;obj) <span class="keyword">noexcept</span> = <span class="keyword">delete</span>; </div>
<div class="line"><a id="l00112" name="l00112"></a><span class="lineno"> 112</span> </div>
<div class="line"><a id="l00116" name="l00116"></a><span class="lineno"> 116</span> </div>
<div class="line"><a id="l00126" name="l00126"></a><span class="lineno"> 126</span> <span class="keywordtype">void</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ab06a20c7848eddbcc910d5b03ea98f20">clearAllSubscriptions</a>();</div>
<div class="line"><a id="l00127" name="l00127"></a><span class="lineno"> 127</span> </div>
<div class="line"><a id="l00141" name="l00141"></a><span class="lineno"> 141</span> <span class="keywordtype">void</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#aaed1ce9185dbc68270991a68901e1d3e">subscribe</a>(<a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node, <a class="code hl_typedef" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a> eventType);</div>
<div class="line"><a id="l00142" name="l00142"></a><span class="lineno"> 142</span> </div>
<div class="line"><a id="l00156" name="l00156"></a><span class="lineno"> 156</span> <span class="keywordtype">void</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a27cc2e333f174e22b360045c7aad959d">unsubscribe</a>(<a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node, <a class="code hl_typedef" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a> eventType);</div>
<div class="line"><a id="l00157" name="l00157"></a><span class="lineno"> 157</span> </div>
<div class="line"><a id="l00171" name="l00171"></a><span class="lineno"> 171</span> <span class="keywordtype">void</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#af42df59cac80896d270e4bf2b350676f">unsubscribeFromAll</a>(<a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node);</div>
<div class="line"><a id="l00172" name="l00172"></a><span class="lineno"> 172</span> </div>
<div class="line"><a id="l00184" name="l00184"></a><span class="lineno"> 184</span> [[nodiscard]] <span class="keywordtype">bool</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a8574031338c5bf7827cc0d561ed93171">isSubscribed</a>(<span class="keyword">const</span> <a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node, <a class="code hl_typedef" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a> eventType) <span class="keyword">const</span>;</div>
<div class="line"><a id="l00185" name="l00185"></a><span class="lineno"> 185</span> </div>
<div class="line"><a id="l00189" name="l00189"></a><span class="lineno"> 189</span> </div>
<div class="line"><a id="l00203" name="l00203"></a><span class="lineno"> 203</span> <span class="keywordtype">void</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a309bedf4b2fb78c99de024ece1f39eb5">subscribeToBroadcast</a>(<a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node);</div>
<div class="line"><a id="l00204" name="l00204"></a><span class="lineno"> 204</span> </div>
<div class="line"><a id="l00216" name="l00216"></a><span class="lineno"> 216</span> <span class="keywordtype">void</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ae9c37a95472381e33190bd951e381ebe">unsubscribeFromBroadcast</a>(<a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node);</div>
<div class="line"><a id="l00217" name="l00217"></a><span class="lineno"> 217</span> </div>
<div class="line"><a id="l00228" name="l00228"></a><span class="lineno"> 228</span> [[nodiscard]] <span class="keywordtype">bool</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a7b375afd6d8b416cfd37e3bfce5b8ffd">isSubscribedToBroadcast</a>(<a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node) <span class="keyword">const</span>; <span class="comment">// Check if a node is subscribed to broadcast mode</span></div>
<div class="line"><a id="l00229" name="l00229"></a><span class="lineno"> 229</span> </div>
<div class="line"><a id="l00233" name="l00233"></a><span class="lineno"> 233</span> </div>
<div class="line"><a id="l00254" name="l00254"></a><span class="lineno"> 254</span> <span class="keyword">template</span>&lt;<span class="keyword">class </span>T, <span class="keyword">class</span>... Args&gt;</div>
<div class="line"><a id="l00255" name="l00255"></a><span class="lineno"> 255</span> <span class="keywordtype">bool</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a9aab57a60533a1a80a705bc569a9c589">emit</a>(Args &amp;&amp;...args);</div>
<div class="line"><a id="l00256" name="l00256"></a><span class="lineno"> 256</span> </div>
<div class="line"><a id="l00270" name="l00270"></a><span class="lineno"> 270</span> <span class="keywordtype">bool</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a92c2bc8aa8bcf018ffe954a3e8e34324">post</a>(<span class="keyword">const</span> std::shared_ptr&lt;Message&gt; &amp;message) <span class="keyword">const</span>; <span class="comment">// Post a message to the bus</span></div>
<div class="line"><a id="l00271" name="l00271"></a><span class="lineno"> 271</span> </div>
<div class="line"><a id="l00273" name="l00273"></a><span class="lineno"> 273</span> </div>
<div class="line"><a id="l00274" name="l00274"></a><span class="lineno"> 274</span> <span class="keyword">private</span>:</div>
<div class="line"><a id="l00281" name="l00281"></a><span class="lineno"> 281</span> <span class="keywordtype">size_t</span> postMessageToSubscribers(<a class="code hl_typedef" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a> eventType, <span class="keyword">const</span> std::shared_ptr&lt;Message&gt; &amp;message) <span class="keyword">const</span>;</div>
<div class="line"><a id="l00282" name="l00282"></a><span class="lineno"> 282</span> </div>
<div class="line"><a id="l00288" name="l00288"></a><span class="lineno"> 288</span> <span class="keywordtype">size_t</span> postMessageToBroadcastSubscribers(<span class="keyword">const</span> std::shared_ptr&lt;Message&gt; &amp;message) <span class="keyword">const</span>;</div>
<div class="line"><a id="l00289" name="l00289"></a><span class="lineno"> 289</span> </div>
<div class="line"><a id="l00295" name="l00295"></a><span class="lineno"> 295</span> <span class="keyword">const</span> VectorNode *getSubscribersForMessageType(<a class="code hl_typedef" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a> messageType) <span class="keyword">const</span>; <span class="comment">// Get the list of subscribers for a specific message type</span></div>
<div class="line"><a id="l00296" name="l00296"></a><span class="lineno"> 296</span> </div>
<div class="line"><a id="l00298" name="l00298"></a><span class="lineno"> 298</span> <a class="code hl_typedef" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#ae5ca775e8d8c664b6edef818ce1251b9">TimePoint</a> m_busStartTimestamp;</div>
<div class="line"><a id="l00299" name="l00299"></a><span class="lineno"> 299</span> </div>
<div class="line"><a id="l00301" name="l00301"></a><span class="lineno"> 301</span> <span class="keyword">struct</span></div>
<div class="line"><a id="l00302" name="l00302"></a><span class="lineno"> 302</span> {</div>
<div class="line"><a id="l00303" name="l00303"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ad5e0dbd36f0d71fce9b00b7f991b2f38"> 303</a></span> <span class="keyword">mutable</span> std::mutex <a class="code hl_variable" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ad5e0dbd36f0d71fce9b00b7f991b2f38">mtx</a>; </div>
<div class="line"><a id="l00304" name="l00304"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a4bc64bd8db5527dc8af9b458a82d6a65"> 304</a></span> std::unordered_map&lt;MessageTypeID, VectorNode&gt; <a class="code hl_variable" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a4bc64bd8db5527dc8af9b458a82d6a65">nodeList</a>; </div>
<div class="line"><a id="l00305" name="l00305"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a3c682b9a6b53418d7a147960e6dcdad1"> 305</a></span> std::set&lt;INode *&gt; <a class="code hl_variable" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a3c682b9a6b53418d7a147960e6dcdad1">broadcastNodeList</a>; </div>
<div class="line"><a id="l00306" name="l00306"></a><span class="lineno"> 306</span> } m_routingTable;</div>
<div class="line"><a id="l00307" name="l00307"></a><span class="lineno"> 307</span>};</div>
</div>
<div class="line"><a id="l00308" name="l00308"></a><span class="lineno"> 308</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00309" name="l00309"></a><span class="lineno"> 309</span> </div>
<div class="line"><a id="l00310" name="l00310"></a><span class="lineno"> 310</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00311" name="l00311"></a><span class="lineno"> 311</span><span class="comment">/* Default constructor */</span></div>
<div class="foldopen" id="foldopen00312" data-start="{" data-end="}">
<div class="line"><a id="l00312" name="l00312"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a29358764c7d91cfcf3447e93b43bb20f"> 312</a></span><span class="keyword">inline</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a29358764c7d91cfcf3447e93b43bb20f">Bus::Bus</a>()</div>
<div class="line"><a id="l00313" name="l00313"></a><span class="lineno"> 313</span>{</div>
<div class="line"><a id="l00314" name="l00314"></a><span class="lineno"> 314</span> <span class="comment">// Initialization</span></div>
<div class="line"><a id="l00315" name="l00315"></a><span class="lineno"> 315</span> m_busStartTimestamp = std::chrono::steady_clock::now();</div>
<div class="line"><a id="l00316" name="l00316"></a><span class="lineno"> 316</span>}</div>
</div>
<div class="line"><a id="l00317" name="l00317"></a><span class="lineno"> 317</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00318" name="l00318"></a><span class="lineno"> 318</span><span class="comment">/* Clear all subscriptions from the bus (remove all nodes from the routing table) */</span></div>
<div class="foldopen" id="foldopen00319" data-start="{" data-end="}">
<div class="line"><a id="l00319" name="l00319"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ab06a20c7848eddbcc910d5b03ea98f20"> 319</a></span><span class="keyword">inline</span> <span class="keywordtype">void</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ab06a20c7848eddbcc910d5b03ea98f20">Bus::clearAllSubscriptions</a>()</div>
<div class="line"><a id="l00320" name="l00320"></a><span class="lineno"> 320</span>{</div>
<div class="line"><a id="l00321" name="l00321"></a><span class="lineno"> 321</span> std::scoped_lock lock(m_routingTable.mtx);</div>
<div class="line"><a id="l00322" name="l00322"></a><span class="lineno"> 322</span> </div>
<div class="line"><a id="l00323" name="l00323"></a><span class="lineno"> 323</span> m_routingTable.nodeList.clear(); <span class="comment">// Clear all event subscriptions</span></div>
<div class="line"><a id="l00324" name="l00324"></a><span class="lineno"> 324</span> m_routingTable.broadcastNodeList.clear(); <span class="comment">// Clear all broadcast subscriptions</span></div>
<div class="line"><a id="l00325" name="l00325"></a><span class="lineno"> 325</span>}</div>
</div>
<div class="line"><a id="l00326" name="l00326"></a><span class="lineno"> 326</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00327" name="l00327"></a><span class="lineno"> 327</span><span class="comment">/* Subscribe a listener to a specific event type */</span></div>
<div class="foldopen" id="foldopen00328" data-start="{" data-end="}">
<div class="line"><a id="l00328" name="l00328"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#aaed1ce9185dbc68270991a68901e1d3e"> 328</a></span><span class="keyword">inline</span> <span class="keywordtype">void</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#aaed1ce9185dbc68270991a68901e1d3e">Bus::subscribe</a>(<a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node, <a class="code hl_typedef" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a> eventType)</div>
<div class="line"><a id="l00329" name="l00329"></a><span class="lineno"> 329</span>{</div>
<div class="line"><a id="l00330" name="l00330"></a><span class="lineno"> 330</span> <span class="comment">// Sanity check</span></div>
<div class="line"><a id="l00331" name="l00331"></a><span class="lineno"> 331</span> <span class="keywordflow">if</span> (!node)</div>
<div class="line"><a id="l00332" name="l00332"></a><span class="lineno"> 332</span> <span class="keywordflow">throw</span> std::runtime_error(<span class="stringliteral">&quot;invalid node handle&quot;</span>);</div>
<div class="line"><a id="l00333" name="l00333"></a><span class="lineno"> 333</span> </div>
<div class="line"><a id="l00334" name="l00334"></a><span class="lineno"> 334</span> std::scoped_lock lock(m_routingTable.mtx);</div>
<div class="line"><a id="l00335" name="l00335"></a><span class="lineno"> 335</span> </div>
<div class="line"><a id="l00336" name="l00336"></a><span class="lineno"> 336</span> <span class="keywordflow">if</span> (!m_routingTable.nodeList.contains(eventType)) <span class="comment">// Event type not registered yet, create a new entry with the node</span></div>
<div class="line"><a id="l00337" name="l00337"></a><span class="lineno"> 337</span> {</div>
<div class="line"><a id="l00338" name="l00338"></a><span class="lineno"> 338</span> m_routingTable.nodeList[eventType] = { node };</div>
<div class="line"><a id="l00339" name="l00339"></a><span class="lineno"> 339</span> }</div>
<div class="line"><a id="l00340" name="l00340"></a><span class="lineno"> 340</span> <span class="keywordflow">else</span> <span class="comment">// Event type already registered, add the node if not already subscribed</span></div>
<div class="line"><a id="l00341" name="l00341"></a><span class="lineno"> 341</span> {</div>
<div class="line"><a id="l00342" name="l00342"></a><span class="lineno"> 342</span> <span class="keyword">auto</span> &amp;nodes = m_routingTable.nodeList.at(eventType);</div>
<div class="line"><a id="l00343" name="l00343"></a><span class="lineno"> 343</span> <span class="keywordflow">if</span> (std::ranges::find(nodes, node) == nodes.end())</div>
<div class="line"><a id="l00344" name="l00344"></a><span class="lineno"> 344</span> {</div>
<div class="line"><a id="l00345" name="l00345"></a><span class="lineno"> 345</span> <span class="comment">// Node not already subscribed, add it to the list</span></div>
<div class="line"><a id="l00346" name="l00346"></a><span class="lineno"> 346</span> nodes.push_back(node);</div>
<div class="line"><a id="l00347" name="l00347"></a><span class="lineno"> 347</span> }</div>
<div class="line"><a id="l00348" name="l00348"></a><span class="lineno"> 348</span> }</div>
<div class="line"><a id="l00349" name="l00349"></a><span class="lineno"> 349</span>}</div>
</div>
<div class="line"><a id="l00350" name="l00350"></a><span class="lineno"> 350</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00351" name="l00351"></a><span class="lineno"> 351</span><span class="comment">/* Unsubscribe a listener from a specific event type */</span></div>
<div class="foldopen" id="foldopen00352" data-start="{" data-end="}">
<div class="line"><a id="l00352" name="l00352"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a27cc2e333f174e22b360045c7aad959d"> 352</a></span><span class="keyword">inline</span> <span class="keywordtype">void</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a27cc2e333f174e22b360045c7aad959d">Bus::unsubscribe</a>(<a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node, <a class="code hl_typedef" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a> eventType)</div>
<div class="line"><a id="l00353" name="l00353"></a><span class="lineno"> 353</span>{</div>
<div class="line"><a id="l00354" name="l00354"></a><span class="lineno"> 354</span> <span class="comment">// Sanity check</span></div>
<div class="line"><a id="l00355" name="l00355"></a><span class="lineno"> 355</span> <span class="keywordflow">if</span> (!node)</div>
<div class="line"><a id="l00356" name="l00356"></a><span class="lineno"> 356</span> <span class="keywordflow">throw</span> std::runtime_error(<span class="stringliteral">&quot;invalid node handle&quot;</span>);</div>
<div class="line"><a id="l00357" name="l00357"></a><span class="lineno"> 357</span> </div>
<div class="line"><a id="l00358" name="l00358"></a><span class="lineno"> 358</span> std::scoped_lock lock(m_routingTable.mtx);</div>
<div class="line"><a id="l00359" name="l00359"></a><span class="lineno"> 359</span> </div>
<div class="line"><a id="l00360" name="l00360"></a><span class="lineno"> 360</span> <span class="comment">// Event type not recorded, nothing to do</span></div>
<div class="line"><a id="l00361" name="l00361"></a><span class="lineno"> 361</span> <span class="keywordflow">if</span> (!m_routingTable.nodeList.contains(eventType))</div>
<div class="line"><a id="l00362" name="l00362"></a><span class="lineno"> 362</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l00363" name="l00363"></a><span class="lineno"> 363</span> </div>
<div class="line"><a id="l00364" name="l00364"></a><span class="lineno"> 364</span> <span class="comment">// Event type registered, remove the listener if subscribed</span></div>
<div class="line"><a id="l00365" name="l00365"></a><span class="lineno"> 365</span> <span class="keyword">auto</span> &amp;nodes = m_routingTable.nodeList.at(eventType);</div>
<div class="line"><a id="l00366" name="l00366"></a><span class="lineno"> 366</span> std::erase(nodes, node);</div>
<div class="line"><a id="l00367" name="l00367"></a><span class="lineno"> 367</span>}</div>
</div>
<div class="line"><a id="l00368" name="l00368"></a><span class="lineno"> 368</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00369" name="l00369"></a><span class="lineno"> 369</span><span class="comment">/* Unsubscribe a listener from a specific event type */</span></div>
<div class="foldopen" id="foldopen00370" data-start="{" data-end="}">
<div class="line"><a id="l00370" name="l00370"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#af42df59cac80896d270e4bf2b350676f"> 370</a></span><span class="keyword">inline</span> <span class="keywordtype">void</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#af42df59cac80896d270e4bf2b350676f">Bus::unsubscribeFromAll</a>(<a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node)</div>
<div class="line"><a id="l00371" name="l00371"></a><span class="lineno"> 371</span>{</div>
<div class="line"><a id="l00372" name="l00372"></a><span class="lineno"> 372</span> <span class="comment">// Sanity check</span></div>
<div class="line"><a id="l00373" name="l00373"></a><span class="lineno"> 373</span> <span class="keywordflow">if</span> (!node)</div>
<div class="line"><a id="l00374" name="l00374"></a><span class="lineno"> 374</span> <span class="keywordflow">throw</span> std::runtime_error(<span class="stringliteral">&quot;invalid node handle&quot;</span>);</div>
<div class="line"><a id="l00375" name="l00375"></a><span class="lineno"> 375</span> </div>
<div class="line"><a id="l00376" name="l00376"></a><span class="lineno"> 376</span> std::scoped_lock lock(m_routingTable.mtx);</div>
<div class="line"><a id="l00377" name="l00377"></a><span class="lineno"> 377</span> </div>
<div class="line"><a id="l00378" name="l00378"></a><span class="lineno"> 378</span> <span class="comment">// Iterate through all event types and remove the node from each list</span></div>
<div class="line"><a id="l00379" name="l00379"></a><span class="lineno"> 379</span> <span class="keywordflow">for</span> (<span class="keyword">auto</span> &amp;<a class="code hl_variable" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a4bc64bd8db5527dc8af9b458a82d6a65">nodeList</a> : m_routingTable.nodeList | std::views::values)</div>
<div class="line"><a id="l00380" name="l00380"></a><span class="lineno"> 380</span> std::erase(<a class="code hl_variable" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a4bc64bd8db5527dc8af9b458a82d6a65">nodeList</a>, node);</div>
<div class="line"><a id="l00381" name="l00381"></a><span class="lineno"> 381</span> </div>
<div class="line"><a id="l00382" name="l00382"></a><span class="lineno"> 382</span> <span class="comment">// Remove from broadcast subscriptions as well</span></div>
<div class="line"><a id="l00383" name="l00383"></a><span class="lineno"> 383</span> m_routingTable.broadcastNodeList.erase(node);</div>
<div class="line"><a id="l00384" name="l00384"></a><span class="lineno"> 384</span>}</div>
</div>
<div class="line"><a id="l00385" name="l00385"></a><span class="lineno"> 385</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00386" name="l00386"></a><span class="lineno"> 386</span><span class="comment">/* Check if a listener is subscribed to a specific event type */</span></div>
<div class="foldopen" id="foldopen00387" data-start="{" data-end="}">
<div class="line"><a id="l00387" name="l00387"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a8574031338c5bf7827cc0d561ed93171"> 387</a></span><span class="keyword">inline</span> <span class="keywordtype">bool</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a8574031338c5bf7827cc0d561ed93171">Bus::isSubscribed</a>(<span class="keyword">const</span> <a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node, <a class="code hl_typedef" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a> eventType)<span class="keyword"> const</span></div>
<div class="line"><a id="l00388" name="l00388"></a><span class="lineno"> 388</span><span class="keyword"></span>{</div>
<div class="line"><a id="l00389" name="l00389"></a><span class="lineno"> 389</span> <span class="comment">// Sanity check</span></div>
<div class="line"><a id="l00390" name="l00390"></a><span class="lineno"> 390</span> <span class="keywordflow">if</span> (!node)</div>
<div class="line"><a id="l00391" name="l00391"></a><span class="lineno"> 391</span> <span class="keywordflow">throw</span> std::runtime_error(<span class="stringliteral">&quot;invalid node handle&quot;</span>);</div>
<div class="line"><a id="l00392" name="l00392"></a><span class="lineno"> 392</span> </div>
<div class="line"><a id="l00393" name="l00393"></a><span class="lineno"> 393</span> std::scoped_lock lock(m_routingTable.mtx);</div>
<div class="line"><a id="l00394" name="l00394"></a><span class="lineno"> 394</span> </div>
<div class="line"><a id="l00395" name="l00395"></a><span class="lineno"> 395</span> <span class="comment">// Event type not recorded, node not subscribed</span></div>
<div class="line"><a id="l00396" name="l00396"></a><span class="lineno"> 396</span> <span class="keywordflow">if</span> (!m_routingTable.nodeList.contains(eventType))</div>
<div class="line"><a id="l00397" name="l00397"></a><span class="lineno"> 397</span> <span class="keywordflow">return</span> <span class="keyword">false</span>;</div>
<div class="line"><a id="l00398" name="l00398"></a><span class="lineno"> 398</span> </div>
<div class="line"><a id="l00399" name="l00399"></a><span class="lineno"> 399</span> <span class="comment">// Event type recorded, check if the node is in the list</span></div>
<div class="line"><a id="l00400" name="l00400"></a><span class="lineno"> 400</span> <span class="keyword">const</span> <span class="keyword">auto</span> &amp;nodes = m_routingTable.nodeList.at(eventType);</div>
<div class="line"><a id="l00401" name="l00401"></a><span class="lineno"> 401</span> <span class="keywordflow">return</span> std::ranges::find(nodes, node) != nodes.end();</div>
<div class="line"><a id="l00402" name="l00402"></a><span class="lineno"> 402</span>}</div>
</div>
<div class="line"><a id="l00403" name="l00403"></a><span class="lineno"> 403</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00404" name="l00404"></a><span class="lineno"> 404</span><span class="comment">/* Subscribe a node to receive all messages (broadcast mode) */</span></div>
<div class="foldopen" id="foldopen00405" data-start="{" data-end="}">
<div class="line"><a id="l00405" name="l00405"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a309bedf4b2fb78c99de024ece1f39eb5"> 405</a></span><span class="keyword">inline</span> <span class="keywordtype">void</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a309bedf4b2fb78c99de024ece1f39eb5">Bus::subscribeToBroadcast</a>(<a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node)</div>
<div class="line"><a id="l00406" name="l00406"></a><span class="lineno"> 406</span>{</div>
<div class="line"><a id="l00407" name="l00407"></a><span class="lineno"> 407</span> <span class="comment">// Sanity check</span></div>
<div class="line"><a id="l00408" name="l00408"></a><span class="lineno"> 408</span> <span class="keywordflow">if</span> (!node)</div>
<div class="line"><a id="l00409" name="l00409"></a><span class="lineno"> 409</span> <span class="keywordflow">throw</span> std::runtime_error(<span class="stringliteral">&quot;invalid node handle&quot;</span>);</div>
<div class="line"><a id="l00410" name="l00410"></a><span class="lineno"> 410</span> </div>
<div class="line"><a id="l00411" name="l00411"></a><span class="lineno"> 411</span> std::scoped_lock lock(m_routingTable.mtx);</div>
<div class="line"><a id="l00412" name="l00412"></a><span class="lineno"> 412</span> </div>
<div class="line"><a id="l00413" name="l00413"></a><span class="lineno"> 413</span> <span class="comment">// Add the node to the broadcast nodes set</span></div>
<div class="line"><a id="l00414" name="l00414"></a><span class="lineno"> 414</span> m_routingTable.broadcastNodeList.insert(node);</div>
<div class="line"><a id="l00415" name="l00415"></a><span class="lineno"> 415</span>}</div>
</div>
<div class="line"><a id="l00416" name="l00416"></a><span class="lineno"> 416</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00417" name="l00417"></a><span class="lineno"> 417</span><span class="comment">/* Unsubscribe a node from broadcast mode */</span></div>
<div class="foldopen" id="foldopen00418" data-start="{" data-end="}">
<div class="line"><a id="l00418" name="l00418"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ae9c37a95472381e33190bd951e381ebe"> 418</a></span><span class="keyword">inline</span> <span class="keywordtype">void</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ae9c37a95472381e33190bd951e381ebe">Bus::unsubscribeFromBroadcast</a>(<a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node)</div>
<div class="line"><a id="l00419" name="l00419"></a><span class="lineno"> 419</span>{</div>
<div class="line"><a id="l00420" name="l00420"></a><span class="lineno"> 420</span> <span class="comment">// Sanity check</span></div>
<div class="line"><a id="l00421" name="l00421"></a><span class="lineno"> 421</span> <span class="keywordflow">if</span> (!node)</div>
<div class="line"><a id="l00422" name="l00422"></a><span class="lineno"> 422</span> <span class="keywordflow">throw</span> std::runtime_error(<span class="stringliteral">&quot;invalid node handle&quot;</span>);</div>
<div class="line"><a id="l00423" name="l00423"></a><span class="lineno"> 423</span> </div>
<div class="line"><a id="l00424" name="l00424"></a><span class="lineno"> 424</span> std::scoped_lock lock(m_routingTable.mtx);</div>
<div class="line"><a id="l00425" name="l00425"></a><span class="lineno"> 425</span> </div>
<div class="line"><a id="l00426" name="l00426"></a><span class="lineno"> 426</span> <span class="comment">// Remove the node from the broadcast nodes set</span></div>
<div class="line"><a id="l00427" name="l00427"></a><span class="lineno"> 427</span> m_routingTable.broadcastNodeList.erase(node);</div>
<div class="line"><a id="l00428" name="l00428"></a><span class="lineno"> 428</span>}</div>
</div>
<div class="line"><a id="l00429" name="l00429"></a><span class="lineno"> 429</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00430" name="l00430"></a><span class="lineno"> 430</span><span class="comment">/* Check if a node is subscribed to broadcast mode */</span></div>
<div class="foldopen" id="foldopen00431" data-start="{" data-end="}">
<div class="line"><a id="l00431" name="l00431"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a7b375afd6d8b416cfd37e3bfce5b8ffd"> 431</a></span><span class="keyword">inline</span> <span class="keywordtype">bool</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a7b375afd6d8b416cfd37e3bfce5b8ffd">Bus::isSubscribedToBroadcast</a>(<a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node)<span class="keyword"> const</span></div>
<div class="line"><a id="l00432" name="l00432"></a><span class="lineno"> 432</span><span class="keyword"></span>{</div>
<div class="line"><a id="l00433" name="l00433"></a><span class="lineno"> 433</span> <span class="comment">// Sanity check</span></div>
<div class="line"><a id="l00434" name="l00434"></a><span class="lineno"> 434</span> <span class="keywordflow">if</span> (!node)</div>
<div class="line"><a id="l00435" name="l00435"></a><span class="lineno"> 435</span> <span class="keywordflow">throw</span> std::runtime_error(<span class="stringliteral">&quot;invalid node handle&quot;</span>);</div>
<div class="line"><a id="l00436" name="l00436"></a><span class="lineno"> 436</span> </div>
<div class="line"><a id="l00437" name="l00437"></a><span class="lineno"> 437</span> std::scoped_lock lock(m_routingTable.mtx);</div>
<div class="line"><a id="l00438" name="l00438"></a><span class="lineno"> 438</span> </div>
<div class="line"><a id="l00439" name="l00439"></a><span class="lineno"> 439</span> <span class="comment">// Check if the node is in the broadcast nodes set</span></div>
<div class="line"><a id="l00440" name="l00440"></a><span class="lineno"> 440</span> <span class="keywordflow">return</span> m_routingTable.broadcastNodeList.contains(node);</div>
<div class="line"><a id="l00441" name="l00441"></a><span class="lineno"> 441</span>}</div>
</div>
<div class="line"><a id="l00442" name="l00442"></a><span class="lineno"> 442</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00443" name="l00443"></a><span class="lineno"> 443</span><span class="comment">/* Emit a message of type T with the given arguments(create a message and post it to the bus) */</span></div>
<div class="line"><a id="l00444" name="l00444"></a><span class="lineno"> 444</span><span class="keyword">template</span>&lt;<span class="keyword">class </span>T, <span class="keyword">class</span>... Args&gt;</div>
<div class="foldopen" id="foldopen00445" data-start="{" data-end="}">
<div class="line"><a id="l00445" name="l00445"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a9aab57a60533a1a80a705bc569a9c589"> 445</a></span><span class="keywordtype">bool</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a9aab57a60533a1a80a705bc569a9c589">Bus::emit</a>(Args &amp;&amp;...args)</div>
<div class="line"><a id="l00446" name="l00446"></a><span class="lineno"> 446</span>{</div>
<div class="line"><a id="l00447" name="l00447"></a><span class="lineno"> 447</span> <span class="keyword">static_assert</span>(std::derived_from&lt;T, Message&gt;, <span class="stringliteral">&quot;T must be derived from IMessage&quot;</span>);</div>
<div class="line"><a id="l00448" name="l00448"></a><span class="lineno"> 448</span> </div>
<div class="line"><a id="l00449" name="l00449"></a><span class="lineno"> 449</span> <span class="comment">// Create a message of type T with the given arguments</span></div>
<div class="line"><a id="l00450" name="l00450"></a><span class="lineno"> 450</span> <span class="keyword">auto</span> message = std::make_shared&lt;T&gt;(std::forward&lt;Args&gt;(args)...);</div>
<div class="line"><a id="l00451" name="l00451"></a><span class="lineno"> 451</span> </div>
<div class="line"><a id="l00452" name="l00452"></a><span class="lineno"> 452</span> <span class="comment">// Post the message to the bus</span></div>
<div class="line"><a id="l00453" name="l00453"></a><span class="lineno"> 453</span> <span class="keywordflow">return</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a92c2bc8aa8bcf018ffe954a3e8e34324">post</a>(message);</div>
<div class="line"><a id="l00454" name="l00454"></a><span class="lineno"> 454</span>}</div>
</div>
<div class="line"><a id="l00455" name="l00455"></a><span class="lineno"> 455</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00456" name="l00456"></a><span class="lineno"> 456</span><span class="comment">/* Post a message to the bus */</span></div>
<div class="foldopen" id="foldopen00457" data-start="{" data-end="}">
<div class="line"><a id="l00457" name="l00457"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a92c2bc8aa8bcf018ffe954a3e8e34324"> 457</a></span><span class="keyword">inline</span> <span class="keywordtype">bool</span> <a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a92c2bc8aa8bcf018ffe954a3e8e34324">Bus::post</a>(<span class="keyword">const</span> std::shared_ptr&lt;Message&gt; &amp;message)<span class="keyword"> const</span></div>
<div class="line"><a id="l00458" name="l00458"></a><span class="lineno"> 458</span><span class="keyword"></span>{</div>
<div class="line"><a id="l00459" name="l00459"></a><span class="lineno"> 459</span> std::scoped_lock lock(m_routingTable.mtx);</div>
<div class="line"><a id="l00460" name="l00460"></a><span class="lineno"> 460</span> </div>
<div class="line"><a id="l00461" name="l00461"></a><span class="lineno"> 461</span> <span class="comment">// Update message state</span></div>
<div class="line"><a id="l00462" name="l00462"></a><span class="lineno"> 462</span> message-&gt;updateTimestamp(); <span class="comment">// Update the timestamp of when the message was posted to the bus</span></div>
<div class="line"><a id="l00463" name="l00463"></a><span class="lineno"> 463</span> </div>
<div class="line"><a id="l00464" name="l00464"></a><span class="lineno"> 464</span> <span class="comment">// Post the message to all subscribers of the specific</span></div>
<div class="line"><a id="l00465" name="l00465"></a><span class="lineno"> 465</span> <span class="comment">// message type and get the number of subscribers that</span></div>
<div class="line"><a id="l00466" name="l00466"></a><span class="lineno"> 466</span> <span class="comment">// received the message</span></div>
<div class="line"><a id="l00467" name="l00467"></a><span class="lineno"> 467</span> <span class="keyword">const</span> <span class="keyword">auto</span> subscriberCount = postMessageToSubscribers(message-&gt;getMessageTypeID(), message);</div>
<div class="line"><a id="l00468" name="l00468"></a><span class="lineno"> 468</span> </div>
<div class="line"><a id="l00469" name="l00469"></a><span class="lineno"> 469</span> <span class="comment">// Post the message to all broadcast subscribers and</span></div>
<div class="line"><a id="l00470" name="l00470"></a><span class="lineno"> 470</span> <span class="comment">// get the number of subscribers that received the</span></div>
<div class="line"><a id="l00471" name="l00471"></a><span class="lineno"> 471</span> <span class="comment">// message</span></div>
<div class="line"><a id="l00472" name="l00472"></a><span class="lineno"> 472</span> (void)postMessageToBroadcastSubscribers(message);</div>
<div class="line"><a id="l00473" name="l00473"></a><span class="lineno"> 473</span> </div>
<div class="line"><a id="l00474" name="l00474"></a><span class="lineno"> 474</span> <span class="keywordflow">return</span> subscriberCount &gt; 0;</div>
<div class="line"><a id="l00475" name="l00475"></a><span class="lineno"> 475</span>}</div>
</div>
<div class="line"><a id="l00476" name="l00476"></a><span class="lineno"> 476</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00477" name="l00477"></a><span class="lineno"> 477</span><span class="comment">/* Post a message to all subscribers of a specific event type and return the number of subscribers that received the message */</span></div>
<div class="line"><a id="l00478" name="l00478"></a><span class="lineno"> 478</span><span class="keyword">inline</span> <span class="keywordtype">size_t</span> Bus::postMessageToSubscribers(<span class="keyword">const</span> <a class="code hl_typedef" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a> eventType, <span class="keyword">const</span> std::shared_ptr&lt;Message&gt; &amp;message)<span class="keyword"> const</span></div>
<div class="line"><a id="l00479" name="l00479"></a><span class="lineno"> 479</span><span class="keyword"></span>{</div>
<div class="line"><a id="l00480" name="l00480"></a><span class="lineno"> 480</span> <span class="keyword">const</span> <span class="keyword">auto</span> subscriberList = getSubscribersForMessageType(eventType);</div>
<div class="line"><a id="l00481" name="l00481"></a><span class="lineno"> 481</span> <span class="keywordflow">if</span> (!subscriberList)</div>
<div class="line"><a id="l00482" name="l00482"></a><span class="lineno"> 482</span> <span class="keywordflow">return</span> 0;</div>
<div class="line"><a id="l00483" name="l00483"></a><span class="lineno"> 483</span> </div>
<div class="line"><a id="l00484" name="l00484"></a><span class="lineno"> 484</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keyword">auto</span> &amp;node : *subscriberList)</div>
<div class="line"><a id="l00485" name="l00485"></a><span class="lineno"> 485</span> node-&gt;append(message);</div>
<div class="line"><a id="l00486" name="l00486"></a><span class="lineno"> 486</span> </div>
<div class="line"><a id="l00487" name="l00487"></a><span class="lineno"> 487</span> <span class="keywordflow">return</span> subscriberList-&gt;size();</div>
<div class="line"><a id="l00488" name="l00488"></a><span class="lineno"> 488</span>}</div>
<div class="line"><a id="l00489" name="l00489"></a><span class="lineno"> 489</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00490" name="l00490"></a><span class="lineno"> 490</span><span class="comment">/* Post a message to all broadcast subscribers and return the number of subscribers that received the message */</span></div>
<div class="line"><a id="l00491" name="l00491"></a><span class="lineno"> 491</span><span class="keyword">inline</span> <span class="keywordtype">size_t</span> Bus::postMessageToBroadcastSubscribers(<span class="keyword">const</span> std::shared_ptr&lt;Message&gt; &amp;message)<span class="keyword"> const</span></div>
<div class="line"><a id="l00492" name="l00492"></a><span class="lineno"> 492</span><span class="keyword"></span>{</div>
<div class="line"><a id="l00493" name="l00493"></a><span class="lineno"> 493</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keyword">auto</span> &amp;node : m_routingTable.<a class="code hl_variable" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a3c682b9a6b53418d7a147960e6dcdad1">broadcastNodeList</a>)</div>
<div class="line"><a id="l00494" name="l00494"></a><span class="lineno"> 494</span> node-&gt;append(message);</div>
<div class="line"><a id="l00495" name="l00495"></a><span class="lineno"> 495</span> </div>
<div class="line"><a id="l00496" name="l00496"></a><span class="lineno"> 496</span> <span class="keywordflow">return</span> m_routingTable.broadcastNodeList.size();</div>
<div class="line"><a id="l00497" name="l00497"></a><span class="lineno"> 497</span>}</div>
<div class="line"><a id="l00498" name="l00498"></a><span class="lineno"> 498</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00499" name="l00499"></a><span class="lineno"> 499</span><span class="comment">/* Get the list of subscribers for a specific message type */</span></div>
<div class="line"><a id="l00500" name="l00500"></a><span class="lineno"> 500</span><span class="keyword">inline</span> <span class="keyword">const</span> Bus::VectorNode *Bus::getSubscribersForMessageType(<span class="keyword">const</span> <a class="code hl_typedef" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a> messageType)<span class="keyword"> const</span></div>
<div class="line"><a id="l00501" name="l00501"></a><span class="lineno"> 501</span><span class="keyword"></span>{</div>
<div class="line"><a id="l00502" name="l00502"></a><span class="lineno"> 502</span> <span class="keywordflow">if</span> (!m_routingTable.nodeList.contains(messageType))</div>
<div class="line"><a id="l00503" name="l00503"></a><span class="lineno"> 503</span> <span class="keywordflow">return</span> <span class="keyword">nullptr</span>; <span class="comment">// No subscribers for this message type</span></div>
<div class="line"><a id="l00504" name="l00504"></a><span class="lineno"> 504</span> </div>
<div class="line"><a id="l00505" name="l00505"></a><span class="lineno"> 505</span> <span class="keywordflow">return</span> &amp;m_routingTable.nodeList.at(messageType);</div>
<div class="line"><a id="l00506" name="l00506"></a><span class="lineno"> 506</span>}</div>
<div class="line"><a id="l00507" name="l00507"></a><span class="lineno"> 507</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00508" name="l00508"></a><span class="lineno"> 508</span>} <span class="comment">// namespace sdi_toolBox::desktop::eventBus</span></div>
</div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">sdi_toolBox::desktop::eventBus::Bus</a></div><div class="ttdoc">Central message dispatcher for the event bus system.</div><div class="ttdef"><b>Definition</b> <a href="bus_8h_source.html#l00062">bus.h:63</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html_a27cc2e333f174e22b360045c7aad959d"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a27cc2e333f174e22b360045c7aad959d">sdi_toolBox::desktop::eventBus::Bus::unsubscribe</a></div><div class="ttdeci">void unsubscribe(INode *node, MessageTypeID eventType)</div><div class="ttdoc">Unsubscribe a node from a specific message type.</div><div class="ttdef"><b>Definition</b> <a href="bus_8h_source.html#l00352">bus.h:352</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html_a29358764c7d91cfcf3447e93b43bb20f"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a29358764c7d91cfcf3447e93b43bb20f">sdi_toolBox::desktop::eventBus::Bus::Bus</a></div><div class="ttdeci">Bus()</div><div class="ttdoc">Default constructor.</div><div class="ttdef"><b>Definition</b> <a href="bus_8h_source.html#l00312">bus.h:312</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html_a309bedf4b2fb78c99de024ece1f39eb5"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a309bedf4b2fb78c99de024ece1f39eb5">sdi_toolBox::desktop::eventBus::Bus::subscribeToBroadcast</a></div><div class="ttdeci">void subscribeToBroadcast(INode *node)</div><div class="ttdoc">Subscribe a node to broadcast mode.</div><div class="ttdef"><b>Definition</b> <a href="bus_8h_source.html#l00405">bus.h:405</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html_a3c682b9a6b53418d7a147960e6dcdad1"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a3c682b9a6b53418d7a147960e6dcdad1">sdi_toolBox::desktop::eventBus::Bus::broadcastNodeList</a></div><div class="ttdeci">std::set&lt; INode * &gt; broadcastNodeList</div><div class="ttdoc">Set of nodes subscribed to receive all messages (broadcast mode)</div><div class="ttdef"><b>Definition</b> <a href="bus_8h_source.html#l00305">bus.h:305</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html_a422f08b55d205f02a11025e753679555"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a422f08b55d205f02a11025e753679555">sdi_toolBox::desktop::eventBus::Bus::Bus</a></div><div class="ttdeci">Bus(Bus &amp;&amp;obj) noexcept=delete</div><div class="ttdoc">Move constructor - deleted.</div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html_a472403c9840a1d19c264c55f00070a3e"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a472403c9840a1d19c264c55f00070a3e">sdi_toolBox::desktop::eventBus::Bus::Bus</a></div><div class="ttdeci">Bus(const Bus &amp;obj)=delete</div><div class="ttdoc">Copy constructor - deleted.</div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html_a4bc64bd8db5527dc8af9b458a82d6a65"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a4bc64bd8db5527dc8af9b458a82d6a65">sdi_toolBox::desktop::eventBus::Bus::nodeList</a></div><div class="ttdeci">std::unordered_map&lt; MessageTypeID, VectorNode &gt; nodeList</div><div class="ttdoc">Map of message type IDs to lists of subscribed nodes.</div><div class="ttdef"><b>Definition</b> <a href="bus_8h_source.html#l00304">bus.h:304</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html_a7b375afd6d8b416cfd37e3bfce5b8ffd"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a7b375afd6d8b416cfd37e3bfce5b8ffd">sdi_toolBox::desktop::eventBus::Bus::isSubscribedToBroadcast</a></div><div class="ttdeci">bool isSubscribedToBroadcast(INode *node) const</div><div class="ttdoc">Check whether a node is subscribed to broadcast mode.</div><div class="ttdef"><b>Definition</b> <a href="bus_8h_source.html#l00431">bus.h:431</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html_a8574031338c5bf7827cc0d561ed93171"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a8574031338c5bf7827cc0d561ed93171">sdi_toolBox::desktop::eventBus::Bus::isSubscribed</a></div><div class="ttdeci">bool isSubscribed(const INode *node, MessageTypeID eventType) const</div><div class="ttdoc">Check whether a node is subscribed to a specific message type.</div><div class="ttdef"><b>Definition</b> <a href="bus_8h_source.html#l00387">bus.h:387</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html_a92c2bc8aa8bcf018ffe954a3e8e34324"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a92c2bc8aa8bcf018ffe954a3e8e34324">sdi_toolBox::desktop::eventBus::Bus::post</a></div><div class="ttdeci">bool post(const std::shared_ptr&lt; Message &gt; &amp;message) const</div><div class="ttdoc">Post an already constructed message to the bus.</div><div class="ttdef"><b>Definition</b> <a href="bus_8h_source.html#l00457">bus.h:457</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html_a9aab57a60533a1a80a705bc569a9c589"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a9aab57a60533a1a80a705bc569a9c589">sdi_toolBox::desktop::eventBus::Bus::emit</a></div><div class="ttdeci">bool emit(Args &amp;&amp;...args)</div><div class="ttdoc">Construct and emit a message of type T to the bus.</div><div class="ttdef"><b>Definition</b> <a href="bus_8h_source.html#l00445">bus.h:445</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html_aaed1ce9185dbc68270991a68901e1d3e"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#aaed1ce9185dbc68270991a68901e1d3e">sdi_toolBox::desktop::eventBus::Bus::subscribe</a></div><div class="ttdeci">void subscribe(INode *node, MessageTypeID eventType)</div><div class="ttdoc">Subscribe a node to a specific message type.</div><div class="ttdef"><b>Definition</b> <a href="bus_8h_source.html#l00328">bus.h:328</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html_aaf1361cfa73ea4f24a5182e4aaf7f6e3"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#aaf1361cfa73ea4f24a5182e4aaf7f6e3">sdi_toolBox::desktop::eventBus::Bus::~Bus</a></div><div class="ttdeci">~Bus()=default</div><div class="ttdoc">Default destructor.</div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html_ab06a20c7848eddbcc910d5b03ea98f20"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ab06a20c7848eddbcc910d5b03ea98f20">sdi_toolBox::desktop::eventBus::Bus::clearAllSubscriptions</a></div><div class="ttdeci">void clearAllSubscriptions()</div><div class="ttdoc">Remove all subscriptions from the routing table.</div><div class="ttdef"><b>Definition</b> <a href="bus_8h_source.html#l00319">bus.h:319</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html_ad0f453f147d8e394a5b66b8494564a82"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ad0f453f147d8e394a5b66b8494564a82">sdi_toolBox::desktop::eventBus::Bus::operator=</a></div><div class="ttdeci">Bus &amp; operator=(Bus &amp;&amp;obj) noexcept=delete</div><div class="ttdoc">Move assignment operator - deleted.</div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html_ad5e0dbd36f0d71fce9b00b7f991b2f38"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ad5e0dbd36f0d71fce9b00b7f991b2f38">sdi_toolBox::desktop::eventBus::Bus::mtx</a></div><div class="ttdeci">std::mutex mtx</div><div class="ttdoc">Mutex for thread-safe access to the nodes map.</div><div class="ttdef"><b>Definition</b> <a href="bus_8h_source.html#l00303">bus.h:303</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html_ae9c37a95472381e33190bd951e381ebe"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ae9c37a95472381e33190bd951e381ebe">sdi_toolBox::desktop::eventBus::Bus::unsubscribeFromBroadcast</a></div><div class="ttdeci">void unsubscribeFromBroadcast(INode *node)</div><div class="ttdoc">Unsubscribe a node from broadcast mode.</div><div class="ttdef"><b>Definition</b> <a href="bus_8h_source.html#l00418">bus.h:418</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html_af42df59cac80896d270e4bf2b350676f"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#af42df59cac80896d270e4bf2b350676f">sdi_toolBox::desktop::eventBus::Bus::unsubscribeFromAll</a></div><div class="ttdeci">void unsubscribeFromAll(INode *node)</div><div class="ttdoc">Unsubscribe a node from all message types and broadcast mode.</div><div class="ttdef"><b>Definition</b> <a href="bus_8h_source.html#l00370">bus.h:370</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html_afc5179367040f25bcdb4e27d5682168b"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#afc5179367040f25bcdb4e27d5682168b">sdi_toolBox::desktop::eventBus::Bus::operator=</a></div><div class="ttdeci">Bus &amp; operator=(const Bus &amp;obj)=delete</div><div class="ttdoc">Copy assignment operator - deleted.</div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1INode_html"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">sdi_toolBox::desktop::eventBus::INode</a></div><div class="ttdoc">Abstract interface representing a subscriber node in the event bus system.</div><div class="ttdef"><b>Definition</b> <a href="inode_8h_source.html#l00041">inode.h:42</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Node_html"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">sdi_toolBox::desktop::eventBus::Node</a></div><div class="ttdoc">Concrete subscriber node in the event bus system.</div><div class="ttdef"><b>Definition</b> <a href="node_8h_source.html#l00063">node.h:64</a></div></div>
<div class="ttc" id="adefs_8h_html"><div class="ttname"><a href="defs_8h.html">defs.h</a></div></div>
<div class="ttc" id="ainode_8h_html"><div class="ttname"><a href="inode_8h.html">inode.h</a></div></div>
<div class="ttc" id="amessage_8h_html"><div class="ttname"><a href="message_8h.html">message.h</a></div></div>
<div class="ttc" id="anamespacesdi__toolBox_1_1desktop_1_1eventBus_html"><div class="ttname"><a href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html">sdi_toolBox::desktop::eventBus</a></div><div class="ttdoc">Lightweight thread-safe event bus for decoupled message passing.</div><div class="ttdef"><b>Definition</b> <a href="bus_8h_source.html#l00026">bus.h:27</a></div></div>
<div class="ttc" id="anamespacesdi__toolBox_1_1desktop_1_1eventBus_html_a9a6bed6d55e3ccf6e4b27ebfa879277c"><div class="ttname"><a href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">sdi_toolBox::desktop::eventBus::MessageTypeID</a></div><div class="ttdeci">uint64_t MessageTypeID</div><div class="ttdoc">Unique identifier for a message type.</div><div class="ttdef"><b>Definition</b> <a href="defs_8h_source.html#l00021">defs.h:21</a></div></div>
<div class="ttc" id="anamespacesdi__toolBox_1_1desktop_1_1eventBus_html_ae5ca775e8d8c664b6edef818ce1251b9"><div class="ttname"><a href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#ae5ca775e8d8c664b6edef818ce1251b9">sdi_toolBox::desktop::eventBus::TimePoint</a></div><div class="ttdeci">std::chrono::steady_clock::time_point TimePoint</div><div class="ttdoc">Monotonic timestamp type used throughout the event bus.</div><div class="ttdef"><b>Definition</b> <a href="defs_8h_source.html#l00022">defs.h:22</a></div></div>
</div><!-- fragment --></div><!-- contents -->
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
SDi toolsBox is licensed under the terms and conditions of the <a href="https://opensource.org/licenses/zlib-license.php" target="_blank">zlib/png license</a>
<br />
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE | ver: 2.x.x - build: 2026-04-28
<br />
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen" /></a> 1.9.8
</small>
</address>
</body>

View File

@@ -0,0 +1,105 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>SDi toolsBox</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="custom_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">sdi_toolBox
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',false,false,'search.php','Search');
});
/* @license-end */
</script>
<div id="main-nav"></div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_1635ad76f8180971a36e709fb0d71e5a.html">toolBox</a></li><li class="navelem"><a class="el" href="dir_a330ae4cda0dd4c6ab0e77aa921b4b70.html">sdi_toolBox</a></li><li class="navelem"><a class="el" href="dir_54865fdb36137c23be3687ea6e83f837.html">common</a></li><li class="navelem"><a class="el" href="dir_d0c2fb49d0db32828bce9490aff92f8c.html">utils</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="summary">
<a href="#nested-classes">Classes</a> &#124;
<a href="#namespaces">Namespaces</a> </div>
<div class="headertitle"><div class="title">circularBuffer.h File Reference</div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><code>#include &quot;<a class="el" href="ringBuffer_8h_source.html">ringBuffer.h</a>&quot;</code><br />
</div><div class="textblock"><div class="dynheader">
Include dependency graph for circularBuffer.h:</div>
<div class="dyncontent">
<div class="center"><img src="circularBuffer_8h__incl.png" border="0" usemap="#acircularBuffer_8h" alt=""/></div>
<map name="acircularBuffer_8h" id="acircularBuffer_8h">
<area shape="rect" title=" " alt="" coords="61,5,181,31"/>
<area shape="rect" href="ringBuffer_8h.html" title=" " alt="" coords="73,79,170,104"/>
<area shape="poly" title=" " alt="" coords="124,31,124,65,119,65,119,31"/>
<area shape="rect" title=" " alt="" coords="5,152,61,177"/>
<area shape="poly" title=" " alt="" coords="109,106,60,145,57,141,106,102"/>
<area shape="rect" title=" " alt="" coords="86,152,157,177"/>
<area shape="poly" title=" " alt="" coords="124,104,124,138,119,138,119,104"/>
<area shape="rect" title=" " alt="" coords="181,152,256,177"/>
<area shape="poly" title=" " alt="" coords="139,102,193,141,190,146,135,106"/>
</map>
</div>
</div>
<p><a href="circularBuffer_8h_source.html">Go to the source code of this file.</a></p>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="nested-classes" name="nested-classes"></a>
Classes</h2></td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">CircularBuffer&lt; T, CAPACITY &gt;</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Fixed-size circular buffer with compile-time capacity and no-overwrite behavior. <a href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="namespaces" name="namespaces"></a>
Namespaces</h2></td></tr>
<tr class="memitem:namespacesdi__toolBox" id="r_namespacesdi__toolBox"><td class="memItemLeft" align="right" valign="top">namespace &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespacesdi__toolBox.html">sdi_toolBox</a></td></tr>
<tr class="memdesc:namespacesdi__toolBox"><td class="mdescLeft">&#160;</td><td class="mdescRight">Root namespace for the <a class="el" href="namespacesdi__toolBox.html" title="Root namespace for the sdi_toolBox library.">sdi_toolBox</a> library. <br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:namespacesdi__toolBox_1_1common" id="r_namespacesdi__toolBox_1_1common"><td class="memItemLeft" align="right" valign="top">namespace &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespacesdi__toolBox_1_1common.html">sdi_toolBox::common</a></td></tr>
<tr class="memdesc:namespacesdi__toolBox_1_1common"><td class="mdescLeft">&#160;</td><td class="mdescRight">Cross-platform, reusable components shared across all <a class="el" href="namespacesdi__toolBox.html" title="Root namespace for the sdi_toolBox library.">sdi_toolBox</a> modules. <br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:namespacesdi__toolBox_1_1common_1_1utils" id="r_namespacesdi__toolBox_1_1common_1_1utils"><td class="memItemLeft" align="right" valign="top">namespace &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespacesdi__toolBox_1_1common_1_1utils.html">sdi_toolBox::common::utils</a></td></tr>
<tr class="memdesc:namespacesdi__toolBox_1_1common_1_1utils"><td class="mdescLeft">&#160;</td><td class="mdescRight">General-purpose utility functions shared across all <a class="el" href="namespacesdi__toolBox.html" title="Root namespace for the sdi_toolBox library.">sdi_toolBox</a> modules. <br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
</div><!-- contents -->
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
SDi toolsBox is licensed under the terms and conditions of the <a href="https://opensource.org/licenses/zlib-license.php" target="_blank">zlib/png license</a>
<br />
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE | ver: 2.x.x - build: 2026-04-28
<br />
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen" /></a> 1.9.8
</small>
</address>
</body>
</html>

View File

@@ -0,0 +1,11 @@
<map id="circularBuffer.h" name="circularBuffer.h">
<area shape="rect" id="Node000001" title=" " alt="" coords="61,5,181,31"/>
<area shape="rect" id="Node000002" href="$ringBuffer_8h.html" title=" " alt="" coords="73,79,170,104"/>
<area shape="poly" id="edge1_Node000001_Node000002" title=" " alt="" coords="124,31,124,65,119,65,119,31"/>
<area shape="rect" id="Node000003" title=" " alt="" coords="5,152,61,177"/>
<area shape="poly" id="edge2_Node000002_Node000003" title=" " alt="" coords="109,106,60,145,57,141,106,102"/>
<area shape="rect" id="Node000004" title=" " alt="" coords="86,152,157,177"/>
<area shape="poly" id="edge3_Node000002_Node000004" title=" " alt="" coords="124,104,124,138,119,138,119,104"/>
<area shape="rect" id="Node000005" title=" " alt="" coords="181,152,256,177"/>
<area shape="poly" id="edge4_Node000002_Node000005" title=" " alt="" coords="139,102,193,141,190,146,135,106"/>
</map>

View File

@@ -0,0 +1 @@
b3a7e7800538a8e553aae8f89d98a2de

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@@ -0,0 +1,288 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>SDi toolsBox</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="custom_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">sdi_toolBox
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',false,false,'search.php','Search');
});
/* @license-end */
</script>
<div id="main-nav"></div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(document).ready(function() { init_codefold(0); });
/* @license-end */
</script>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_1635ad76f8180971a36e709fb0d71e5a.html">toolBox</a></li><li class="navelem"><a class="el" href="dir_a330ae4cda0dd4c6ab0e77aa921b4b70.html">sdi_toolBox</a></li><li class="navelem"><a class="el" href="dir_54865fdb36137c23be3687ea6e83f837.html">common</a></li><li class="navelem"><a class="el" href="dir_d0c2fb49d0db32828bce9490aff92f8c.html">utils</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle"><div class="title">circularBuffer.h</div></div>
</div><!--header-->
<div class="contents">
<a href="circularBuffer_8h.html">Go to the documentation of this file.</a><div class="fragment"><div class="line"><a id="l00001" name="l00001"></a><span class="lineno"> 1</span><span class="comment">/*</span></div>
<div class="line"><a id="l00002" name="l00002"></a><span class="lineno"> 2</span><span class="comment"> Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE</span></div>
<div class="line"><a id="l00003" name="l00003"></a><span class="lineno"> 3</span><span class="comment">*/</span></div>
<div class="line"><a id="l00004" name="l00004"></a><span class="lineno"> 4</span> </div>
<div class="line"><a id="l00005" name="l00005"></a><span class="lineno"> 5</span><span class="comment">/*</span></div>
<div class="line"><a id="l00006" name="l00006"></a><span class="lineno"> 6</span><span class="comment">ver: 2.x.x - build: 2026-04-28</span></div>
<div class="line"><a id="l00007" name="l00007"></a><span class="lineno"> 7</span><span class="comment">*/</span></div>
<div class="line"><a id="l00008" name="l00008"></a><span class="lineno"> 8</span> </div>
<div class="line"><a id="l00009" name="l00009"></a><span class="lineno"> 9</span><span class="comment">/*</span></div>
<div class="line"><a id="l00010" name="l00010"></a><span class="lineno"> 10</span><span class="comment">The zlib License
Copyright (c) 2026 SD-Innovation S.A.S.
This software is provided as-is, without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
</span></div>
<div class="line"><a id="l00011" name="l00011"></a><span class="lineno"> 11</span><span class="comment">*/</span></div>
<div class="line"><a id="l00012" name="l00012"></a><span class="lineno"> 12</span> </div>
<div class="line"><a id="l00013" name="l00013"></a><span class="lineno"> 13</span><span class="preprocessor">#pragma once</span></div>
<div class="line"><a id="l00014" name="l00014"></a><span class="lineno"> 14</span> </div>
<div class="line"><a id="l00015" name="l00015"></a><span class="lineno"> 15</span><span class="preprocessor">#include &quot;<a class="code" href="ringBuffer_8h.html">ringBuffer.h</a>&quot;</span></div>
<div class="line"><a id="l00016" name="l00016"></a><span class="lineno"> 16</span> </div>
<div class="foldopen" id="foldopen00017" data-start="{" data-end="}">
<div class="line"><a id="l00017" name="l00017"></a><span class="lineno"><a class="line" href="namespacesdi__toolBox.html"> 17</a></span><span class="keyword">namespace </span><a class="code hl_namespace" href="namespacesdi__toolBox_1_1common_1_1utils.html">sdi_toolBox::common::utils</a></div>
<div class="line"><a id="l00018" name="l00018"></a><span class="lineno"> 18</span>{</div>
<div class="line"><a id="l00019" name="l00019"></a><span class="lineno"> 19</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00047" name="l00047"></a><span class="lineno"> 47</span><span class="keyword">template</span>&lt;<span class="keyword">class</span> T, std::<span class="keywordtype">size_t</span> CAPACITY&gt;</div>
<div class="foldopen" id="foldopen00048" data-start="{" data-end="};">
<div class="line"><a id="l00048" name="l00048"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html"> 48</a></span><span class="keyword">class </span><a class="code hl_class" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">CircularBuffer</a></div>
<div class="line"><a id="l00049" name="l00049"></a><span class="lineno"> 49</span>{</div>
<div class="line"><a id="l00050" name="l00050"></a><span class="lineno"> 50</span> <span class="keyword">static_assert</span>(CAPACITY &gt; 0, <span class="stringliteral">&quot;CAPACITY must be &gt; 0&quot;</span>);</div>
<div class="line"><a id="l00051" name="l00051"></a><span class="lineno"> 51</span> </div>
<div class="line"><a id="l00052" name="l00052"></a><span class="lineno"> 52</span> <span class="keyword">public</span>:</div>
<div class="line"><a id="l00055" name="l00055"></a><span class="lineno"> 55</span> </div>
<div class="line"><a id="l00064" name="l00064"></a><span class="lineno"> 64</span> <span class="keywordtype">bool</span> <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a1e934fd7dc8ba5c9d3e59522f05c67f8">push</a>(<span class="keyword">const</span> T &amp;value);</div>
<div class="line"><a id="l00065" name="l00065"></a><span class="lineno"> 65</span> </div>
<div class="line"><a id="l00069" name="l00069"></a><span class="lineno"> 69</span> </div>
<div class="line"><a id="l00076" name="l00076"></a><span class="lineno"> 76</span> std::optional&lt;T&gt; <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a44a53147d4b3600ec200300ea16e3707">pop</a>();</div>
<div class="line"><a id="l00084" name="l00084"></a><span class="lineno"> 84</span> <span class="keywordtype">bool</span> <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a44a53147d4b3600ec200300ea16e3707">pop</a>(T &amp;value);</div>
<div class="line"><a id="l00085" name="l00085"></a><span class="lineno"> 85</span> </div>
<div class="line"><a id="l00091" name="l00091"></a><span class="lineno"> 91</span> [[nodiscard]] std::optional&lt;T&gt; <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a0920f451034bda88271b5f69bd324f5e">front</a>() <span class="keyword">const</span>;</div>
<div class="line"><a id="l00092" name="l00092"></a><span class="lineno"> 92</span> </div>
<div class="line"><a id="l00100" name="l00100"></a><span class="lineno"> 100</span> [[nodiscard]] <span class="keywordtype">bool</span> <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a0920f451034bda88271b5f69bd324f5e">front</a>(T &amp;value) <span class="keyword">const</span>;</div>
<div class="line"><a id="l00101" name="l00101"></a><span class="lineno"> 101</span> </div>
<div class="line"><a id="l00107" name="l00107"></a><span class="lineno"> 107</span> [[nodiscard]] std::optional&lt;T&gt; <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ab663c689eb6ec5369a0c6e33dfdee729">back</a>() <span class="keyword">const</span>;</div>
<div class="line"><a id="l00108" name="l00108"></a><span class="lineno"> 108</span> </div>
<div class="line"><a id="l00116" name="l00116"></a><span class="lineno"> 116</span> [[nodiscard]] <span class="keywordtype">bool</span> <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ab663c689eb6ec5369a0c6e33dfdee729">back</a>(T &amp;value) <span class="keyword">const</span>;</div>
<div class="line"><a id="l00117" name="l00117"></a><span class="lineno"> 117</span> </div>
<div class="line"><a id="l00121" name="l00121"></a><span class="lineno"> 121</span> </div>
<div class="line"><a id="l00127" name="l00127"></a><span class="lineno"> 127</span> [[nodiscard]] <span class="keywordtype">bool</span> <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a644718bb2fb240de962dc3c9a1fdf0dc">empty</a>() <span class="keyword">const</span>;</div>
<div class="line"><a id="l00128" name="l00128"></a><span class="lineno"> 128</span> </div>
<div class="line"><a id="l00134" name="l00134"></a><span class="lineno"> 134</span> [[nodiscard]] <span class="keywordtype">bool</span> <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a8abf3cf65268916fe1f1660fd9efd90a">full</a>() <span class="keyword">const</span>;</div>
<div class="line"><a id="l00135" name="l00135"></a><span class="lineno"> 135</span> </div>
<div class="line"><a id="l00141" name="l00141"></a><span class="lineno"> 141</span> [[nodiscard]] std::size_t <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ade1601ccf1fa3bcf050867f0852ca4e5">size</a>() <span class="keyword">const</span>;</div>
<div class="line"><a id="l00142" name="l00142"></a><span class="lineno"> 142</span> </div>
<div class="line"><a id="l00148" name="l00148"></a><span class="lineno"> 148</span> [[nodiscard]] <span class="keyword">constexpr</span> std::size_t <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#adf1df7795354fd1fb99cb89bd54c4f93">capacity</a>() <span class="keyword">const</span>;</div>
<div class="line"><a id="l00149" name="l00149"></a><span class="lineno"> 149</span> </div>
<div class="line"><a id="l00153" name="l00153"></a><span class="lineno"> 153</span> </div>
<div class="line"><a id="l00159" name="l00159"></a><span class="lineno"> 159</span> <span class="keywordtype">void</span> <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ac8bb3912a3ce86b15842e79d0b421204">clear</a>();</div>
<div class="line"><a id="l00160" name="l00160"></a><span class="lineno"> 160</span> </div>
<div class="line"><a id="l00162" name="l00162"></a><span class="lineno"> 162</span> </div>
<div class="line"><a id="l00163" name="l00163"></a><span class="lineno"> 163</span> <span class="keyword">private</span>:</div>
<div class="line"><a id="l00166" name="l00166"></a><span class="lineno"> 166</span> </div>
<div class="line"><a id="l00167" name="l00167"></a><span class="lineno"> 167</span> <a class="code hl_class" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html">RingBuffer&lt;T, CAPACITY&gt;</a> m_buffer{}; </div>
<div class="line"><a id="l00168" name="l00168"></a><span class="lineno"> 168</span> </div>
<div class="line"><a id="l00170" name="l00170"></a><span class="lineno"> 170</span>};</div>
</div>
<div class="line"><a id="l00171" name="l00171"></a><span class="lineno"> 171</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00172" name="l00172"></a><span class="lineno"> 172</span> </div>
<div class="line"><a id="l00173" name="l00173"></a><span class="lineno"> 173</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00174" name="l00174"></a><span class="lineno"> 174</span><span class="comment">/* Try to append a value to the buffer. If the buffer is full,</span></div>
<div class="line"><a id="l00175" name="l00175"></a><span class="lineno"> 175</span><span class="comment"> * the value is discarded. Return true if the value was inserted,</span></div>
<div class="line"><a id="l00176" name="l00176"></a><span class="lineno"> 176</span><span class="comment"> * false if the buffer was full. */</span></div>
<div class="line"><a id="l00177" name="l00177"></a><span class="lineno"> 177</span><span class="keyword">template</span>&lt;<span class="keyword">class</span> T, std::<span class="keywordtype">size_t</span> CAPACITY&gt;</div>
<div class="foldopen" id="foldopen00178" data-start="{" data-end="}">
<div class="line"><a id="l00178" name="l00178"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a1e934fd7dc8ba5c9d3e59522f05c67f8"> 178</a></span><span class="keywordtype">bool</span> <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a1e934fd7dc8ba5c9d3e59522f05c67f8">CircularBuffer&lt;T, CAPACITY&gt;::push</a>(<span class="keyword">const</span> T &amp;value)</div>
<div class="line"><a id="l00179" name="l00179"></a><span class="lineno"> 179</span>{</div>
<div class="line"><a id="l00180" name="l00180"></a><span class="lineno"> 180</span> <span class="keywordflow">if</span> (m_buffer.full())</div>
<div class="line"><a id="l00181" name="l00181"></a><span class="lineno"> 181</span> <span class="keywordflow">return</span> <span class="keyword">false</span>;</div>
<div class="line"><a id="l00182" name="l00182"></a><span class="lineno"> 182</span> <span class="keywordflow">return</span> m_buffer.<a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a1e934fd7dc8ba5c9d3e59522f05c67f8">push</a>(value);</div>
<div class="line"><a id="l00183" name="l00183"></a><span class="lineno"> 183</span>}</div>
</div>
<div class="line"><a id="l00184" name="l00184"></a><span class="lineno"> 184</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00185" name="l00185"></a><span class="lineno"> 185</span><span class="comment">/* Remove and return the oldest value from the buffer. If the</span></div>
<div class="line"><a id="l00186" name="l00186"></a><span class="lineno"> 186</span><span class="comment"> * buffer is empty, return std::nullopt */</span></div>
<div class="line"><a id="l00187" name="l00187"></a><span class="lineno"> 187</span><span class="keyword">template</span>&lt;<span class="keyword">class</span> T, std::<span class="keywordtype">size_t</span> CAPACITY&gt;</div>
<div class="foldopen" id="foldopen00188" data-start="{" data-end="}">
<div class="line"><a id="l00188" name="l00188"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a44a53147d4b3600ec200300ea16e3707"> 188</a></span>std::optional&lt;T&gt; <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a44a53147d4b3600ec200300ea16e3707">CircularBuffer&lt;T, CAPACITY&gt;::pop</a>()</div>
<div class="line"><a id="l00189" name="l00189"></a><span class="lineno"> 189</span>{</div>
<div class="line"><a id="l00190" name="l00190"></a><span class="lineno"> 190</span> <span class="keywordflow">return</span> m_buffer.pop();</div>
<div class="line"><a id="l00191" name="l00191"></a><span class="lineno"> 191</span>}</div>
</div>
<div class="line"><a id="l00192" name="l00192"></a><span class="lineno"> 192</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00193" name="l00193"></a><span class="lineno"> 193</span><span class="comment">/* Remove the oldest value from the buffer and store it in</span></div>
<div class="line"><a id="l00194" name="l00194"></a><span class="lineno"> 194</span><span class="comment"> * &#39;value&#39;. Return true if successful, false if the buffer is empty */</span></div>
<div class="line"><a id="l00195" name="l00195"></a><span class="lineno"> 195</span><span class="keyword">template</span>&lt;<span class="keyword">class</span> T, std::<span class="keywordtype">size_t</span> CAPACITY&gt;</div>
<div class="foldopen" id="foldopen00196" data-start="{" data-end="}">
<div class="line"><a id="l00196" name="l00196"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a7e56f823fd199baf6badc044e6b7b7f2"> 196</a></span><span class="keywordtype">bool</span> <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a44a53147d4b3600ec200300ea16e3707">CircularBuffer&lt;T, CAPACITY&gt;::pop</a>(T &amp;value)</div>
<div class="line"><a id="l00197" name="l00197"></a><span class="lineno"> 197</span>{</div>
<div class="line"><a id="l00198" name="l00198"></a><span class="lineno"> 198</span> <span class="keywordflow">return</span> m_buffer.pop(value);</div>
<div class="line"><a id="l00199" name="l00199"></a><span class="lineno"> 199</span>}</div>
</div>
<div class="line"><a id="l00200" name="l00200"></a><span class="lineno"> 200</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00201" name="l00201"></a><span class="lineno"> 201</span><span class="comment">/* Return the oldest value without removing it. If the buffer is</span></div>
<div class="line"><a id="l00202" name="l00202"></a><span class="lineno"> 202</span><span class="comment"> * empty, return std::nullopt */</span></div>
<div class="line"><a id="l00203" name="l00203"></a><span class="lineno"> 203</span><span class="keyword">template</span>&lt;<span class="keyword">class</span> T, std::<span class="keywordtype">size_t</span> CAPACITY&gt;</div>
<div class="foldopen" id="foldopen00204" data-start="{" data-end="}">
<div class="line"><a id="l00204" name="l00204"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a0920f451034bda88271b5f69bd324f5e"> 204</a></span>std::optional&lt;T&gt; <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a0920f451034bda88271b5f69bd324f5e">CircularBuffer&lt;T, CAPACITY&gt;::front</a>()<span class="keyword"> const</span></div>
<div class="line"><a id="l00205" name="l00205"></a><span class="lineno"> 205</span><span class="keyword"></span>{</div>
<div class="line"><a id="l00206" name="l00206"></a><span class="lineno"> 206</span> <span class="keywordflow">return</span> m_buffer.front();</div>
<div class="line"><a id="l00207" name="l00207"></a><span class="lineno"> 207</span>}</div>
</div>
<div class="line"><a id="l00208" name="l00208"></a><span class="lineno"> 208</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00209" name="l00209"></a><span class="lineno"> 209</span><span class="comment">/* Return the oldest value without removing it and store it in</span></div>
<div class="line"><a id="l00210" name="l00210"></a><span class="lineno"> 210</span><span class="comment"> * &#39;value&#39;. Return true if successful, false if the buffer is empty */</span></div>
<div class="line"><a id="l00211" name="l00211"></a><span class="lineno"> 211</span><span class="keyword">template</span>&lt;<span class="keyword">class</span> T, std::<span class="keywordtype">size_t</span> CAPACITY&gt;</div>
<div class="foldopen" id="foldopen00212" data-start="{" data-end="}">
<div class="line"><a id="l00212" name="l00212"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a080817748fcd320c071f781b94aed283"> 212</a></span><span class="keywordtype">bool</span> <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a0920f451034bda88271b5f69bd324f5e">CircularBuffer&lt;T, CAPACITY&gt;::front</a>(T &amp;value)<span class="keyword"> const</span></div>
<div class="line"><a id="l00213" name="l00213"></a><span class="lineno"> 213</span><span class="keyword"></span>{</div>
<div class="line"><a id="l00214" name="l00214"></a><span class="lineno"> 214</span> <span class="keywordflow">return</span> m_buffer.front(value);</div>
<div class="line"><a id="l00215" name="l00215"></a><span class="lineno"> 215</span>}</div>
</div>
<div class="line"><a id="l00216" name="l00216"></a><span class="lineno"> 216</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00217" name="l00217"></a><span class="lineno"> 217</span><span class="comment">/* Return the newest value without removing it. If the buffer is</span></div>
<div class="line"><a id="l00218" name="l00218"></a><span class="lineno"> 218</span><span class="comment"> * empty, return std::nullopt */</span></div>
<div class="line"><a id="l00219" name="l00219"></a><span class="lineno"> 219</span><span class="keyword">template</span>&lt;<span class="keyword">class</span> T, std::<span class="keywordtype">size_t</span> CAPACITY&gt;</div>
<div class="foldopen" id="foldopen00220" data-start="{" data-end="}">
<div class="line"><a id="l00220" name="l00220"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ab663c689eb6ec5369a0c6e33dfdee729"> 220</a></span>std::optional&lt;T&gt; <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ab663c689eb6ec5369a0c6e33dfdee729">CircularBuffer&lt;T, CAPACITY&gt;::back</a>()<span class="keyword"> const</span></div>
<div class="line"><a id="l00221" name="l00221"></a><span class="lineno"> 221</span><span class="keyword"></span>{</div>
<div class="line"><a id="l00222" name="l00222"></a><span class="lineno"> 222</span> <span class="keywordflow">return</span> m_buffer.back();</div>
<div class="line"><a id="l00223" name="l00223"></a><span class="lineno"> 223</span>}</div>
</div>
<div class="line"><a id="l00224" name="l00224"></a><span class="lineno"> 224</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00225" name="l00225"></a><span class="lineno"> 225</span><span class="comment">/* Return the newest value without removing it and store it in</span></div>
<div class="line"><a id="l00226" name="l00226"></a><span class="lineno"> 226</span><span class="comment"> * &#39;value&#39;. Return true if successful, false if the buffer is empty */</span></div>
<div class="line"><a id="l00227" name="l00227"></a><span class="lineno"> 227</span><span class="keyword">template</span>&lt;<span class="keyword">class</span> T, std::<span class="keywordtype">size_t</span> CAPACITY&gt;</div>
<div class="foldopen" id="foldopen00228" data-start="{" data-end="}">
<div class="line"><a id="l00228" name="l00228"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a3785129392466b941567c8b6c5f4f849"> 228</a></span><span class="keywordtype">bool</span> <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ab663c689eb6ec5369a0c6e33dfdee729">CircularBuffer&lt;T, CAPACITY&gt;::back</a>(T &amp;value)<span class="keyword"> const</span></div>
<div class="line"><a id="l00229" name="l00229"></a><span class="lineno"> 229</span><span class="keyword"></span>{</div>
<div class="line"><a id="l00230" name="l00230"></a><span class="lineno"> 230</span> <span class="keywordflow">return</span> m_buffer.back(value);</div>
<div class="line"><a id="l00231" name="l00231"></a><span class="lineno"> 231</span>}</div>
</div>
<div class="line"><a id="l00232" name="l00232"></a><span class="lineno"> 232</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00233" name="l00233"></a><span class="lineno"> 233</span><span class="comment">/* Check if the buffer is empty */</span></div>
<div class="line"><a id="l00234" name="l00234"></a><span class="lineno"> 234</span><span class="keyword">template</span>&lt;<span class="keyword">class</span> T, std::<span class="keywordtype">size_t</span> CAPACITY&gt;</div>
<div class="foldopen" id="foldopen00235" data-start="{" data-end="}">
<div class="line"><a id="l00235" name="l00235"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a644718bb2fb240de962dc3c9a1fdf0dc"> 235</a></span><span class="keywordtype">bool</span> <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a644718bb2fb240de962dc3c9a1fdf0dc">CircularBuffer&lt;T, CAPACITY&gt;::empty</a>()<span class="keyword"> const</span></div>
<div class="line"><a id="l00236" name="l00236"></a><span class="lineno"> 236</span><span class="keyword"></span>{</div>
<div class="line"><a id="l00237" name="l00237"></a><span class="lineno"> 237</span> <span class="keywordflow">return</span> m_buffer.empty();</div>
<div class="line"><a id="l00238" name="l00238"></a><span class="lineno"> 238</span>}</div>
</div>
<div class="line"><a id="l00239" name="l00239"></a><span class="lineno"> 239</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00240" name="l00240"></a><span class="lineno"> 240</span><span class="comment">/* Check if the buffer is full */</span></div>
<div class="line"><a id="l00241" name="l00241"></a><span class="lineno"> 241</span><span class="keyword">template</span>&lt;<span class="keyword">class</span> T, std::<span class="keywordtype">size_t</span> CAPACITY&gt;</div>
<div class="foldopen" id="foldopen00242" data-start="{" data-end="}">
<div class="line"><a id="l00242" name="l00242"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a8abf3cf65268916fe1f1660fd9efd90a"> 242</a></span><span class="keywordtype">bool</span> <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a8abf3cf65268916fe1f1660fd9efd90a">CircularBuffer&lt;T, CAPACITY&gt;::full</a>()<span class="keyword"> const</span></div>
<div class="line"><a id="l00243" name="l00243"></a><span class="lineno"> 243</span><span class="keyword"></span>{</div>
<div class="line"><a id="l00244" name="l00244"></a><span class="lineno"> 244</span> <span class="keywordflow">return</span> m_buffer.full();</div>
<div class="line"><a id="l00245" name="l00245"></a><span class="lineno"> 245</span>}</div>
</div>
<div class="line"><a id="l00246" name="l00246"></a><span class="lineno"> 246</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00247" name="l00247"></a><span class="lineno"> 247</span><span class="comment">/* Get the number of elements currently in the buffer */</span></div>
<div class="line"><a id="l00248" name="l00248"></a><span class="lineno"> 248</span><span class="keyword">template</span>&lt;<span class="keyword">class</span> T, std::<span class="keywordtype">size_t</span> CAPACITY&gt;</div>
<div class="foldopen" id="foldopen00249" data-start="{" data-end="}">
<div class="line"><a id="l00249" name="l00249"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ade1601ccf1fa3bcf050867f0852ca4e5"> 249</a></span>std::size_t <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ade1601ccf1fa3bcf050867f0852ca4e5">CircularBuffer&lt;T, CAPACITY&gt;::size</a>()<span class="keyword"> const</span></div>
<div class="line"><a id="l00250" name="l00250"></a><span class="lineno"> 250</span><span class="keyword"></span>{</div>
<div class="line"><a id="l00251" name="l00251"></a><span class="lineno"> 251</span> <span class="keywordflow">return</span> m_buffer.size();</div>
<div class="line"><a id="l00252" name="l00252"></a><span class="lineno"> 252</span>}</div>
</div>
<div class="line"><a id="l00253" name="l00253"></a><span class="lineno"> 253</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00254" name="l00254"></a><span class="lineno"> 254</span><span class="comment">/* Get the maximum capacity of the buffer */</span></div>
<div class="line"><a id="l00255" name="l00255"></a><span class="lineno"> 255</span><span class="keyword">template</span>&lt;<span class="keyword">class</span> T, std::<span class="keywordtype">size_t</span> CAPACITY&gt;</div>
<div class="foldopen" id="foldopen00256" data-start="{" data-end="}">
<div class="line"><a id="l00256" name="l00256"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#adf1df7795354fd1fb99cb89bd54c4f93"> 256</a></span>[[nodiscard]] <span class="keyword">constexpr</span> std::size_t <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#adf1df7795354fd1fb99cb89bd54c4f93">CircularBuffer&lt;T, CAPACITY&gt;::capacity</a>()<span class="keyword"> const</span></div>
<div class="line"><a id="l00257" name="l00257"></a><span class="lineno"> 257</span><span class="keyword"></span>{</div>
<div class="line"><a id="l00258" name="l00258"></a><span class="lineno"> 258</span> <span class="keywordflow">return</span> CAPACITY;</div>
<div class="line"><a id="l00259" name="l00259"></a><span class="lineno"> 259</span>}</div>
</div>
<div class="line"><a id="l00260" name="l00260"></a><span class="lineno"> 260</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00261" name="l00261"></a><span class="lineno"> 261</span><span class="comment">/* Clear the buffer, resetting it to an empty state */</span></div>
<div class="line"><a id="l00262" name="l00262"></a><span class="lineno"> 262</span><span class="keyword">template</span>&lt;<span class="keyword">class</span> T, std::<span class="keywordtype">size_t</span> CAPACITY&gt;</div>
<div class="foldopen" id="foldopen00263" data-start="{" data-end="}">
<div class="line"><a id="l00263" name="l00263"></a><span class="lineno"><a class="line" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ac8bb3912a3ce86b15842e79d0b421204"> 263</a></span><span class="keywordtype">void</span> <a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ac8bb3912a3ce86b15842e79d0b421204">CircularBuffer&lt;T, CAPACITY&gt;::clear</a>()</div>
<div class="line"><a id="l00264" name="l00264"></a><span class="lineno"> 264</span>{</div>
<div class="line"><a id="l00265" name="l00265"></a><span class="lineno"> 265</span> m_buffer.clear();</div>
<div class="line"><a id="l00266" name="l00266"></a><span class="lineno"> 266</span>}</div>
</div>
<div class="line"><a id="l00267" name="l00267"></a><span class="lineno"> 267</span><span class="comment">//--------------------------------------------------------------</span></div>
<div class="line"><a id="l00268" name="l00268"></a><span class="lineno"> 268</span>} <span class="comment">// namespace sdi_toolBox::common::utils</span></div>
</div>
<div class="ttc" id="aclasssdi__toolBox_1_1common_1_1utils_1_1CircularBuffer_html"><div class="ttname"><a href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">sdi_toolBox::common::utils::CircularBuffer</a></div><div class="ttdoc">Fixed-size circular buffer with compile-time capacity and no-overwrite behavior.</div><div class="ttdef"><b>Definition</b> <a href="circularBuffer_8h_source.html#l00048">circularBuffer.h:49</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1common_1_1utils_1_1CircularBuffer_html_a0920f451034bda88271b5f69bd324f5e"><div class="ttname"><a href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a0920f451034bda88271b5f69bd324f5e">sdi_toolBox::common::utils::CircularBuffer::front</a></div><div class="ttdeci">std::optional&lt; T &gt; front() const</div><div class="ttdoc">Return (without removing) the oldest element.</div><div class="ttdef"><b>Definition</b> <a href="circularBuffer_8h_source.html#l00204">circularBuffer.h:204</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1common_1_1utils_1_1CircularBuffer_html_a1e934fd7dc8ba5c9d3e59522f05c67f8"><div class="ttname"><a href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a1e934fd7dc8ba5c9d3e59522f05c67f8">sdi_toolBox::common::utils::CircularBuffer::push</a></div><div class="ttdeci">bool push(const T &amp;value)</div><div class="ttdoc">Try to append a value to the buffer.</div><div class="ttdef"><b>Definition</b> <a href="circularBuffer_8h_source.html#l00178">circularBuffer.h:178</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1common_1_1utils_1_1CircularBuffer_html_a44a53147d4b3600ec200300ea16e3707"><div class="ttname"><a href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a44a53147d4b3600ec200300ea16e3707">sdi_toolBox::common::utils::CircularBuffer::pop</a></div><div class="ttdeci">std::optional&lt; T &gt; pop()</div><div class="ttdoc">Remove and return the oldest element from the buffer.</div><div class="ttdef"><b>Definition</b> <a href="circularBuffer_8h_source.html#l00188">circularBuffer.h:188</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1common_1_1utils_1_1CircularBuffer_html_a644718bb2fb240de962dc3c9a1fdf0dc"><div class="ttname"><a href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a644718bb2fb240de962dc3c9a1fdf0dc">sdi_toolBox::common::utils::CircularBuffer::empty</a></div><div class="ttdeci">bool empty() const</div><div class="ttdoc">Check whether the buffer is empty.</div><div class="ttdef"><b>Definition</b> <a href="circularBuffer_8h_source.html#l00235">circularBuffer.h:235</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1common_1_1utils_1_1CircularBuffer_html_a8abf3cf65268916fe1f1660fd9efd90a"><div class="ttname"><a href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a8abf3cf65268916fe1f1660fd9efd90a">sdi_toolBox::common::utils::CircularBuffer::full</a></div><div class="ttdeci">bool full() const</div><div class="ttdoc">Check whether the buffer is full.</div><div class="ttdef"><b>Definition</b> <a href="circularBuffer_8h_source.html#l00242">circularBuffer.h:242</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1common_1_1utils_1_1CircularBuffer_html_ab663c689eb6ec5369a0c6e33dfdee729"><div class="ttname"><a href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ab663c689eb6ec5369a0c6e33dfdee729">sdi_toolBox::common::utils::CircularBuffer::back</a></div><div class="ttdeci">std::optional&lt; T &gt; back() const</div><div class="ttdoc">Return (without removing) the newest element.</div><div class="ttdef"><b>Definition</b> <a href="circularBuffer_8h_source.html#l00220">circularBuffer.h:220</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1common_1_1utils_1_1CircularBuffer_html_ac8bb3912a3ce86b15842e79d0b421204"><div class="ttname"><a href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ac8bb3912a3ce86b15842e79d0b421204">sdi_toolBox::common::utils::CircularBuffer::clear</a></div><div class="ttdeci">void clear()</div><div class="ttdoc">Clear the buffer and reset internal indices.</div><div class="ttdef"><b>Definition</b> <a href="circularBuffer_8h_source.html#l00263">circularBuffer.h:263</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1common_1_1utils_1_1CircularBuffer_html_ade1601ccf1fa3bcf050867f0852ca4e5"><div class="ttname"><a href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ade1601ccf1fa3bcf050867f0852ca4e5">sdi_toolBox::common::utils::CircularBuffer::size</a></div><div class="ttdeci">std::size_t size() const</div><div class="ttdoc">Number of elements currently stored in the buffer.</div><div class="ttdef"><b>Definition</b> <a href="circularBuffer_8h_source.html#l00249">circularBuffer.h:249</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1common_1_1utils_1_1CircularBuffer_html_adf1df7795354fd1fb99cb89bd54c4f93"><div class="ttname"><a href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#adf1df7795354fd1fb99cb89bd54c4f93">sdi_toolBox::common::utils::CircularBuffer::capacity</a></div><div class="ttdeci">constexpr std::size_t capacity() const</div><div class="ttdoc">Compile-time capacity of the buffer.</div><div class="ttdef"><b>Definition</b> <a href="circularBuffer_8h_source.html#l00256">circularBuffer.h:256</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1common_1_1utils_1_1RingBuffer_html"><div class="ttname"><a href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html">sdi_toolBox::common::utils::RingBuffer</a></div><div class="ttdoc">Fixed-size ring (circular) buffer with compile-time capacity and overwrite-on-full behavior.</div><div class="ttdef"><b>Definition</b> <a href="ringBuffer_8h_source.html#l00049">ringBuffer.h:50</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1common_1_1utils_1_1RingBuffer_html_a1e934fd7dc8ba5c9d3e59522f05c67f8"><div class="ttname"><a href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a1e934fd7dc8ba5c9d3e59522f05c67f8">sdi_toolBox::common::utils::RingBuffer::push</a></div><div class="ttdeci">bool push(const T &amp;value)</div><div class="ttdoc">Append a value to the buffer.</div><div class="ttdef"><b>Definition</b> <a href="ringBuffer_8h_source.html#l00196">ringBuffer.h:196</a></div></div>
<div class="ttc" id="anamespacesdi__toolBox_1_1common_1_1utils_html"><div class="ttname"><a href="namespacesdi__toolBox_1_1common_1_1utils.html">sdi_toolBox::common::utils</a></div><div class="ttdoc">General-purpose utility functions shared across all sdi_toolBox modules.</div><div class="ttdef"><b>Definition</b> <a href="circularBuffer_8h_source.html#l00017">circularBuffer.h:18</a></div></div>
<div class="ttc" id="aringBuffer_8h_html"><div class="ttname"><a href="ringBuffer_8h.html">ringBuffer.h</a></div></div>
</div><!-- fragment --></div><!-- contents -->
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
SDi toolsBox is licensed under the terms and conditions of the <a href="https://opensource.org/licenses/zlib-license.php" target="_blank">zlib/png license</a>
<br />
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE | ver: 2.x.x - build: 2026-04-28
<br />
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen" /></a> 1.9.8
</small>
</address>
</body>

View File

@@ -0,0 +1,84 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>SDi toolsBox</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="custom_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">sdi_toolBox
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',false,false,'search.php','Search');
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div class="header">
<div class="headertitle"><div class="title">Class Index</div></div>
</div><!--header-->
<div class="contents">
<div class="qindex"><a class="qindex" href="#letter_B">B</a>&#160;|&#160;<a class="qindex" href="#letter_C">C</a>&#160;|&#160;<a class="qindex" href="#letter_I">I</a>&#160;|&#160;<a class="qindex" href="#letter_M">M</a>&#160;|&#160;<a class="qindex" href="#letter_N">N</a>&#160;|&#160;<a class="qindex" href="#letter_R">R</a>&#160;|&#160;<a class="qindex" href="#letter_W">W</a></div>
<div class="classindex">
<dl class="classindex even">
<dt class="alphachar"><a id="letter_B" name="letter_B">B</a></dt>
<dd><a class="el" href="classsdi__toolBox_1_1desktop_1_1utils_1_1Base64.html">Base64</a> (<a class="el" href="namespacesdi__toolBox_1_1desktop_1_1utils.html">sdi_toolBox::desktop::utils</a>)</dd><dd><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> (<a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html">sdi_toolBox::desktop::eventBus</a>)</dd></dl>
<dl class="classindex odd">
<dt class="alphachar"><a id="letter_C" name="letter_C">C</a></dt>
<dd><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">CircularBuffer</a> (<a class="el" href="namespacesdi__toolBox_1_1common_1_1utils.html">sdi_toolBox::common::utils</a>)</dd></dl>
<dl class="classindex even">
<dt class="alphachar"><a id="letter_I" name="letter_I">I</a></dt>
<dd><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> (<a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html">sdi_toolBox::desktop::eventBus</a>)</dd></dl>
<dl class="classindex odd">
<dt class="alphachar"><a id="letter_M" name="letter_M">M</a></dt>
<dd><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> (<a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html">sdi_toolBox::desktop::eventBus</a>)</dd></dl>
<dl class="classindex even">
<dt class="alphachar"><a id="letter_N" name="letter_N">N</a></dt>
<dd><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a> (<a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html">sdi_toolBox::desktop::eventBus</a>)</dd></dl>
<dl class="classindex odd">
<dt class="alphachar"><a id="letter_R" name="letter_R">R</a></dt>
<dd><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html">RingBuffer</a> (<a class="el" href="namespacesdi__toolBox_1_1common_1_1utils.html">sdi_toolBox::common::utils</a>)</dd></dl>
<dl class="classindex even">
<dt class="alphachar"><a id="letter_W" name="letter_W">W</a></dt>
<dd><a class="el" href="classsdi__toolBox_1_1desktop_1_1wxWidgets_1_1Wildcard.html">Wildcard</a> (<a class="el" href="namespacesdi__toolBox_1_1desktop_1_1wxWidgets.html">sdi_toolBox::desktop::wxWidgets</a>)</dd><dd><a class="el" href="structsdi__toolBox_1_1desktop_1_1wxWidgets_1_1Wildcard_1_1WildcardEntry.html">Wildcard::WildcardEntry</a> (<a class="el" href="namespacesdi__toolBox_1_1desktop_1_1wxWidgets.html">sdi_toolBox::desktop::wxWidgets</a>)</dd></dl>
</div>
</div><!-- contents -->
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
SDi toolsBox is licensed under the terms and conditions of the <a href="https://opensource.org/licenses/zlib-license.php" target="_blank">zlib/png license</a>
<br />
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE | ver: 2.x.x - build: 2026-04-28
<br />
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen" /></a> 1.9.8
</small>
</address>
</body>
</html>

View File

@@ -0,0 +1,79 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>SDi toolsBox</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="custom_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">sdi_toolBox
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',false,false,'search.php','Search');
});
/* @license-end */
</script>
<div id="main-nav"></div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="namespacesdi__toolBox.html">sdi_toolBox</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1common.html">common</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1common_1_1utils.html">utils</a></li><li class="navelem"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">CircularBuffer</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle"><div class="title">CircularBuffer&lt; T, CAPACITY &gt; Member List</div></div>
</div><!--header-->
<div class="contents">
<p>This is the complete list of members for <a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">CircularBuffer&lt; T, CAPACITY &gt;</a>, including all inherited members.</p>
<table class="directory">
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ab663c689eb6ec5369a0c6e33dfdee729">back</a>() const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">CircularBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a3785129392466b941567c8b6c5f4f849">back</a>(T &amp;value) const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">CircularBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#adf1df7795354fd1fb99cb89bd54c4f93">capacity</a>() const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">CircularBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ac8bb3912a3ce86b15842e79d0b421204">clear</a>()</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">CircularBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a644718bb2fb240de962dc3c9a1fdf0dc">empty</a>() const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">CircularBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a0920f451034bda88271b5f69bd324f5e">front</a>() const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">CircularBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a080817748fcd320c071f781b94aed283">front</a>(T &amp;value) const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">CircularBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a8abf3cf65268916fe1f1660fd9efd90a">full</a>() const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">CircularBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a44a53147d4b3600ec200300ea16e3707">pop</a>()</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">CircularBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a7e56f823fd199baf6badc044e6b7b7f2">pop</a>(T &amp;value)</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">CircularBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a1e934fd7dc8ba5c9d3e59522f05c67f8">push</a>(const T &amp;value)</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">CircularBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ade1601ccf1fa3bcf050867f0852ca4e5">size</a>() const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">CircularBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
</table></div><!-- contents -->
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
SDi toolsBox is licensed under the terms and conditions of the <a href="https://opensource.org/licenses/zlib-license.php" target="_blank">zlib/png license</a>
<br />
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE | ver: 2.x.x - build: 2026-04-28
<br />
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen" /></a> 1.9.8
</small>
</address>
</body>
</html>

View File

@@ -0,0 +1,463 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>SDi toolsBox</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="custom_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">sdi_toolBox
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',false,false,'search.php','Search');
});
/* @license-end */
</script>
<div id="main-nav"></div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="namespacesdi__toolBox.html">sdi_toolBox</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1common.html">common</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1common_1_1utils.html">utils</a></li><li class="navelem"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">CircularBuffer</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="summary">
<a href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer-members.html">List of all members</a> </div>
<div class="headertitle"><div class="title">CircularBuffer&lt; T, CAPACITY &gt; Class Template Reference</div></div>
</div><!--header-->
<div class="contents">
<p><code>#include &lt;<a class="el" href="circularBuffer_8h_source.html">circularBuffer.h</a>&gt;</code></p>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><div class="compoundTemplParams">template&lt;class T, std::size_t CAPACITY&gt;<br />
class sdi_toolBox::common::utils::CircularBuffer&lt; T, CAPACITY &gt;</div><p>Fixed-size circular buffer with compile-time capacity and no-overwrite behavior. </p>
<p>This template wraps a <a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html" title="Fixed-size ring (circular) buffer with compile-time capacity and overwrite-on-full behavior.">RingBuffer</a> and prevents new elements from being written when the buffer is full. Existing data is never overwritten; <a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a1e934fd7dc8ba5c9d3e59522f05c67f8" title="Try to append a value to the buffer.">push()</a> simply fails and returns false when capacity is reached.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
<table class="tparams">
<tr><td class="paramname">T</td><td>Element type stored in the buffer. </td></tr>
<tr><td class="paramname">CAPACITY</td><td>Compile-time buffer capacity. Must be &gt; 0.</td></tr>
</table>
</dd>
</dl>
<dl class="section note"><dt>Note</dt><dd>The class provides both optional-returning and out-parameter overloads for pop/front/back to suit different runtime constraints. </dd></dl>
<dl class="section warning"><dt>Warning</dt><dd>Instantiating with CAPACITY == 0 is forbidden (static_assert).</dd></dl>
<div class="fragment"><div class="line"><a class="code hl_class" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">CircularBuffer&lt;int, 8&gt;</a> cb;</div>
<div class="line"><span class="keywordflow">if</span> (cb.<a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a1e934fd7dc8ba5c9d3e59522f05c67f8">push</a>(42))</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// element was inserted</span></div>
<div class="line">}</div>
<div class="line"><span class="keywordflow">else</span></div>
<div class="line">{</div>
<div class="line"> <span class="comment">// buffer was full, element was discarded</span></div>
<div class="line">}</div>
<div class="ttc" id="aclasssdi__toolBox_1_1common_1_1utils_1_1CircularBuffer_html"><div class="ttname"><a href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html">sdi_toolBox::common::utils::CircularBuffer</a></div><div class="ttdoc">Fixed-size circular buffer with compile-time capacity and no-overwrite behavior.</div><div class="ttdef"><b>Definition</b> <a href="circularBuffer_8h_source.html#l00048">circularBuffer.h:49</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1common_1_1utils_1_1CircularBuffer_html_a1e934fd7dc8ba5c9d3e59522f05c67f8"><div class="ttname"><a href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a1e934fd7dc8ba5c9d3e59522f05c67f8">sdi_toolBox::common::utils::CircularBuffer::push</a></div><div class="ttdeci">bool push(const T &amp;value)</div><div class="ttdoc">Try to append a value to the buffer.</div><div class="ttdef"><b>Definition</b> <a href="circularBuffer_8h_source.html#l00178">circularBuffer.h:178</a></div></div>
</div><!-- fragment -->
<p class="definition">Definition at line <a class="el" href="circularBuffer_8h_source.html#l00048">48</a> of file <a class="el" href="circularBuffer_8h_source.html">circularBuffer.h</a>.</p>
</div><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr><td colspan="2"><div class="groupHeader">Write operations</div></td></tr>
<tr class="memitem:a1e934fd7dc8ba5c9d3e59522f05c67f8" id="r_a1e934fd7dc8ba5c9d3e59522f05c67f8"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a1e934fd7dc8ba5c9d3e59522f05c67f8">push</a> (const T &amp;value)</td></tr>
<tr class="memdesc:a1e934fd7dc8ba5c9d3e59522f05c67f8"><td class="mdescLeft">&#160;</td><td class="mdescRight">Try to append a value to the buffer. <br /></td></tr>
<tr class="separator:a1e934fd7dc8ba5c9d3e59522f05c67f8"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr><td colspan="2"><div class="groupHeader">Read operations</div></td></tr>
<tr class="memitem:a44a53147d4b3600ec200300ea16e3707" id="r_a44a53147d4b3600ec200300ea16e3707"><td class="memItemLeft" align="right" valign="top">std::optional&lt; T &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a44a53147d4b3600ec200300ea16e3707">pop</a> ()</td></tr>
<tr class="memdesc:a44a53147d4b3600ec200300ea16e3707"><td class="mdescLeft">&#160;</td><td class="mdescRight">Remove and return the oldest element from the buffer. <br /></td></tr>
<tr class="separator:a44a53147d4b3600ec200300ea16e3707"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a7e56f823fd199baf6badc044e6b7b7f2" id="r_a7e56f823fd199baf6badc044e6b7b7f2"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a7e56f823fd199baf6badc044e6b7b7f2">pop</a> (T &amp;value)</td></tr>
<tr class="memdesc:a7e56f823fd199baf6badc044e6b7b7f2"><td class="mdescLeft">&#160;</td><td class="mdescRight">Remove the oldest element and store it in the provided reference. <br /></td></tr>
<tr class="separator:a7e56f823fd199baf6badc044e6b7b7f2"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a0920f451034bda88271b5f69bd324f5e" id="r_a0920f451034bda88271b5f69bd324f5e"><td class="memItemLeft" align="right" valign="top">std::optional&lt; T &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a0920f451034bda88271b5f69bd324f5e">front</a> () const</td></tr>
<tr class="memdesc:a0920f451034bda88271b5f69bd324f5e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Return (without removing) the oldest element. <br /></td></tr>
<tr class="separator:a0920f451034bda88271b5f69bd324f5e"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a080817748fcd320c071f781b94aed283" id="r_a080817748fcd320c071f781b94aed283"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a080817748fcd320c071f781b94aed283">front</a> (T &amp;value) const</td></tr>
<tr class="memdesc:a080817748fcd320c071f781b94aed283"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy the oldest element into the provided reference without removing it. <br /></td></tr>
<tr class="separator:a080817748fcd320c071f781b94aed283"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ab663c689eb6ec5369a0c6e33dfdee729" id="r_ab663c689eb6ec5369a0c6e33dfdee729"><td class="memItemLeft" align="right" valign="top">std::optional&lt; T &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ab663c689eb6ec5369a0c6e33dfdee729">back</a> () const</td></tr>
<tr class="memdesc:ab663c689eb6ec5369a0c6e33dfdee729"><td class="mdescLeft">&#160;</td><td class="mdescRight">Return (without removing) the newest element. <br /></td></tr>
<tr class="separator:ab663c689eb6ec5369a0c6e33dfdee729"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a3785129392466b941567c8b6c5f4f849" id="r_a3785129392466b941567c8b6c5f4f849"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a3785129392466b941567c8b6c5f4f849">back</a> (T &amp;value) const</td></tr>
<tr class="memdesc:a3785129392466b941567c8b6c5f4f849"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy the newest element into the provided reference without removing it. <br /></td></tr>
<tr class="separator:a3785129392466b941567c8b6c5f4f849"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr><td colspan="2"><div class="groupHeader">State queries</div></td></tr>
<tr class="memitem:a644718bb2fb240de962dc3c9a1fdf0dc" id="r_a644718bb2fb240de962dc3c9a1fdf0dc"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a644718bb2fb240de962dc3c9a1fdf0dc">empty</a> () const</td></tr>
<tr class="memdesc:a644718bb2fb240de962dc3c9a1fdf0dc"><td class="mdescLeft">&#160;</td><td class="mdescRight">Check whether the buffer is empty. <br /></td></tr>
<tr class="separator:a644718bb2fb240de962dc3c9a1fdf0dc"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a8abf3cf65268916fe1f1660fd9efd90a" id="r_a8abf3cf65268916fe1f1660fd9efd90a"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a8abf3cf65268916fe1f1660fd9efd90a">full</a> () const</td></tr>
<tr class="memdesc:a8abf3cf65268916fe1f1660fd9efd90a"><td class="mdescLeft">&#160;</td><td class="mdescRight">Check whether the buffer is full. <br /></td></tr>
<tr class="separator:a8abf3cf65268916fe1f1660fd9efd90a"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ade1601ccf1fa3bcf050867f0852ca4e5" id="r_ade1601ccf1fa3bcf050867f0852ca4e5"><td class="memItemLeft" align="right" valign="top">std::size_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ade1601ccf1fa3bcf050867f0852ca4e5">size</a> () const</td></tr>
<tr class="memdesc:ade1601ccf1fa3bcf050867f0852ca4e5"><td class="mdescLeft">&#160;</td><td class="mdescRight">Number of elements currently stored in the buffer. <br /></td></tr>
<tr class="separator:ade1601ccf1fa3bcf050867f0852ca4e5"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:adf1df7795354fd1fb99cb89bd54c4f93" id="r_adf1df7795354fd1fb99cb89bd54c4f93"><td class="memItemLeft" align="right" valign="top">constexpr std::size_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#adf1df7795354fd1fb99cb89bd54c4f93">capacity</a> () const</td></tr>
<tr class="memdesc:adf1df7795354fd1fb99cb89bd54c4f93"><td class="mdescLeft">&#160;</td><td class="mdescRight">Compile-time capacity of the buffer. <br /></td></tr>
<tr class="separator:adf1df7795354fd1fb99cb89bd54c4f93"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr><td colspan="2"><div class="groupHeader">Modifiers</div></td></tr>
<tr class="memitem:ac8bb3912a3ce86b15842e79d0b421204" id="r_ac8bb3912a3ce86b15842e79d0b421204"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ac8bb3912a3ce86b15842e79d0b421204">clear</a> ()</td></tr>
<tr class="memdesc:ac8bb3912a3ce86b15842e79d0b421204"><td class="mdescLeft">&#160;</td><td class="mdescRight">Clear the buffer and reset internal indices. <br /></td></tr>
<tr class="separator:ac8bb3912a3ce86b15842e79d0b421204"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<h2 class="groupheader">Member Function Documentation</h2>
<a id="a1e934fd7dc8ba5c9d3e59522f05c67f8" name="a1e934fd7dc8ba5c9d3e59522f05c67f8"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a1e934fd7dc8ba5c9d3e59522f05c67f8">&#9670;&#160;</a></span>push()</h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">bool push </td>
<td>(</td>
<td class="paramtype">const T &amp;&#160;</td>
<td class="paramname"><em>value</em></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Try to append a value to the buffer. </p>
<p>If the buffer is full, the value is discarded and no overwrite occurs. </p><dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">value</td><td>Value to append (copied).</td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>true if the value was inserted, false if the buffer was full. </dd></dl>
<p class="definition">Definition at line <a class="el" href="circularBuffer_8h_source.html#l00178">178</a> of file <a class="el" href="circularBuffer_8h_source.html">circularBuffer.h</a>.</p>
</div>
</div>
<a id="a44a53147d4b3600ec200300ea16e3707" name="a44a53147d4b3600ec200300ea16e3707"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a44a53147d4b3600ec200300ea16e3707">&#9670;&#160;</a></span>pop() <span class="overload">[1/2]</span></h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">std::optional&lt; T &gt; pop </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Remove and return the oldest element from the buffer. </p>
<dl class="section return"><dt>Returns</dt><dd>std::optional&lt;T&gt; The oldest element if present, std::nullopt if empty. </dd></dl>
<p class="definition">Definition at line <a class="el" href="circularBuffer_8h_source.html#l00188">188</a> of file <a class="el" href="circularBuffer_8h_source.html">circularBuffer.h</a>.</p>
</div>
</div>
<a id="a7e56f823fd199baf6badc044e6b7b7f2" name="a7e56f823fd199baf6badc044e6b7b7f2"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a7e56f823fd199baf6badc044e6b7b7f2">&#9670;&#160;</a></span>pop() <span class="overload">[2/2]</span></h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">bool pop </td>
<td>(</td>
<td class="paramtype">T &amp;&#160;</td>
<td class="paramname"><em>value</em></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Remove the oldest element and store it in the provided reference. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">value</td><td>Output reference that receives the removed element.</td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>true if an element was removed, false if the buffer was empty. </dd></dl>
<p class="definition">Definition at line <a class="el" href="circularBuffer_8h_source.html#l00196">196</a> of file <a class="el" href="circularBuffer_8h_source.html">circularBuffer.h</a>.</p>
</div>
</div>
<a id="a0920f451034bda88271b5f69bd324f5e" name="a0920f451034bda88271b5f69bd324f5e"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a0920f451034bda88271b5f69bd324f5e">&#9670;&#160;</a></span>front() <span class="overload">[1/2]</span></h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">std::optional&lt; T &gt; front </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Return (without removing) the oldest element. </p>
<dl class="section return"><dt>Returns</dt><dd>std::optional&lt;T&gt; The oldest element if present, std::nullopt if empty. </dd></dl>
<p class="definition">Definition at line <a class="el" href="circularBuffer_8h_source.html#l00204">204</a> of file <a class="el" href="circularBuffer_8h_source.html">circularBuffer.h</a>.</p>
</div>
</div>
<a id="a080817748fcd320c071f781b94aed283" name="a080817748fcd320c071f781b94aed283"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a080817748fcd320c071f781b94aed283">&#9670;&#160;</a></span>front() <span class="overload">[2/2]</span></h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">bool front </td>
<td>(</td>
<td class="paramtype">T &amp;&#160;</td>
<td class="paramname"><em>value</em></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Copy the oldest element into the provided reference without removing it. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">value</td><td>Output reference that receives the element.</td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>true if the element was copied, false if the buffer is empty. </dd></dl>
<p class="definition">Definition at line <a class="el" href="circularBuffer_8h_source.html#l00212">212</a> of file <a class="el" href="circularBuffer_8h_source.html">circularBuffer.h</a>.</p>
</div>
</div>
<a id="ab663c689eb6ec5369a0c6e33dfdee729" name="ab663c689eb6ec5369a0c6e33dfdee729"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ab663c689eb6ec5369a0c6e33dfdee729">&#9670;&#160;</a></span>back() <span class="overload">[1/2]</span></h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">std::optional&lt; T &gt; back </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Return (without removing) the newest element. </p>
<dl class="section return"><dt>Returns</dt><dd>std::optional&lt;T&gt; The newest element if present, std::nullopt if empty. </dd></dl>
<p class="definition">Definition at line <a class="el" href="circularBuffer_8h_source.html#l00220">220</a> of file <a class="el" href="circularBuffer_8h_source.html">circularBuffer.h</a>.</p>
</div>
</div>
<a id="a3785129392466b941567c8b6c5f4f849" name="a3785129392466b941567c8b6c5f4f849"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a3785129392466b941567c8b6c5f4f849">&#9670;&#160;</a></span>back() <span class="overload">[2/2]</span></h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">bool back </td>
<td>(</td>
<td class="paramtype">T &amp;&#160;</td>
<td class="paramname"><em>value</em></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Copy the newest element into the provided reference without removing it. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">value</td><td>Output reference that receives the element.</td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>true if the element was copied, false if the buffer is empty. </dd></dl>
<p class="definition">Definition at line <a class="el" href="circularBuffer_8h_source.html#l00228">228</a> of file <a class="el" href="circularBuffer_8h_source.html">circularBuffer.h</a>.</p>
</div>
</div>
<a id="a644718bb2fb240de962dc3c9a1fdf0dc" name="a644718bb2fb240de962dc3c9a1fdf0dc"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a644718bb2fb240de962dc3c9a1fdf0dc">&#9670;&#160;</a></span>empty()</h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">bool empty </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Check whether the buffer is empty. </p>
<dl class="section return"><dt>Returns</dt><dd>true if empty, false otherwise. </dd></dl>
<p class="definition">Definition at line <a class="el" href="circularBuffer_8h_source.html#l00235">235</a> of file <a class="el" href="circularBuffer_8h_source.html">circularBuffer.h</a>.</p>
</div>
</div>
<a id="a8abf3cf65268916fe1f1660fd9efd90a" name="a8abf3cf65268916fe1f1660fd9efd90a"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a8abf3cf65268916fe1f1660fd9efd90a">&#9670;&#160;</a></span>full()</h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">bool full </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Check whether the buffer is full. </p>
<dl class="section return"><dt>Returns</dt><dd>true if full, false otherwise. </dd></dl>
<p class="definition">Definition at line <a class="el" href="circularBuffer_8h_source.html#l00242">242</a> of file <a class="el" href="circularBuffer_8h_source.html">circularBuffer.h</a>.</p>
</div>
</div>
<a id="ade1601ccf1fa3bcf050867f0852ca4e5" name="ade1601ccf1fa3bcf050867f0852ca4e5"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ade1601ccf1fa3bcf050867f0852ca4e5">&#9670;&#160;</a></span>size()</h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">std::size_t size </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Number of elements currently stored in the buffer. </p>
<dl class="section return"><dt>Returns</dt><dd>Current size (0 .. CAPACITY). </dd></dl>
<p class="definition">Definition at line <a class="el" href="circularBuffer_8h_source.html#l00249">249</a> of file <a class="el" href="circularBuffer_8h_source.html">circularBuffer.h</a>.</p>
</div>
</div>
<a id="adf1df7795354fd1fb99cb89bd54c4f93" name="adf1df7795354fd1fb99cb89bd54c4f93"></a>
<h2 class="memtitle"><span class="permalink"><a href="#adf1df7795354fd1fb99cb89bd54c4f93">&#9670;&#160;</a></span>capacity()</h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">constexpr std::size_t capacity </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td> const</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">constexpr</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Compile-time capacity of the buffer. </p>
<dl class="section return"><dt>Returns</dt><dd>The maximum number of elements the buffer can hold. </dd></dl>
<p class="definition">Definition at line <a class="el" href="circularBuffer_8h_source.html#l00256">256</a> of file <a class="el" href="circularBuffer_8h_source.html">circularBuffer.h</a>.</p>
</div>
</div>
<a id="ac8bb3912a3ce86b15842e79d0b421204" name="ac8bb3912a3ce86b15842e79d0b421204"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ac8bb3912a3ce86b15842e79d0b421204">&#9670;&#160;</a></span>clear()</h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">void clear </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Clear the buffer and reset internal indices. </p>
<p>After calling <a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ac8bb3912a3ce86b15842e79d0b421204" title="Clear the buffer and reset internal indices.">clear()</a>, <a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#a644718bb2fb240de962dc3c9a1fdf0dc" title="Check whether the buffer is empty.">empty()</a> returns true and <a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1CircularBuffer.html#ade1601ccf1fa3bcf050867f0852ca4e5" title="Number of elements currently stored in the buffer.">size()</a> returns 0. </p>
<p class="definition">Definition at line <a class="el" href="circularBuffer_8h_source.html#l00263">263</a> of file <a class="el" href="circularBuffer_8h_source.html">circularBuffer.h</a>.</p>
</div>
</div>
</div><!-- contents -->
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
SDi toolsBox is licensed under the terms and conditions of the <a href="https://opensource.org/licenses/zlib-license.php" target="_blank">zlib/png license</a>
<br />
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE | ver: 2.x.x - build: 2026-04-28
<br />
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen" /></a> 1.9.8
</small>
</address>
</body>
</html>

View File

@@ -0,0 +1,79 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>SDi toolsBox</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="custom_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">sdi_toolBox
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',false,false,'search.php','Search');
});
/* @license-end */
</script>
<div id="main-nav"></div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="namespacesdi__toolBox.html">sdi_toolBox</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1common.html">common</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1common_1_1utils.html">utils</a></li><li class="navelem"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html">RingBuffer</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle"><div class="title">RingBuffer&lt; T, CAPACITY &gt; Member List</div></div>
</div><!--header-->
<div class="contents">
<p>This is the complete list of members for <a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html">RingBuffer&lt; T, CAPACITY &gt;</a>, including all inherited members.</p>
<table class="directory">
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#ab663c689eb6ec5369a0c6e33dfdee729">back</a>() const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html">RingBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a3785129392466b941567c8b6c5f4f849">back</a>(T &amp;value) const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html">RingBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#adf1df7795354fd1fb99cb89bd54c4f93">capacity</a>() const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html">RingBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#ac8bb3912a3ce86b15842e79d0b421204">clear</a>()</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html">RingBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a644718bb2fb240de962dc3c9a1fdf0dc">empty</a>() const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html">RingBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a0920f451034bda88271b5f69bd324f5e">front</a>() const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html">RingBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a080817748fcd320c071f781b94aed283">front</a>(T &amp;value) const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html">RingBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a8abf3cf65268916fe1f1660fd9efd90a">full</a>() const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html">RingBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a44a53147d4b3600ec200300ea16e3707">pop</a>()</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html">RingBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a7e56f823fd199baf6badc044e6b7b7f2">pop</a>(T &amp;value)</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html">RingBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a1e934fd7dc8ba5c9d3e59522f05c67f8">push</a>(const T &amp;value)</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html">RingBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#ade1601ccf1fa3bcf050867f0852ca4e5">size</a>() const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html">RingBuffer&lt; T, CAPACITY &gt;</a></td><td class="entry"></td></tr>
</table></div><!-- contents -->
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
SDi toolsBox is licensed under the terms and conditions of the <a href="https://opensource.org/licenses/zlib-license.php" target="_blank">zlib/png license</a>
<br />
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE | ver: 2.x.x - build: 2026-04-28
<br />
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen" /></a> 1.9.8
</small>
</address>
</body>
</html>

View File

@@ -0,0 +1,463 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>SDi toolsBox</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="custom_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">sdi_toolBox
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',false,false,'search.php','Search');
});
/* @license-end */
</script>
<div id="main-nav"></div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="namespacesdi__toolBox.html">sdi_toolBox</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1common.html">common</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1common_1_1utils.html">utils</a></li><li class="navelem"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html">RingBuffer</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="summary">
<a href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer-members.html">List of all members</a> </div>
<div class="headertitle"><div class="title">RingBuffer&lt; T, CAPACITY &gt; Class Template Reference</div></div>
</div><!--header-->
<div class="contents">
<p><code>#include &lt;<a class="el" href="ringBuffer_8h_source.html">ringBuffer.h</a>&gt;</code></p>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><div class="compoundTemplParams">template&lt;class T, std::size_t CAPACITY&gt;<br />
class sdi_toolBox::common::utils::RingBuffer&lt; T, CAPACITY &gt;</div><p>Fixed-size ring (circular) buffer with compile-time capacity and overwrite-on-full behavior. </p>
<p>This template implements a simple circular buffer with a compile-time fixed capacity. When the buffer is full and a new element is pushed, the oldest element is overwritten.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
<table class="tparams">
<tr><td class="paramname">T</td><td>Element type stored in the buffer. </td></tr>
<tr><td class="paramname">CAPACITY</td><td>Compile-time buffer capacity. Must be &gt; 0.</td></tr>
</table>
</dd>
</dl>
<dl class="section note"><dt>Note</dt><dd>The class provides both optional-returning and out-parameter overloads for pop/front/back to suit different runtime constraints. </dd></dl>
<dl class="section warning"><dt>Warning</dt><dd>Instantiating with CAPACITY == 0 is forbidden (static_assert).</dd></dl>
<dl class="section user"><dt>Example:</dt><dd><div class="fragment"><div class="line"><a class="code hl_class" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html">RingBuffer&lt;int, 8&gt;</a> rb;</div>
<div class="line">rb.<a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a1e934fd7dc8ba5c9d3e59522f05c67f8">push</a>(1);</div>
<div class="line"><span class="keywordtype">int</span> v;</div>
<div class="line"><span class="keywordflow">if</span> (rb.<a class="code hl_function" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a44a53147d4b3600ec200300ea16e3707">pop</a>(v))</div>
<div class="line">{</div>
<div class="line"> ...</div>
<div class="line">}</div>
<div class="ttc" id="aclasssdi__toolBox_1_1common_1_1utils_1_1RingBuffer_html"><div class="ttname"><a href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html">sdi_toolBox::common::utils::RingBuffer</a></div><div class="ttdoc">Fixed-size ring (circular) buffer with compile-time capacity and overwrite-on-full behavior.</div><div class="ttdef"><b>Definition</b> <a href="ringBuffer_8h_source.html#l00049">ringBuffer.h:50</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1common_1_1utils_1_1RingBuffer_html_a1e934fd7dc8ba5c9d3e59522f05c67f8"><div class="ttname"><a href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a1e934fd7dc8ba5c9d3e59522f05c67f8">sdi_toolBox::common::utils::RingBuffer::push</a></div><div class="ttdeci">bool push(const T &amp;value)</div><div class="ttdoc">Append a value to the buffer.</div><div class="ttdef"><b>Definition</b> <a href="ringBuffer_8h_source.html#l00196">ringBuffer.h:196</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1common_1_1utils_1_1RingBuffer_html_a44a53147d4b3600ec200300ea16e3707"><div class="ttname"><a href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a44a53147d4b3600ec200300ea16e3707">sdi_toolBox::common::utils::RingBuffer::pop</a></div><div class="ttdeci">std::optional&lt; T &gt; pop()</div><div class="ttdoc">Remove and return the oldest element from the buffer.</div><div class="ttdef"><b>Definition</b> <a href="ringBuffer_8h_source.html#l00216">ringBuffer.h:216</a></div></div>
</div><!-- fragment --> </dd></dl>
<p class="definition">Definition at line <a class="el" href="ringBuffer_8h_source.html#l00049">49</a> of file <a class="el" href="ringBuffer_8h_source.html">ringBuffer.h</a>.</p>
</div><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr><td colspan="2"><div class="groupHeader">Write operations</div></td></tr>
<tr class="memitem:a1e934fd7dc8ba5c9d3e59522f05c67f8" id="r_a1e934fd7dc8ba5c9d3e59522f05c67f8"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a1e934fd7dc8ba5c9d3e59522f05c67f8">push</a> (const T &amp;value)</td></tr>
<tr class="memdesc:a1e934fd7dc8ba5c9d3e59522f05c67f8"><td class="mdescLeft">&#160;</td><td class="mdescRight">Append a value to the buffer. <br /></td></tr>
<tr class="separator:a1e934fd7dc8ba5c9d3e59522f05c67f8"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr><td colspan="2"><div class="groupHeader">Read operations</div></td></tr>
<tr class="memitem:a44a53147d4b3600ec200300ea16e3707" id="r_a44a53147d4b3600ec200300ea16e3707"><td class="memItemLeft" align="right" valign="top">std::optional&lt; T &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a44a53147d4b3600ec200300ea16e3707">pop</a> ()</td></tr>
<tr class="memdesc:a44a53147d4b3600ec200300ea16e3707"><td class="mdescLeft">&#160;</td><td class="mdescRight">Remove and return the oldest element from the buffer. <br /></td></tr>
<tr class="separator:a44a53147d4b3600ec200300ea16e3707"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a7e56f823fd199baf6badc044e6b7b7f2" id="r_a7e56f823fd199baf6badc044e6b7b7f2"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a7e56f823fd199baf6badc044e6b7b7f2">pop</a> (T &amp;value)</td></tr>
<tr class="memdesc:a7e56f823fd199baf6badc044e6b7b7f2"><td class="mdescLeft">&#160;</td><td class="mdescRight">Remove the oldest element and store it in the provided reference. <br /></td></tr>
<tr class="separator:a7e56f823fd199baf6badc044e6b7b7f2"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a0920f451034bda88271b5f69bd324f5e" id="r_a0920f451034bda88271b5f69bd324f5e"><td class="memItemLeft" align="right" valign="top">std::optional&lt; T &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a0920f451034bda88271b5f69bd324f5e">front</a> () const</td></tr>
<tr class="memdesc:a0920f451034bda88271b5f69bd324f5e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Return (without removing) the oldest element. <br /></td></tr>
<tr class="separator:a0920f451034bda88271b5f69bd324f5e"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a080817748fcd320c071f781b94aed283" id="r_a080817748fcd320c071f781b94aed283"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a080817748fcd320c071f781b94aed283">front</a> (T &amp;value) const</td></tr>
<tr class="memdesc:a080817748fcd320c071f781b94aed283"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy the oldest element into the provided reference without removing it. <br /></td></tr>
<tr class="separator:a080817748fcd320c071f781b94aed283"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ab663c689eb6ec5369a0c6e33dfdee729" id="r_ab663c689eb6ec5369a0c6e33dfdee729"><td class="memItemLeft" align="right" valign="top">std::optional&lt; T &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#ab663c689eb6ec5369a0c6e33dfdee729">back</a> () const</td></tr>
<tr class="memdesc:ab663c689eb6ec5369a0c6e33dfdee729"><td class="mdescLeft">&#160;</td><td class="mdescRight">Return (without removing) the newest element. <br /></td></tr>
<tr class="separator:ab663c689eb6ec5369a0c6e33dfdee729"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a3785129392466b941567c8b6c5f4f849" id="r_a3785129392466b941567c8b6c5f4f849"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a3785129392466b941567c8b6c5f4f849">back</a> (T &amp;value) const</td></tr>
<tr class="memdesc:a3785129392466b941567c8b6c5f4f849"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy the newest element into the provided reference without removing it. <br /></td></tr>
<tr class="separator:a3785129392466b941567c8b6c5f4f849"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr><td colspan="2"><div class="groupHeader">State queries</div></td></tr>
<tr class="memitem:a644718bb2fb240de962dc3c9a1fdf0dc" id="r_a644718bb2fb240de962dc3c9a1fdf0dc"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a644718bb2fb240de962dc3c9a1fdf0dc">empty</a> () const</td></tr>
<tr class="memdesc:a644718bb2fb240de962dc3c9a1fdf0dc"><td class="mdescLeft">&#160;</td><td class="mdescRight">Check whether the buffer is empty. <br /></td></tr>
<tr class="separator:a644718bb2fb240de962dc3c9a1fdf0dc"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a8abf3cf65268916fe1f1660fd9efd90a" id="r_a8abf3cf65268916fe1f1660fd9efd90a"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a8abf3cf65268916fe1f1660fd9efd90a">full</a> () const</td></tr>
<tr class="memdesc:a8abf3cf65268916fe1f1660fd9efd90a"><td class="mdescLeft">&#160;</td><td class="mdescRight">Check whether the buffer is full. <br /></td></tr>
<tr class="separator:a8abf3cf65268916fe1f1660fd9efd90a"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ade1601ccf1fa3bcf050867f0852ca4e5" id="r_ade1601ccf1fa3bcf050867f0852ca4e5"><td class="memItemLeft" align="right" valign="top">std::size_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#ade1601ccf1fa3bcf050867f0852ca4e5">size</a> () const</td></tr>
<tr class="memdesc:ade1601ccf1fa3bcf050867f0852ca4e5"><td class="mdescLeft">&#160;</td><td class="mdescRight">Number of elements currently stored in the buffer. <br /></td></tr>
<tr class="separator:ade1601ccf1fa3bcf050867f0852ca4e5"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:adf1df7795354fd1fb99cb89bd54c4f93" id="r_adf1df7795354fd1fb99cb89bd54c4f93"><td class="memItemLeft" align="right" valign="top">constexpr std::size_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#adf1df7795354fd1fb99cb89bd54c4f93">capacity</a> () const</td></tr>
<tr class="memdesc:adf1df7795354fd1fb99cb89bd54c4f93"><td class="mdescLeft">&#160;</td><td class="mdescRight">Compile-time capacity of the buffer. <br /></td></tr>
<tr class="separator:adf1df7795354fd1fb99cb89bd54c4f93"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr><td colspan="2"><div class="groupHeader">Modifiers</div></td></tr>
<tr class="memitem:ac8bb3912a3ce86b15842e79d0b421204" id="r_ac8bb3912a3ce86b15842e79d0b421204"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#ac8bb3912a3ce86b15842e79d0b421204">clear</a> ()</td></tr>
<tr class="memdesc:ac8bb3912a3ce86b15842e79d0b421204"><td class="mdescLeft">&#160;</td><td class="mdescRight">Clear the buffer and reset internal indices. <br /></td></tr>
<tr class="separator:ac8bb3912a3ce86b15842e79d0b421204"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<h2 class="groupheader">Member Function Documentation</h2>
<a id="a1e934fd7dc8ba5c9d3e59522f05c67f8" name="a1e934fd7dc8ba5c9d3e59522f05c67f8"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a1e934fd7dc8ba5c9d3e59522f05c67f8">&#9670;&#160;</a></span>push()</h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">bool push </td>
<td>(</td>
<td class="paramtype">const T &amp;&#160;</td>
<td class="paramname"><em>value</em></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Append a value to the buffer. </p>
<p>If the buffer is full, the oldest element is overwritten. </p><dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">value</td><td>Value to append (copied).</td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>true if the value was added without overwriting, false if an overwrite occurred. </dd></dl>
<p class="definition">Definition at line <a class="el" href="ringBuffer_8h_source.html#l00196">196</a> of file <a class="el" href="ringBuffer_8h_source.html">ringBuffer.h</a>.</p>
</div>
</div>
<a id="a44a53147d4b3600ec200300ea16e3707" name="a44a53147d4b3600ec200300ea16e3707"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a44a53147d4b3600ec200300ea16e3707">&#9670;&#160;</a></span>pop() <span class="overload">[1/2]</span></h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">std::optional&lt; T &gt; pop </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Remove and return the oldest element from the buffer. </p>
<dl class="section return"><dt>Returns</dt><dd>std::optional&lt;T&gt; The oldest element if present, std::nullopt if empty. </dd></dl>
<p class="definition">Definition at line <a class="el" href="ringBuffer_8h_source.html#l00216">216</a> of file <a class="el" href="ringBuffer_8h_source.html">ringBuffer.h</a>.</p>
</div>
</div>
<a id="a7e56f823fd199baf6badc044e6b7b7f2" name="a7e56f823fd199baf6badc044e6b7b7f2"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a7e56f823fd199baf6badc044e6b7b7f2">&#9670;&#160;</a></span>pop() <span class="overload">[2/2]</span></h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">bool pop </td>
<td>(</td>
<td class="paramtype">T &amp;&#160;</td>
<td class="paramname"><em>value</em></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Remove the oldest element and store it in the provided reference. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">value</td><td>Output reference that receives the removed element.</td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>true if an element was removed, false if the buffer was empty. </dd></dl>
<p class="definition">Definition at line <a class="el" href="ringBuffer_8h_source.html#l00229">229</a> of file <a class="el" href="ringBuffer_8h_source.html">ringBuffer.h</a>.</p>
</div>
</div>
<a id="a0920f451034bda88271b5f69bd324f5e" name="a0920f451034bda88271b5f69bd324f5e"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a0920f451034bda88271b5f69bd324f5e">&#9670;&#160;</a></span>front() <span class="overload">[1/2]</span></h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">std::optional&lt; T &gt; front </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Return (without removing) the oldest element. </p>
<dl class="section return"><dt>Returns</dt><dd>std::optional&lt;T&gt; The oldest element if present, std::nullopt if empty. </dd></dl>
<p class="definition">Definition at line <a class="el" href="ringBuffer_8h_source.html#l00243">243</a> of file <a class="el" href="ringBuffer_8h_source.html">ringBuffer.h</a>.</p>
</div>
</div>
<a id="a080817748fcd320c071f781b94aed283" name="a080817748fcd320c071f781b94aed283"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a080817748fcd320c071f781b94aed283">&#9670;&#160;</a></span>front() <span class="overload">[2/2]</span></h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">bool front </td>
<td>(</td>
<td class="paramtype">T &amp;&#160;</td>
<td class="paramname"><em>value</em></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Copy the oldest element into the provided reference without removing it. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">value</td><td>Output reference that receives the element.</td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>true if the element was copied, false if the buffer is empty. </dd></dl>
<p class="definition">Definition at line <a class="el" href="ringBuffer_8h_source.html#l00253">253</a> of file <a class="el" href="ringBuffer_8h_source.html">ringBuffer.h</a>.</p>
</div>
</div>
<a id="ab663c689eb6ec5369a0c6e33dfdee729" name="ab663c689eb6ec5369a0c6e33dfdee729"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ab663c689eb6ec5369a0c6e33dfdee729">&#9670;&#160;</a></span>back() <span class="overload">[1/2]</span></h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">std::optional&lt; T &gt; back </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Return (without removing) the newest element. </p>
<dl class="section return"><dt>Returns</dt><dd>std::optional&lt;T&gt; The newest element if present, std::nullopt if empty. </dd></dl>
<p class="definition">Definition at line <a class="el" href="ringBuffer_8h_source.html#l00264">264</a> of file <a class="el" href="ringBuffer_8h_source.html">ringBuffer.h</a>.</p>
</div>
</div>
<a id="a3785129392466b941567c8b6c5f4f849" name="a3785129392466b941567c8b6c5f4f849"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a3785129392466b941567c8b6c5f4f849">&#9670;&#160;</a></span>back() <span class="overload">[2/2]</span></h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">bool back </td>
<td>(</td>
<td class="paramtype">T &amp;&#160;</td>
<td class="paramname"><em>value</em></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Copy the newest element into the provided reference without removing it. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">value</td><td>Output reference that receives the element.</td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>true if the element was copied, false if the buffer is empty. </dd></dl>
<p class="definition">Definition at line <a class="el" href="ringBuffer_8h_source.html#l00274">274</a> of file <a class="el" href="ringBuffer_8h_source.html">ringBuffer.h</a>.</p>
</div>
</div>
<a id="a644718bb2fb240de962dc3c9a1fdf0dc" name="a644718bb2fb240de962dc3c9a1fdf0dc"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a644718bb2fb240de962dc3c9a1fdf0dc">&#9670;&#160;</a></span>empty()</h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">bool empty </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Check whether the buffer is empty. </p>
<dl class="section return"><dt>Returns</dt><dd>true if empty, false otherwise. </dd></dl>
<p class="definition">Definition at line <a class="el" href="ringBuffer_8h_source.html#l00285">285</a> of file <a class="el" href="ringBuffer_8h_source.html">ringBuffer.h</a>.</p>
</div>
</div>
<a id="a8abf3cf65268916fe1f1660fd9efd90a" name="a8abf3cf65268916fe1f1660fd9efd90a"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a8abf3cf65268916fe1f1660fd9efd90a">&#9670;&#160;</a></span>full()</h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">bool full </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Check whether the buffer is full. </p>
<dl class="section return"><dt>Returns</dt><dd>true if full, false otherwise. </dd></dl>
<p class="definition">Definition at line <a class="el" href="ringBuffer_8h_source.html#l00292">292</a> of file <a class="el" href="ringBuffer_8h_source.html">ringBuffer.h</a>.</p>
</div>
</div>
<a id="ade1601ccf1fa3bcf050867f0852ca4e5" name="ade1601ccf1fa3bcf050867f0852ca4e5"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ade1601ccf1fa3bcf050867f0852ca4e5">&#9670;&#160;</a></span>size()</h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">std::size_t size </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Number of elements currently stored in the buffer. </p>
<dl class="section return"><dt>Returns</dt><dd>Current size (0 .. CAPACITY). </dd></dl>
<p class="definition">Definition at line <a class="el" href="ringBuffer_8h_source.html#l00299">299</a> of file <a class="el" href="ringBuffer_8h_source.html">ringBuffer.h</a>.</p>
</div>
</div>
<a id="adf1df7795354fd1fb99cb89bd54c4f93" name="adf1df7795354fd1fb99cb89bd54c4f93"></a>
<h2 class="memtitle"><span class="permalink"><a href="#adf1df7795354fd1fb99cb89bd54c4f93">&#9670;&#160;</a></span>capacity()</h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">constexpr std::size_t capacity </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td> const</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">constexpr</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Compile-time capacity of the buffer. </p>
<dl class="section return"><dt>Returns</dt><dd>The maximum number of elements the buffer can hold. </dd></dl>
<p class="definition">Definition at line <a class="el" href="ringBuffer_8h_source.html#l00310">310</a> of file <a class="el" href="ringBuffer_8h_source.html">ringBuffer.h</a>.</p>
</div>
</div>
<a id="ac8bb3912a3ce86b15842e79d0b421204" name="ac8bb3912a3ce86b15842e79d0b421204"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ac8bb3912a3ce86b15842e79d0b421204">&#9670;&#160;</a></span>clear()</h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , std::size_t CAPACITY&gt; </div>
<table class="memname">
<tr>
<td class="memname">void clear </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Clear the buffer and reset internal indices. </p>
<p>After calling <a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#ac8bb3912a3ce86b15842e79d0b421204" title="Clear the buffer and reset internal indices.">clear()</a>, <a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#a644718bb2fb240de962dc3c9a1fdf0dc" title="Check whether the buffer is empty.">empty()</a> returns true and <a class="el" href="classsdi__toolBox_1_1common_1_1utils_1_1RingBuffer.html#ade1601ccf1fa3bcf050867f0852ca4e5" title="Number of elements currently stored in the buffer.">size()</a> returns 0. </p>
<p class="definition">Definition at line <a class="el" href="ringBuffer_8h_source.html#l00317">317</a> of file <a class="el" href="ringBuffer_8h_source.html">ringBuffer.h</a>.</p>
</div>
</div>
</div><!-- contents -->
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
SDi toolsBox is licensed under the terms and conditions of the <a href="https://opensource.org/licenses/zlib-license.php" target="_blank">zlib/png license</a>
<br />
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE | ver: 2.x.x - build: 2026-04-28
<br />
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen" /></a> 1.9.8
</small>
</address>
</body>
</html>

View File

@@ -0,0 +1,87 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>SDi toolsBox</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="custom_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">sdi_toolBox
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',false,false,'search.php','Search');
});
/* @license-end */
</script>
<div id="main-nav"></div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="namespacesdi__toolBox.html">sdi_toolBox</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1desktop.html">desktop</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html">eventBus</a></li><li class="navelem"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle"><div class="title">Bus Member List</div></div>
</div><!--header-->
<div class="contents">
<p>This is the complete list of members for <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a>, including all inherited members.</p>
<table class="directory">
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a3c682b9a6b53418d7a147960e6dcdad1">broadcastNodeList</a></td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a29358764c7d91cfcf3447e93b43bb20f">Bus</a>()</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a472403c9840a1d19c264c55f00070a3e">Bus</a>(const Bus &amp;obj)=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a422f08b55d205f02a11025e753679555">Bus</a>(Bus &amp;&amp;obj) noexcept=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ab06a20c7848eddbcc910d5b03ea98f20">clearAllSubscriptions</a>()</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a9aab57a60533a1a80a705bc569a9c589">emit</a>(Args &amp;&amp;...args)</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a8574031338c5bf7827cc0d561ed93171">isSubscribed</a>(const INode *node, MessageTypeID eventType) const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a7b375afd6d8b416cfd37e3bfce5b8ffd">isSubscribedToBroadcast</a>(INode *node) const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ad5e0dbd36f0d71fce9b00b7f991b2f38">mtx</a></td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td><td class="entry"><span class="mlabel">mutable</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a6db9d28bd448a131448276ee03de1e6d">Node</a></td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td><td class="entry"><span class="mlabel">friend</span></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a4bc64bd8db5527dc8af9b458a82d6a65">nodeList</a></td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#afc5179367040f25bcdb4e27d5682168b">operator=</a>(const Bus &amp;obj)=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ad0f453f147d8e394a5b66b8494564a82">operator=</a>(Bus &amp;&amp;obj) noexcept=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a92c2bc8aa8bcf018ffe954a3e8e34324">post</a>(const std::shared_ptr&lt; Message &gt; &amp;message) const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#aaed1ce9185dbc68270991a68901e1d3e">subscribe</a>(INode *node, MessageTypeID eventType)</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a309bedf4b2fb78c99de024ece1f39eb5">subscribeToBroadcast</a>(INode *node)</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a27cc2e333f174e22b360045c7aad959d">unsubscribe</a>(INode *node, MessageTypeID eventType)</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#af42df59cac80896d270e4bf2b350676f">unsubscribeFromAll</a>(INode *node)</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ae9c37a95472381e33190bd951e381ebe">unsubscribeFromBroadcast</a>(INode *node)</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#aaf1361cfa73ea4f24a5182e4aaf7f6e3">~Bus</a>()=default</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td><td class="entry"></td></tr>
</table></div><!-- contents -->
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
SDi toolsBox is licensed under the terms and conditions of the <a href="https://opensource.org/licenses/zlib-license.php" target="_blank">zlib/png license</a>
<br />
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE | ver: 2.x.x - build: 2026-04-28
<br />
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen" /></a> 1.9.8
</small>
</address>
</body>
</html>

View File

@@ -0,0 +1,879 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>SDi toolsBox</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="custom_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">sdi_toolBox
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',false,false,'search.php','Search');
});
/* @license-end */
</script>
<div id="main-nav"></div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="namespacesdi__toolBox.html">sdi_toolBox</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1desktop.html">desktop</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html">eventBus</a></li><li class="navelem"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="summary">
<a href="#friends">Friends</a> &#124;
<a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus-members.html">List of all members</a> </div>
<div class="headertitle"><div class="title">Bus Class Reference<span class="mlabels"><span class="mlabel">final</span></span></div></div>
</div><!--header-->
<div class="contents">
<p><code>#include &lt;<a class="el" href="bus_8h_source.html">bus.h</a>&gt;</code></p>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p>Central message dispatcher for the event bus system. </p>
<p>The <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html" title="Central message dispatcher for the event bus system.">Bus</a> class is the core component of the event bus architecture. It manages a routing table that maps message type identifiers to lists of subscribed nodes, and dispatches messages to the appropriate nodes when they are emitted or posted.</p>
<p>Nodes can subscribe to specific message types or to broadcast mode, in which case they receive all messages regardless of their type.</p>
<p>The <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html" title="Central message dispatcher for the event bus system.">Bus</a> is thread-safe: all operations on the routing table are protected by an internal mutex.</p>
<dl class="section note"><dt>Note</dt><dd>The <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html" title="Central message dispatcher for the event bus system.">Bus</a> is non-copyable and non-movable. </dd>
<dd>
The <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html" title="Central message dispatcher for the event bus system.">Bus</a> does not take ownership of the nodes it manages.</dd></dl>
<dl class="section user"><dt>Example usage:</dt><dd><div class="fragment"><div class="line"><a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">sdi_toolBox::desktop::eventBus::Bus</a> bus;</div>
<div class="line"><a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">sdi_toolBox::desktop::eventBus::Node</a> node(bus);</div>
<div class="line"> </div>
<div class="line">node.subscribe(MY_EVENT_TYPE);</div>
<div class="line">bus.<a class="code hl_function" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a9aab57a60533a1a80a705bc569a9c589">emit</a>&lt;MyMessage&gt;(arg1, arg2);</div>
<div class="line"> </div>
<div class="line"><span class="keyword">auto</span> msg = std::dynamic_pointer_cast&lt;MyMessage&gt;(node.popMessage());</div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">sdi_toolBox::desktop::eventBus::Bus</a></div><div class="ttdoc">Central message dispatcher for the event bus system.</div><div class="ttdef"><b>Definition</b> <a href="bus_8h_source.html#l00062">bus.h:63</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html_a9aab57a60533a1a80a705bc569a9c589"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a9aab57a60533a1a80a705bc569a9c589">sdi_toolBox::desktop::eventBus::Bus::emit</a></div><div class="ttdeci">bool emit(Args &amp;&amp;...args)</div><div class="ttdoc">Construct and emit a message of type T to the bus.</div><div class="ttdef"><b>Definition</b> <a href="bus_8h_source.html#l00445">bus.h:445</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Node_html"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">sdi_toolBox::desktop::eventBus::Node</a></div><div class="ttdoc">Concrete subscriber node in the event bus system.</div><div class="ttdef"><b>Definition</b> <a href="node_8h_source.html#l00063">node.h:64</a></div></div>
</div><!-- fragment --></dd></dl>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" title="Concrete subscriber node in the event bus system.">Node</a> </dd>
<dd>
<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html" title="Abstract interface representing a subscriber node in the event bus system.">INode</a> </dd>
<dd>
<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html" title="Base class for all messages dispatched through the event bus.">Message</a> </dd></dl>
<p class="definition">Definition at line <a class="el" href="bus_8h_source.html#l00062">62</a> of file <a class="el" href="bus_8h_source.html">bus.h</a>.</p>
</div><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr><td colspan="2"><div class="groupHeader">Construction &amp; Destruction</div></td></tr>
<tr class="memitem:a29358764c7d91cfcf3447e93b43bb20f" id="r_a29358764c7d91cfcf3447e93b43bb20f"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a29358764c7d91cfcf3447e93b43bb20f">Bus</a> ()</td></tr>
<tr class="memdesc:a29358764c7d91cfcf3447e93b43bb20f"><td class="mdescLeft">&#160;</td><td class="mdescRight">Default constructor. <br /></td></tr>
<tr class="separator:a29358764c7d91cfcf3447e93b43bb20f"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aaf1361cfa73ea4f24a5182e4aaf7f6e3" id="r_aaf1361cfa73ea4f24a5182e4aaf7f6e3"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#aaf1361cfa73ea4f24a5182e4aaf7f6e3">~Bus</a> ()=default</td></tr>
<tr class="memdesc:aaf1361cfa73ea4f24a5182e4aaf7f6e3"><td class="mdescLeft">&#160;</td><td class="mdescRight">Default destructor. <br /></td></tr>
<tr class="separator:aaf1361cfa73ea4f24a5182e4aaf7f6e3"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a472403c9840a1d19c264c55f00070a3e" id="r_a472403c9840a1d19c264c55f00070a3e"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a472403c9840a1d19c264c55f00070a3e">Bus</a> (const <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> &amp;obj)=delete</td></tr>
<tr class="memdesc:a472403c9840a1d19c264c55f00070a3e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy constructor - deleted. <br /></td></tr>
<tr class="separator:a472403c9840a1d19c264c55f00070a3e"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a422f08b55d205f02a11025e753679555" id="r_a422f08b55d205f02a11025e753679555"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a422f08b55d205f02a11025e753679555">Bus</a> (<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> &amp;&amp;obj) noexcept=delete</td></tr>
<tr class="memdesc:a422f08b55d205f02a11025e753679555"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move constructor - deleted. <br /></td></tr>
<tr class="separator:a422f08b55d205f02a11025e753679555"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:afc5179367040f25bcdb4e27d5682168b" id="r_afc5179367040f25bcdb4e27d5682168b"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#afc5179367040f25bcdb4e27d5682168b">operator=</a> (const <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> &amp;obj)=delete</td></tr>
<tr class="memdesc:afc5179367040f25bcdb4e27d5682168b"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy assignment operator - deleted. <br /></td></tr>
<tr class="separator:afc5179367040f25bcdb4e27d5682168b"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ad0f453f147d8e394a5b66b8494564a82" id="r_ad0f453f147d8e394a5b66b8494564a82"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ad0f453f147d8e394a5b66b8494564a82">operator=</a> (<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> &amp;&amp;obj) noexcept=delete</td></tr>
<tr class="memdesc:ad0f453f147d8e394a5b66b8494564a82"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move assignment operator - deleted. <br /></td></tr>
<tr class="separator:ad0f453f147d8e394a5b66b8494564a82"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr><td colspan="2"><div class="groupHeader">Subscription Management</div></td></tr>
<tr class="memitem:ab06a20c7848eddbcc910d5b03ea98f20" id="r_ab06a20c7848eddbcc910d5b03ea98f20"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ab06a20c7848eddbcc910d5b03ea98f20">clearAllSubscriptions</a> ()</td></tr>
<tr class="memdesc:ab06a20c7848eddbcc910d5b03ea98f20"><td class="mdescLeft">&#160;</td><td class="mdescRight">Remove all subscriptions from the routing table. <br /></td></tr>
<tr class="separator:ab06a20c7848eddbcc910d5b03ea98f20"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aaed1ce9185dbc68270991a68901e1d3e" id="r_aaed1ce9185dbc68270991a68901e1d3e"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#aaed1ce9185dbc68270991a68901e1d3e">subscribe</a> (<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node, <a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a> eventType)</td></tr>
<tr class="memdesc:aaed1ce9185dbc68270991a68901e1d3e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Subscribe a node to a specific message type. <br /></td></tr>
<tr class="separator:aaed1ce9185dbc68270991a68901e1d3e"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a27cc2e333f174e22b360045c7aad959d" id="r_a27cc2e333f174e22b360045c7aad959d"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a27cc2e333f174e22b360045c7aad959d">unsubscribe</a> (<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node, <a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a> eventType)</td></tr>
<tr class="memdesc:a27cc2e333f174e22b360045c7aad959d"><td class="mdescLeft">&#160;</td><td class="mdescRight">Unsubscribe a node from a specific message type. <br /></td></tr>
<tr class="separator:a27cc2e333f174e22b360045c7aad959d"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af42df59cac80896d270e4bf2b350676f" id="r_af42df59cac80896d270e4bf2b350676f"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#af42df59cac80896d270e4bf2b350676f">unsubscribeFromAll</a> (<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node)</td></tr>
<tr class="memdesc:af42df59cac80896d270e4bf2b350676f"><td class="mdescLeft">&#160;</td><td class="mdescRight">Unsubscribe a node from all message types and broadcast mode. <br /></td></tr>
<tr class="separator:af42df59cac80896d270e4bf2b350676f"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a8574031338c5bf7827cc0d561ed93171" id="r_a8574031338c5bf7827cc0d561ed93171"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a8574031338c5bf7827cc0d561ed93171">isSubscribed</a> (const <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node, <a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a> eventType) const</td></tr>
<tr class="memdesc:a8574031338c5bf7827cc0d561ed93171"><td class="mdescLeft">&#160;</td><td class="mdescRight">Check whether a node is subscribed to a specific message type. <br /></td></tr>
<tr class="separator:a8574031338c5bf7827cc0d561ed93171"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr><td colspan="2"><div class="groupHeader">Broadcast management</div></td></tr>
<tr class="memitem:a309bedf4b2fb78c99de024ece1f39eb5" id="r_a309bedf4b2fb78c99de024ece1f39eb5"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a309bedf4b2fb78c99de024ece1f39eb5">subscribeToBroadcast</a> (<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node)</td></tr>
<tr class="memdesc:a309bedf4b2fb78c99de024ece1f39eb5"><td class="mdescLeft">&#160;</td><td class="mdescRight">Subscribe a node to broadcast mode. <br /></td></tr>
<tr class="separator:a309bedf4b2fb78c99de024ece1f39eb5"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ae9c37a95472381e33190bd951e381ebe" id="r_ae9c37a95472381e33190bd951e381ebe"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#ae9c37a95472381e33190bd951e381ebe">unsubscribeFromBroadcast</a> (<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node)</td></tr>
<tr class="memdesc:ae9c37a95472381e33190bd951e381ebe"><td class="mdescLeft">&#160;</td><td class="mdescRight">Unsubscribe a node from broadcast mode. <br /></td></tr>
<tr class="separator:ae9c37a95472381e33190bd951e381ebe"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a7b375afd6d8b416cfd37e3bfce5b8ffd" id="r_a7b375afd6d8b416cfd37e3bfce5b8ffd"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a7b375afd6d8b416cfd37e3bfce5b8ffd">isSubscribedToBroadcast</a> (<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *node) const</td></tr>
<tr class="memdesc:a7b375afd6d8b416cfd37e3bfce5b8ffd"><td class="mdescLeft">&#160;</td><td class="mdescRight">Check whether a node is subscribed to broadcast mode. <br /></td></tr>
<tr class="separator:a7b375afd6d8b416cfd37e3bfce5b8ffd"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr><td colspan="2"><div class="groupHeader">Message transmission</div></td></tr>
<tr class="memitem:a9aab57a60533a1a80a705bc569a9c589" id="r_a9aab57a60533a1a80a705bc569a9c589"><td class="memTemplParams" colspan="2">template&lt;class T , class... Args&gt; </td></tr>
<tr class="memitem:a9aab57a60533a1a80a705bc569a9c589"><td class="memTemplItemLeft" align="right" valign="top">bool&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a9aab57a60533a1a80a705bc569a9c589">emit</a> (Args &amp;&amp;...args)</td></tr>
<tr class="memdesc:a9aab57a60533a1a80a705bc569a9c589"><td class="mdescLeft">&#160;</td><td class="mdescRight">Construct and emit a message of type <code>T</code> to the bus. <br /></td></tr>
<tr class="separator:a9aab57a60533a1a80a705bc569a9c589"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a92c2bc8aa8bcf018ffe954a3e8e34324" id="r_a92c2bc8aa8bcf018ffe954a3e8e34324"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a92c2bc8aa8bcf018ffe954a3e8e34324">post</a> (const std::shared_ptr&lt; <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &gt; &amp;message) const</td></tr>
<tr class="memdesc:a92c2bc8aa8bcf018ffe954a3e8e34324"><td class="mdescLeft">&#160;</td><td class="mdescRight">Post an already constructed message to the bus. <br /></td></tr>
<tr class="separator:a92c2bc8aa8bcf018ffe954a3e8e34324"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="friends" name="friends"></a>
Friends</h2></td></tr>
<tr class="memitem:a6db9d28bd448a131448276ee03de1e6d" id="r_a6db9d28bd448a131448276ee03de1e6d"><td class="memItemLeft" align="right" valign="top">class&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a6db9d28bd448a131448276ee03de1e6d">Node</a></td></tr>
<tr class="memdesc:a6db9d28bd448a131448276ee03de1e6d"><td class="mdescLeft">&#160;</td><td class="mdescRight">Allow the <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" title="Concrete subscriber node in the event bus system.">Node</a> class to access private members. <br /></td></tr>
<tr class="separator:a6db9d28bd448a131448276ee03de1e6d"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
<a id="a29358764c7d91cfcf3447e93b43bb20f" name="a29358764c7d91cfcf3447e93b43bb20f"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a29358764c7d91cfcf3447e93b43bb20f">&#9670;&#160;</a></span>Bus() <span class="overload">[1/3]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Default constructor. </p>
<p>Initializes the <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html" title="Central message dispatcher for the event bus system.">Bus</a> and records the construction timestamp used as the bus start reference time. </p>
<p class="definition">Definition at line <a class="el" href="bus_8h_source.html#l00312">312</a> of file <a class="el" href="bus_8h_source.html">bus.h</a>.</p>
</div>
</div>
<a id="aaf1361cfa73ea4f24a5182e4aaf7f6e3" name="aaf1361cfa73ea4f24a5182e4aaf7f6e3"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aaf1361cfa73ea4f24a5182e4aaf7f6e3">&#9670;&#160;</a></span>~Bus()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">~<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">default</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Default destructor. </p>
</div>
</div>
<a id="a472403c9840a1d19c264c55f00070a3e" name="a472403c9840a1d19c264c55f00070a3e"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a472403c9840a1d19c264c55f00070a3e">&#9670;&#160;</a></span>Bus() <span class="overload">[2/3]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> &amp;&#160;</td>
<td class="paramname"><em>obj</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">delete</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Copy constructor - deleted. </p>
<p>The <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html" title="Central message dispatcher for the event bus system.">Bus</a> is non-copyable. </p>
</div>
</div>
<a id="a422f08b55d205f02a11025e753679555" name="a422f08b55d205f02a11025e753679555"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a422f08b55d205f02a11025e753679555">&#9670;&#160;</a></span>Bus() <span class="overload">[3/3]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> </td>
<td>(</td>
<td class="paramtype"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> &amp;&amp;&#160;</td>
<td class="paramname"><em>obj</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">delete</span><span class="mlabel">noexcept</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Move constructor - deleted. </p>
<p>The <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html" title="Central message dispatcher for the event bus system.">Bus</a> is non-movable. </p>
</div>
</div>
<h2 class="groupheader">Member Function Documentation</h2>
<a id="afc5179367040f25bcdb4e27d5682168b" name="afc5179367040f25bcdb4e27d5682168b"></a>
<h2 class="memtitle"><span class="permalink"><a href="#afc5179367040f25bcdb4e27d5682168b">&#9670;&#160;</a></span>operator=() <span class="overload">[1/2]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> &amp; operator= </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> &amp;&#160;</td>
<td class="paramname"><em>obj</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">delete</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Copy assignment operator - deleted. </p>
<p>The <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html" title="Central message dispatcher for the event bus system.">Bus</a> is non-copyable. </p>
</div>
</div>
<a id="ad0f453f147d8e394a5b66b8494564a82" name="ad0f453f147d8e394a5b66b8494564a82"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ad0f453f147d8e394a5b66b8494564a82">&#9670;&#160;</a></span>operator=() <span class="overload">[2/2]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> &amp; operator= </td>
<td>(</td>
<td class="paramtype"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> &amp;&amp;&#160;</td>
<td class="paramname"><em>obj</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">delete</span><span class="mlabel">noexcept</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Move assignment operator - deleted. </p>
<p>The <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html" title="Central message dispatcher for the event bus system.">Bus</a> is non-movable. </p>
</div>
</div>
<a id="ab06a20c7848eddbcc910d5b03ea98f20" name="ab06a20c7848eddbcc910d5b03ea98f20"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ab06a20c7848eddbcc910d5b03ea98f20">&#9670;&#160;</a></span>clearAllSubscriptions()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">void clearAllSubscriptions </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Remove all subscriptions from the routing table. </p>
<p>Clears both the specific event subscriptions and the broadcast subscription list. After this call, no node will receive any message until it re-subscribes.</p>
<dl class="section note"><dt>Note</dt><dd>This operation is thread-safe. </dd></dl>
<p class="definition">Definition at line <a class="el" href="bus_8h_source.html#l00319">319</a> of file <a class="el" href="bus_8h_source.html">bus.h</a>.</p>
</div>
</div>
<a id="aaed1ce9185dbc68270991a68901e1d3e" name="aaed1ce9185dbc68270991a68901e1d3e"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aaed1ce9185dbc68270991a68901e1d3e">&#9670;&#160;</a></span>subscribe()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">void subscribe </td>
<td>(</td>
<td class="paramtype"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *&#160;</td>
<td class="paramname"><em>node</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype"><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a>&#160;</td>
<td class="paramname"><em>eventType</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Subscribe a node to a specific message type. </p>
<p>Registers the given node to receive messages of the specified type. If the node is already subscribed to this type, this call has no effect (no duplicates are created).</p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">node</td><td>Pointer to the node to subscribe. Must not be <code>nullptr</code>. </td></tr>
<tr><td class="paramname">eventType</td><td>The message type identifier to subscribe to.</td></tr>
</table>
</dd>
</dl>
<dl class="exception"><dt>Exceptions</dt><dd>
<table class="exception">
<tr><td class="paramname">std::runtime_error</td><td>if <code>node</code> is <code>nullptr</code>. </td></tr>
</table>
</dd>
</dl>
<dl class="section note"><dt>Note</dt><dd>This operation is thread-safe. </dd></dl>
<p class="definition">Definition at line <a class="el" href="bus_8h_source.html#l00328">328</a> of file <a class="el" href="bus_8h_source.html">bus.h</a>.</p>
</div>
</div>
<a id="a27cc2e333f174e22b360045c7aad959d" name="a27cc2e333f174e22b360045c7aad959d"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a27cc2e333f174e22b360045c7aad959d">&#9670;&#160;</a></span>unsubscribe()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">void unsubscribe </td>
<td>(</td>
<td class="paramtype"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *&#160;</td>
<td class="paramname"><em>node</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype"><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a>&#160;</td>
<td class="paramname"><em>eventType</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Unsubscribe a node from a specific message type. </p>
<p>Removes the given node from the list of subscribers for the specified message type. If the node was not subscribed to this type, this call has no effect.</p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">node</td><td>Pointer to the node to unsubscribe. Must not be <code>nullptr</code>. </td></tr>
<tr><td class="paramname">eventType</td><td>The message type identifier to unsubscribe from.</td></tr>
</table>
</dd>
</dl>
<dl class="exception"><dt>Exceptions</dt><dd>
<table class="exception">
<tr><td class="paramname">std::runtime_error</td><td>if <code>node</code> is <code>nullptr</code>. </td></tr>
</table>
</dd>
</dl>
<dl class="section note"><dt>Note</dt><dd>This operation is thread-safe. </dd></dl>
<p class="definition">Definition at line <a class="el" href="bus_8h_source.html#l00352">352</a> of file <a class="el" href="bus_8h_source.html">bus.h</a>.</p>
</div>
</div>
<a id="af42df59cac80896d270e4bf2b350676f" name="af42df59cac80896d270e4bf2b350676f"></a>
<h2 class="memtitle"><span class="permalink"><a href="#af42df59cac80896d270e4bf2b350676f">&#9670;&#160;</a></span>unsubscribeFromAll()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">void unsubscribeFromAll </td>
<td>(</td>
<td class="paramtype"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *&#160;</td>
<td class="paramname"><em>node</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Unsubscribe a node from all message types and broadcast mode. </p>
<p>Removes the given node from all specific event subscription lists and from the broadcast subscription list. This is automatically called by the <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" title="Concrete subscriber node in the event bus system.">Node</a> destructor to ensure no dangling pointers remain in the routing table.</p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">node</td><td>Pointer to the node to unsubscribe. Must not be <code>nullptr</code>.</td></tr>
</table>
</dd>
</dl>
<dl class="exception"><dt>Exceptions</dt><dd>
<table class="exception">
<tr><td class="paramname">std::runtime_error</td><td>if <code>node</code> is <code>nullptr</code>. </td></tr>
</table>
</dd>
</dl>
<dl class="section note"><dt>Note</dt><dd>This operation is thread-safe. </dd></dl>
<p class="definition">Definition at line <a class="el" href="bus_8h_source.html#l00370">370</a> of file <a class="el" href="bus_8h_source.html">bus.h</a>.</p>
</div>
</div>
<a id="a8574031338c5bf7827cc0d561ed93171" name="a8574031338c5bf7827cc0d561ed93171"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a8574031338c5bf7827cc0d561ed93171">&#9670;&#160;</a></span>isSubscribed()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">bool isSubscribed </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *&#160;</td>
<td class="paramname"><em>node</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype"><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a>&#160;</td>
<td class="paramname"><em>eventType</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td> const</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Check whether a node is subscribed to a specific message type. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">node</td><td>Pointer to the node to check. Must not be <code>nullptr</code>. </td></tr>
<tr><td class="paramname">eventType</td><td>The message type identifier to check. </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>true</code> if the node is subscribed to the given message type, <code>false</code> otherwise.</dd></dl>
<dl class="exception"><dt>Exceptions</dt><dd>
<table class="exception">
<tr><td class="paramname">std::runtime_error</td><td>if <code>node</code> is <code>nullptr</code>. </td></tr>
</table>
</dd>
</dl>
<dl class="section note"><dt>Note</dt><dd>This operation is thread-safe. </dd></dl>
<p class="definition">Definition at line <a class="el" href="bus_8h_source.html#l00387">387</a> of file <a class="el" href="bus_8h_source.html">bus.h</a>.</p>
</div>
</div>
<a id="a309bedf4b2fb78c99de024ece1f39eb5" name="a309bedf4b2fb78c99de024ece1f39eb5"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a309bedf4b2fb78c99de024ece1f39eb5">&#9670;&#160;</a></span>subscribeToBroadcast()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">void subscribeToBroadcast </td>
<td>(</td>
<td class="paramtype"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *&#160;</td>
<td class="paramname"><em>node</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Subscribe a node to broadcast mode. </p>
<p>A node in broadcast mode receives all messages posted to the bus, regardless of their type. A node can be subscribed to both broadcast mode and specific message types simultaneously, in which case it will receive the message twice for matching types.</p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">node</td><td>Pointer to the node to subscribe. Must not be <code>nullptr</code>.</td></tr>
</table>
</dd>
</dl>
<dl class="exception"><dt>Exceptions</dt><dd>
<table class="exception">
<tr><td class="paramname">std::runtime_error</td><td>if <code>node</code> is <code>nullptr</code>. </td></tr>
</table>
</dd>
</dl>
<dl class="section note"><dt>Note</dt><dd>This operation is thread-safe. </dd></dl>
<p class="definition">Definition at line <a class="el" href="bus_8h_source.html#l00405">405</a> of file <a class="el" href="bus_8h_source.html">bus.h</a>.</p>
</div>
</div>
<a id="ae9c37a95472381e33190bd951e381ebe" name="ae9c37a95472381e33190bd951e381ebe"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ae9c37a95472381e33190bd951e381ebe">&#9670;&#160;</a></span>unsubscribeFromBroadcast()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">void unsubscribeFromBroadcast </td>
<td>(</td>
<td class="paramtype"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *&#160;</td>
<td class="paramname"><em>node</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Unsubscribe a node from broadcast mode. </p>
<p>Removes the given node from the broadcast subscription list. If the node was not subscribed to broadcast mode, this call has no effect.</p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">node</td><td>Pointer to the node to unsubscribe. Must not be <code>nullptr</code>.</td></tr>
</table>
</dd>
</dl>
<dl class="exception"><dt>Exceptions</dt><dd>
<table class="exception">
<tr><td class="paramname">std::runtime_error</td><td>if <code>node</code> is <code>nullptr</code>. </td></tr>
</table>
</dd>
</dl>
<dl class="section note"><dt>Note</dt><dd>This operation is thread-safe. </dd></dl>
<p class="definition">Definition at line <a class="el" href="bus_8h_source.html#l00418">418</a> of file <a class="el" href="bus_8h_source.html">bus.h</a>.</p>
</div>
</div>
<a id="a7b375afd6d8b416cfd37e3bfce5b8ffd" name="a7b375afd6d8b416cfd37e3bfce5b8ffd"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a7b375afd6d8b416cfd37e3bfce5b8ffd">&#9670;&#160;</a></span>isSubscribedToBroadcast()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">bool isSubscribedToBroadcast </td>
<td>(</td>
<td class="paramtype"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *&#160;</td>
<td class="paramname"><em>node</em></td><td>)</td>
<td> const</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Check whether a node is subscribed to broadcast mode. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">node</td><td>Pointer to the node to check. Must not be <code>nullptr</code>. </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>true</code> if the node is subscribed to broadcast mode, <code>false</code> otherwise.</dd></dl>
<dl class="exception"><dt>Exceptions</dt><dd>
<table class="exception">
<tr><td class="paramname">std::runtime_error</td><td>if <code>node</code> is <code>nullptr</code>. </td></tr>
</table>
</dd>
</dl>
<dl class="section note"><dt>Note</dt><dd>This operation is thread-safe. </dd></dl>
<p class="definition">Definition at line <a class="el" href="bus_8h_source.html#l00431">431</a> of file <a class="el" href="bus_8h_source.html">bus.h</a>.</p>
</div>
</div>
<a id="a9aab57a60533a1a80a705bc569a9c589" name="a9aab57a60533a1a80a705bc569a9c589"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a9aab57a60533a1a80a705bc569a9c589">&#9670;&#160;</a></span>emit()</h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , class... Args&gt; </div>
<table class="memname">
<tr>
<td class="memname">bool emit </td>
<td>(</td>
<td class="paramtype">Args &amp;&amp;...&#160;</td>
<td class="paramname"><em>args</em></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Construct and emit a message of type <code>T</code> to the bus. </p>
<p>Creates a new message of type <code>T</code> by forwarding the provided arguments to its constructor, then posts it to the bus via <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a92c2bc8aa8bcf018ffe954a3e8e34324">post()</a>.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
<table class="tparams">
<tr><td class="paramname">T</td><td>The message type to emit. Must be derived from <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a>. </td></tr>
<tr><td class="paramname">Args</td><td>Constructor argument types for <code>T</code>. </td></tr>
</table>
</dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">args</td><td>Arguments forwarded to the constructor of <code>T</code>. </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>true</code> if at least one subscriber received the message, <code>false</code> otherwise.</dd></dl>
<dl class="section note"><dt>Note</dt><dd>Enforced at compile time: <code>T</code> must derive from <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a>. </dd>
<dd>
This operation is thread-safe.</dd></dl>
<dl class="section user"><dt>Example:</dt><dd><div class="fragment"><div class="line">bus.emit&lt;MyMessage&gt;(arg1, arg2);</div>
</div><!-- fragment --> </dd></dl>
<p class="definition">Definition at line <a class="el" href="bus_8h_source.html#l00445">445</a> of file <a class="el" href="bus_8h_source.html">bus.h</a>.</p>
</div>
</div>
<a id="a92c2bc8aa8bcf018ffe954a3e8e34324" name="a92c2bc8aa8bcf018ffe954a3e8e34324"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a92c2bc8aa8bcf018ffe954a3e8e34324">&#9670;&#160;</a></span>post()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">bool post </td>
<td>(</td>
<td class="paramtype">const std::shared_ptr&lt; <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &gt; &amp;&#160;</td>
<td class="paramname"><em>message</em></td><td>)</td>
<td> const</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Post an already constructed message to the bus. </p>
<p>Updates the message timestamp and dispatches it to all nodes subscribed to the message type, as well as all nodes in broadcast mode.</p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">message</td><td>Shared pointer to the message to post. Must not be <code>nullptr</code>. </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>true</code> if at least one specific subscriber received the message, <code>false</code> otherwise.</dd></dl>
<dl class="section note"><dt>Note</dt><dd>This operation is thread-safe. </dd></dl>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a9aab57a60533a1a80a705bc569a9c589" title="Construct and emit a message of type T to the bus.">emit()</a> </dd></dl>
<p class="definition">Definition at line <a class="el" href="bus_8h_source.html#l00457">457</a> of file <a class="el" href="bus_8h_source.html">bus.h</a>.</p>
</div>
</div>
<h2 class="groupheader">Friends And Related Symbol Documentation</h2>
<a id="a6db9d28bd448a131448276ee03de1e6d" name="a6db9d28bd448a131448276ee03de1e6d"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a6db9d28bd448a131448276ee03de1e6d">&#9670;&#160;</a></span>Node</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">friend class <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">friend</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Allow the <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" title="Concrete subscriber node in the event bus system.">Node</a> class to access private members. </p>
<p class="definition">Definition at line <a class="el" href="bus_8h_source.html#l00064">64</a> of file <a class="el" href="bus_8h_source.html">bus.h</a>.</p>
</div>
</div>
<h2 class="groupheader">Member Data Documentation</h2>
<a id="ad5e0dbd36f0d71fce9b00b7f991b2f38" name="ad5e0dbd36f0d71fce9b00b7f991b2f38"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ad5e0dbd36f0d71fce9b00b7f991b2f38">&#9670;&#160;</a></span>mtx</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">std::mutex mtx</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">mutable</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Mutex for thread-safe access to the nodes map. </p>
<p class="definition">Definition at line <a class="el" href="bus_8h_source.html#l00303">303</a> of file <a class="el" href="bus_8h_source.html">bus.h</a>.</p>
</div>
</div>
<a id="a4bc64bd8db5527dc8af9b458a82d6a65" name="a4bc64bd8db5527dc8af9b458a82d6a65"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a4bc64bd8db5527dc8af9b458a82d6a65">&#9670;&#160;</a></span>nodeList</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">std::unordered_map&lt;<a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a>, VectorNode&gt; nodeList</td>
</tr>
</table>
</div><div class="memdoc">
<p>Map of message type IDs to lists of subscribed nodes. </p>
<p class="definition">Definition at line <a class="el" href="bus_8h_source.html#l00304">304</a> of file <a class="el" href="bus_8h_source.html">bus.h</a>.</p>
</div>
</div>
<a id="a3c682b9a6b53418d7a147960e6dcdad1" name="a3c682b9a6b53418d7a147960e6dcdad1"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a3c682b9a6b53418d7a147960e6dcdad1">&#9670;&#160;</a></span>broadcastNodeList</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">std::set&lt;<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> *&gt; broadcastNodeList</td>
</tr>
</table>
</div><div class="memdoc">
<p>Set of nodes subscribed to receive all messages (broadcast mode) </p>
<p class="definition">Definition at line <a class="el" href="bus_8h_source.html#l00305">305</a> of file <a class="el" href="bus_8h_source.html">bus.h</a>.</p>
</div>
</div>
</div><!-- contents -->
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
SDi toolsBox is licensed under the terms and conditions of the <a href="https://opensource.org/licenses/zlib-license.php" target="_blank">zlib/png license</a>
<br />
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE | ver: 2.x.x - build: 2026-04-28
<br />
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen" /></a> 1.9.8
</small>
</address>
</body>
</html>

View File

@@ -0,0 +1,75 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>SDi toolsBox</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="custom_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">sdi_toolBox
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',false,false,'search.php','Search');
});
/* @license-end */
</script>
<div id="main-nav"></div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="namespacesdi__toolBox.html">sdi_toolBox</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1desktop.html">desktop</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html">eventBus</a></li><li class="navelem"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle"><div class="title">INode Member List</div></div>
</div><!--header-->
<div class="contents">
<p>This is the complete list of members for <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a>, including all inherited members.</p>
<table class="directory">
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#ac8043e64bbbd7a7a2b324991e96231ef">append</a>(const std::shared_ptr&lt; Message &gt; &amp;message)=0</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a></td><td class="entry"><span class="mlabel">private</span><span class="mlabel">pure virtual</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#a96d8550db89cd8c6abb7e0d3e8923eb2">Bus</a></td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a></td><td class="entry"><span class="mlabel">friend</span></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#ad2a3ec43678e1b15703f874bca9a985d">INode</a>()=default</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#a5b3ead2689bd5eed4b3617ae6a5e4a09">INode</a>(const INode &amp;obj)=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#a48dab9422d43ec52a83947b49845e40b">INode</a>(INode &amp;&amp;obj) noexcept=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#aa663d1ba2c5db32e6e463590bae347f8">operator=</a>(const INode &amp;obj)=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#a08395ac07c088d1d64339d4c0d3b52cb">operator=</a>(INode &amp;&amp;obj) noexcept=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#a1356f0d04912be3ec8d8ce7a2b0cddd2">~INode</a>()=default</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
</table></div><!-- contents -->
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
SDi toolsBox is licensed under the terms and conditions of the <a href="https://opensource.org/licenses/zlib-license.php" target="_blank">zlib/png license</a>
<br />
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE | ver: 2.x.x - build: 2026-04-28
<br />
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen" /></a> 1.9.8
</small>
</address>
</body>
</html>

View File

@@ -0,0 +1,366 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>SDi toolsBox</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="custom_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">sdi_toolBox
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',false,false,'search.php','Search');
});
/* @license-end */
</script>
<div id="main-nav"></div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="namespacesdi__toolBox.html">sdi_toolBox</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1desktop.html">desktop</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html">eventBus</a></li><li class="navelem"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="summary">
<a href="#pri-methods">Private Member Functions</a> &#124;
<a href="#friends">Friends</a> &#124;
<a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode-members.html">List of all members</a> </div>
<div class="headertitle"><div class="title">INode Class Reference<span class="mlabels"><span class="mlabel">abstract</span></span></div></div>
</div><!--header-->
<div class="contents">
<p><code>#include &lt;<a class="el" href="inode_8h_source.html">inode.h</a>&gt;</code></p>
<div class="dynheader">
Inheritance diagram for INode:</div>
<div class="dyncontent">
<div class="center"><img src="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode__inherit__graph.png" border="0" usemap="#aINode_inherit__map" alt="Inheritance graph"/></div>
<map name="aINode_inherit__map" id="aINode_inherit__map">
<area shape="rect" title="Abstract interface representing a subscriber node in the event bus system." alt="" coords="5,5,65,31"/>
<area shape="rect" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" title="Concrete subscriber node in the event bus system." alt="" coords="7,79,63,104"/>
<area shape="poly" title=" " alt="" coords="38,44,38,79,33,79,33,44"/>
</map>
<center><span class="legend">[<a href="graph_legend.html">legend</a>]</span></center></div>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p>Abstract interface representing a subscriber node in the event bus system. </p>
<p><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html" title="Abstract interface representing a subscriber node in the event bus system.">INode</a> is the base interface that all subscriber nodes must implement to participate in the event bus. It exposes a single private pure virtual method, <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#ac8043e64bbbd7a7a2b324991e96231ef">append()</a>, which is called exclusively by the <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> when a message is dispatched to this node.</p>
<p>The <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> is declared as a friend class to allow it to invoke <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#ac8043e64bbbd7a7a2b324991e96231ef">append()</a> without exposing it to the rest of the codebase, enforcing a strict encapsulation of the message delivery mechanism.</p>
<dl class="section note"><dt>Note</dt><dd><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html" title="Abstract interface representing a subscriber node in the event bus system.">INode</a> is non-copyable and non-movable. </dd>
<dd>
Direct instantiation is not possible - this class must be subclassed. The concrete implementation is provided by <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a>.</dd></dl>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html" title="Central message dispatcher for the event bus system.">Bus</a> </dd>
<dd>
<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" title="Concrete subscriber node in the event bus system.">Node</a> </dd>
<dd>
<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html" title="Base class for all messages dispatched through the event bus.">Message</a> </dd></dl>
<p class="definition">Definition at line <a class="el" href="inode_8h_source.html#l00041">41</a> of file <a class="el" href="inode_8h_source.html">inode.h</a>.</p>
</div><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr><td colspan="2"><div class="groupHeader">Construction &amp; Destruction</div></td></tr>
<tr class="memitem:ad2a3ec43678e1b15703f874bca9a985d" id="r_ad2a3ec43678e1b15703f874bca9a985d"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#ad2a3ec43678e1b15703f874bca9a985d">INode</a> ()=default</td></tr>
<tr class="memdesc:ad2a3ec43678e1b15703f874bca9a985d"><td class="mdescLeft">&#160;</td><td class="mdescRight">Default constructor. <br /></td></tr>
<tr class="separator:ad2a3ec43678e1b15703f874bca9a985d"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a1356f0d04912be3ec8d8ce7a2b0cddd2" id="r_a1356f0d04912be3ec8d8ce7a2b0cddd2"><td class="memItemLeft" align="right" valign="top">virtual&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#a1356f0d04912be3ec8d8ce7a2b0cddd2">~INode</a> ()=default</td></tr>
<tr class="memdesc:a1356f0d04912be3ec8d8ce7a2b0cddd2"><td class="mdescLeft">&#160;</td><td class="mdescRight">Default destructor. <br /></td></tr>
<tr class="separator:a1356f0d04912be3ec8d8ce7a2b0cddd2"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a5b3ead2689bd5eed4b3617ae6a5e4a09" id="r_a5b3ead2689bd5eed4b3617ae6a5e4a09"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#a5b3ead2689bd5eed4b3617ae6a5e4a09">INode</a> (const <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> &amp;obj)=delete</td></tr>
<tr class="memdesc:a5b3ead2689bd5eed4b3617ae6a5e4a09"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy constructor - deleted. <br /></td></tr>
<tr class="separator:a5b3ead2689bd5eed4b3617ae6a5e4a09"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a48dab9422d43ec52a83947b49845e40b" id="r_a48dab9422d43ec52a83947b49845e40b"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#a48dab9422d43ec52a83947b49845e40b">INode</a> (<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> &amp;&amp;obj) noexcept=delete</td></tr>
<tr class="memdesc:a48dab9422d43ec52a83947b49845e40b"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move constructor - deleted. <br /></td></tr>
<tr class="separator:a48dab9422d43ec52a83947b49845e40b"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aa663d1ba2c5db32e6e463590bae347f8" id="r_aa663d1ba2c5db32e6e463590bae347f8"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#aa663d1ba2c5db32e6e463590bae347f8">operator=</a> (const <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> &amp;obj)=delete</td></tr>
<tr class="memdesc:aa663d1ba2c5db32e6e463590bae347f8"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy assignment operator - deleted. <br /></td></tr>
<tr class="separator:aa663d1ba2c5db32e6e463590bae347f8"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a08395ac07c088d1d64339d4c0d3b52cb" id="r_a08395ac07c088d1d64339d4c0d3b52cb"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#a08395ac07c088d1d64339d4c0d3b52cb">operator=</a> (<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> &amp;&amp;obj) noexcept=delete</td></tr>
<tr class="memdesc:a08395ac07c088d1d64339d4c0d3b52cb"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move assignment operator - deleted. <br /></td></tr>
<tr class="separator:a08395ac07c088d1d64339d4c0d3b52cb"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pri-methods" name="pri-methods"></a>
Private Member Functions</h2></td></tr>
<tr class="memitem:ac8043e64bbbd7a7a2b324991e96231ef" id="r_ac8043e64bbbd7a7a2b324991e96231ef"><td class="memItemLeft" align="right" valign="top">virtual void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#ac8043e64bbbd7a7a2b324991e96231ef">append</a> (const std::shared_ptr&lt; <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &gt; &amp;message)=0</td></tr>
<tr class="memdesc:ac8043e64bbbd7a7a2b324991e96231ef"><td class="mdescLeft">&#160;</td><td class="mdescRight">Insert a message into the node's internal message queue. <br /></td></tr>
<tr class="separator:ac8043e64bbbd7a7a2b324991e96231ef"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="friends" name="friends"></a>
Friends</h2></td></tr>
<tr class="memitem:a96d8550db89cd8c6abb7e0d3e8923eb2" id="r_a96d8550db89cd8c6abb7e0d3e8923eb2"><td class="memItemLeft" align="right" valign="top">class&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#a96d8550db89cd8c6abb7e0d3e8923eb2">Bus</a></td></tr>
<tr class="memdesc:a96d8550db89cd8c6abb7e0d3e8923eb2"><td class="mdescLeft">&#160;</td><td class="mdescRight">Allow the <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html" title="Central message dispatcher for the event bus system.">Bus</a> class to access private members. <br /></td></tr>
<tr class="separator:a96d8550db89cd8c6abb7e0d3e8923eb2"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
<a id="ad2a3ec43678e1b15703f874bca9a985d" name="ad2a3ec43678e1b15703f874bca9a985d"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ad2a3ec43678e1b15703f874bca9a985d">&#9670;&#160;</a></span>INode() <span class="overload">[1/3]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">default</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Default constructor. </p>
</div>
</div>
<a id="a1356f0d04912be3ec8d8ce7a2b0cddd2" name="a1356f0d04912be3ec8d8ce7a2b0cddd2"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a1356f0d04912be3ec8d8ce7a2b0cddd2">&#9670;&#160;</a></span>~INode()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">virtual ~<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">virtual</span><span class="mlabel">default</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Default destructor. </p>
</div>
</div>
<a id="a5b3ead2689bd5eed4b3617ae6a5e4a09" name="a5b3ead2689bd5eed4b3617ae6a5e4a09"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a5b3ead2689bd5eed4b3617ae6a5e4a09">&#9670;&#160;</a></span>INode() <span class="overload">[2/3]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> &amp;&#160;</td>
<td class="paramname"><em>obj</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">delete</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Copy constructor - deleted. </p>
<p><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html" title="Abstract interface representing a subscriber node in the event bus system.">INode</a> is non-copyable. </p>
</div>
</div>
<a id="a48dab9422d43ec52a83947b49845e40b" name="a48dab9422d43ec52a83947b49845e40b"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a48dab9422d43ec52a83947b49845e40b">&#9670;&#160;</a></span>INode() <span class="overload">[3/3]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> </td>
<td>(</td>
<td class="paramtype"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> &amp;&amp;&#160;</td>
<td class="paramname"><em>obj</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">delete</span><span class="mlabel">noexcept</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Move constructor - deleted. </p>
<p><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html" title="Abstract interface representing a subscriber node in the event bus system.">INode</a> is non-movable. </p>
</div>
</div>
<h2 class="groupheader">Member Function Documentation</h2>
<a id="aa663d1ba2c5db32e6e463590bae347f8" name="aa663d1ba2c5db32e6e463590bae347f8"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aa663d1ba2c5db32e6e463590bae347f8">&#9670;&#160;</a></span>operator=() <span class="overload">[1/2]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> &amp; operator= </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> &amp;&#160;</td>
<td class="paramname"><em>obj</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">delete</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Copy assignment operator - deleted. </p>
<p><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html" title="Abstract interface representing a subscriber node in the event bus system.">INode</a> is non-copyable. </p>
</div>
</div>
<a id="a08395ac07c088d1d64339d4c0d3b52cb" name="a08395ac07c088d1d64339d4c0d3b52cb"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a08395ac07c088d1d64339d4c0d3b52cb">&#9670;&#160;</a></span>operator=() <span class="overload">[2/2]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> &amp; operator= </td>
<td>(</td>
<td class="paramtype"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> &amp;&amp;&#160;</td>
<td class="paramname"><em>obj</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">delete</span><span class="mlabel">noexcept</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Move assignment operator - deleted. </p>
<p><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html" title="Abstract interface representing a subscriber node in the event bus system.">INode</a> is non-movable. </p>
</div>
</div>
<a id="ac8043e64bbbd7a7a2b324991e96231ef" name="ac8043e64bbbd7a7a2b324991e96231ef"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ac8043e64bbbd7a7a2b324991e96231ef">&#9670;&#160;</a></span>append()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">virtual void append </td>
<td>(</td>
<td class="paramtype">const std::shared_ptr&lt; <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &gt; &amp;&#160;</td>
<td class="paramname"><em>message</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span><span class="mlabel">pure virtual</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Insert a message into the node's internal message queue. </p>
<p>This method is called exclusively by the <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> when a message matching this node's subscriptions (or a broadcast message) is dispatched. It must be implemented by all concrete subclasses to define how incoming messages are stored or processed.</p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">message</td><td>Shared pointer to the message being delivered.</td></tr>
</table>
</dd>
</dl>
<dl class="section note"><dt>Note</dt><dd>This method is intentionally private and only accessible to <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> via the friend declaration, preventing external code from injecting messages directly into a node. </dd></dl>
<p>Implemented in <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#afd326e91fe62057d1b3e1fc5e77f8526">Node</a>.</p>
</div>
</div>
<h2 class="groupheader">Friends And Related Symbol Documentation</h2>
<a id="a96d8550db89cd8c6abb7e0d3e8923eb2" name="a96d8550db89cd8c6abb7e0d3e8923eb2"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a96d8550db89cd8c6abb7e0d3e8923eb2">&#9670;&#160;</a></span>Bus</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">friend class <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">friend</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Allow the <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html" title="Central message dispatcher for the event bus system.">Bus</a> class to access private members. </p>
<p class="definition">Definition at line <a class="el" href="inode_8h_source.html#l00043">43</a> of file <a class="el" href="inode_8h_source.html">inode.h</a>.</p>
</div>
</div>
</div><!-- contents -->
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
SDi toolsBox is licensed under the terms and conditions of the <a href="https://opensource.org/licenses/zlib-license.php" target="_blank">zlib/png license</a>
<br />
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE | ver: 2.x.x - build: 2026-04-28
<br />
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen" /></a> 1.9.8
</small>
</address>
</body>
</html>

View File

@@ -0,0 +1,5 @@
<map id="INode" name="INode">
<area shape="rect" id="Node000001" title="Abstract interface representing a subscriber node in the event bus system." alt="" coords="5,5,65,31"/>
<area shape="rect" id="Node000002" href="$classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" title="Concrete subscriber node in the event bus system." alt="" coords="7,79,63,104"/>
<area shape="poly" id="edge1_Node000001_Node000002" title=" " alt="" coords="38,44,38,79,33,79,33,44"/>
</map>

View File

@@ -0,0 +1 @@
7f0705834ef0a2b2429b2a409870055e

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -0,0 +1,77 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>SDi toolsBox</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="custom_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">sdi_toolBox
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',false,false,'search.php','Search');
});
/* @license-end */
</script>
<div id="main-nav"></div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="namespacesdi__toolBox.html">sdi_toolBox</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1desktop.html">desktop</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html">eventBus</a></li><li class="navelem"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle"><div class="title">Message Member List</div></div>
</div><!--header-->
<div class="contents">
<p>This is the complete list of members for <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a>, including all inherited members.</p>
<table class="directory">
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html#a96d8550db89cd8c6abb7e0d3e8923eb2">Bus</a></td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a></td><td class="entry"><span class="mlabel">friend</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html#aa8b1670a081a29f03ff73fe6e8fd75dd">getMessageTypeID</a>() const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html#a0724134c68e584e5bfe25f22830e07bb">getTimestamp</a>() const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html#aa8be7248d1a72ecd8c04f3b074a77262">Message</a>()=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html#a985ae29d79eda2bc249a2f9e3c0d1799">Message</a>(const Message &amp;obj)=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html#ac1dee51597a2b5ecef4d2750ff010df0">Message</a>(Message &amp;&amp;obj) noexcept=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html#aae6bb865d324bb9b062bf4886668a89c">Message</a>(MessageTypeID messageTypeID)</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">explicit</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html#a540c190c4e96ade4e866badaef0c6505">operator=</a>(const Message &amp;obj)=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html#a4c54f56e7dacc9f823d63255ba12da4e">operator=</a>(Message &amp;&amp;obj) noexcept=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html#afd5ba4e5e3792ccbdbe4e60abc535cd6">~Message</a>()=default</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
</table></div><!-- contents -->
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
SDi toolsBox is licensed under the terms and conditions of the <a href="https://opensource.org/licenses/zlib-license.php" target="_blank">zlib/png license</a>
<br />
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE | ver: 2.x.x - build: 2026-04-28
<br />
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen" /></a> 1.9.8
</small>
</address>
</body>
</html>

View File

@@ -0,0 +1,434 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>SDi toolsBox</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="custom_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">sdi_toolBox
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',false,false,'search.php','Search');
});
/* @license-end */
</script>
<div id="main-nav"></div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="namespacesdi__toolBox.html">sdi_toolBox</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1desktop.html">desktop</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html">eventBus</a></li><li class="navelem"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="summary">
<a href="#friends">Friends</a> &#124;
<a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message-members.html">List of all members</a> </div>
<div class="headertitle"><div class="title">Message Class Reference</div></div>
</div><!--header-->
<div class="contents">
<p><code>#include &lt;<a class="el" href="message_8h_source.html">message.h</a>&gt;</code></p>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p>Base class for all messages dispatched through the event bus. </p>
<p>Every message circulating in the event bus system must derive from this class. It carries a unique message type identifier (<a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a>) used by the <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> to route the message to the appropriate subscribers, and a timestamp that is updated when the message is posted to the bus.</p>
<dl class="section note"><dt>Note</dt><dd>The <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html" title="Base class for all messages dispatched through the event bus.">Message</a> class is non-copyable and non-movable. </dd>
<dd>
The default constructor is deleted: a <a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a> must always be provided at construction time. </dd>
<dd>
The timestamp is set by the <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> internally when <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a92c2bc8aa8bcf018ffe954a3e8e34324">Bus::post()</a> is called; it is not set at construction time.</dd></dl>
<dl class="section user"><dt>Example - defining a custom message:</dt><dd><div class="fragment"><div class="line"><span class="keyword">static</span> <span class="keyword">constexpr</span> <a class="code hl_typedef" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">sdi_toolBox::desktop::eventBus::MessageTypeID</a> MY_EVENT = 1;</div>
<div class="line"> </div>
<div class="line"><span class="keyword">struct </span>MyMessage : <span class="keyword">public</span> <a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">sdi_toolBox::desktop::eventBus::Message</a></div>
<div class="line">{</div>
<div class="line"> <span class="keyword">explicit</span> MyMessage(<span class="keywordtype">int</span> value)</div>
<div class="line"> : <a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a>(MY_EVENT)</div>
<div class="line"> , payload(value)</div>
<div class="line"> {}</div>
<div class="line"> <span class="keywordtype">int</span> payload{};</div>
<div class="line">};</div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Message_html"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">sdi_toolBox::desktop::eventBus::Message</a></div><div class="ttdoc">Base class for all messages dispatched through the event bus.</div><div class="ttdef"><b>Definition</b> <a href="message_8h_source.html#l00053">message.h:54</a></div></div>
<div class="ttc" id="anamespacesdi__toolBox_1_1desktop_1_1eventBus_html_a9a6bed6d55e3ccf6e4b27ebfa879277c"><div class="ttname"><a href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">sdi_toolBox::desktop::eventBus::MessageTypeID</a></div><div class="ttdeci">uint64_t MessageTypeID</div><div class="ttdoc">Unique identifier for a message type.</div><div class="ttdef"><b>Definition</b> <a href="defs_8h_source.html#l00021">defs.h:21</a></div></div>
</div><!-- fragment --></dd></dl>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html" title="Central message dispatcher for the event bus system.">Bus</a> </dd>
<dd>
<a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c" title="Unique identifier for a message type.">MessageTypeID</a> </dd>
<dd>
<a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#ae5ca775e8d8c664b6edef818ce1251b9" title="Monotonic timestamp type used throughout the event bus.">TimePoint</a> </dd></dl>
<p class="definition">Definition at line <a class="el" href="message_8h_source.html#l00053">53</a> of file <a class="el" href="message_8h_source.html">message.h</a>.</p>
</div><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr><td colspan="2"><div class="groupHeader">Construction &amp; Destruction</div></td></tr>
<tr class="memitem:aa8be7248d1a72ecd8c04f3b074a77262" id="r_aa8be7248d1a72ecd8c04f3b074a77262"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html#aa8be7248d1a72ecd8c04f3b074a77262">Message</a> ()=delete</td></tr>
<tr class="memdesc:aa8be7248d1a72ecd8c04f3b074a77262"><td class="mdescLeft">&#160;</td><td class="mdescRight">Default constructor - deleted. <br /></td></tr>
<tr class="separator:aa8be7248d1a72ecd8c04f3b074a77262"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:afd5ba4e5e3792ccbdbe4e60abc535cd6" id="r_afd5ba4e5e3792ccbdbe4e60abc535cd6"><td class="memItemLeft" align="right" valign="top">virtual&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html#afd5ba4e5e3792ccbdbe4e60abc535cd6">~Message</a> ()=default</td></tr>
<tr class="memdesc:afd5ba4e5e3792ccbdbe4e60abc535cd6"><td class="mdescLeft">&#160;</td><td class="mdescRight">Default destructor. <br /></td></tr>
<tr class="separator:afd5ba4e5e3792ccbdbe4e60abc535cd6"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a985ae29d79eda2bc249a2f9e3c0d1799" id="r_a985ae29d79eda2bc249a2f9e3c0d1799"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html#a985ae29d79eda2bc249a2f9e3c0d1799">Message</a> (const <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &amp;obj)=delete</td></tr>
<tr class="memdesc:a985ae29d79eda2bc249a2f9e3c0d1799"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy constructor - deleted. <br /></td></tr>
<tr class="separator:a985ae29d79eda2bc249a2f9e3c0d1799"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ac1dee51597a2b5ecef4d2750ff010df0" id="r_ac1dee51597a2b5ecef4d2750ff010df0"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html#ac1dee51597a2b5ecef4d2750ff010df0">Message</a> (<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &amp;&amp;obj) noexcept=delete</td></tr>
<tr class="memdesc:ac1dee51597a2b5ecef4d2750ff010df0"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move constructor - deleted. <br /></td></tr>
<tr class="separator:ac1dee51597a2b5ecef4d2750ff010df0"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a540c190c4e96ade4e866badaef0c6505" id="r_a540c190c4e96ade4e866badaef0c6505"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html#a540c190c4e96ade4e866badaef0c6505">operator=</a> (const <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &amp;obj)=delete</td></tr>
<tr class="memdesc:a540c190c4e96ade4e866badaef0c6505"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy assignment operator - deleted. <br /></td></tr>
<tr class="separator:a540c190c4e96ade4e866badaef0c6505"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a4c54f56e7dacc9f823d63255ba12da4e" id="r_a4c54f56e7dacc9f823d63255ba12da4e"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html#a4c54f56e7dacc9f823d63255ba12da4e">operator=</a> (<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &amp;&amp;obj) noexcept=delete</td></tr>
<tr class="memdesc:a4c54f56e7dacc9f823d63255ba12da4e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move assignment operator - deleted. <br /></td></tr>
<tr class="separator:a4c54f56e7dacc9f823d63255ba12da4e"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aae6bb865d324bb9b062bf4886668a89c" id="r_aae6bb865d324bb9b062bf4886668a89c"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html#aae6bb865d324bb9b062bf4886668a89c">Message</a> (<a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a> messageTypeID)</td></tr>
<tr class="memdesc:aae6bb865d324bb9b062bf4886668a89c"><td class="mdescLeft">&#160;</td><td class="mdescRight">Construct a message with the given type identifier. <br /></td></tr>
<tr class="separator:aae6bb865d324bb9b062bf4886668a89c"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr><td colspan="2"><div class="groupHeader">Accessors</div></td></tr>
<tr class="memitem:aa8b1670a081a29f03ff73fe6e8fd75dd" id="r_aa8b1670a081a29f03ff73fe6e8fd75dd"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html#aa8b1670a081a29f03ff73fe6e8fd75dd">getMessageTypeID</a> () const</td></tr>
<tr class="memdesc:aa8b1670a081a29f03ff73fe6e8fd75dd"><td class="mdescLeft">&#160;</td><td class="mdescRight">Get the unique type identifier of this message. <br /></td></tr>
<tr class="separator:aa8b1670a081a29f03ff73fe6e8fd75dd"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a0724134c68e584e5bfe25f22830e07bb" id="r_a0724134c68e584e5bfe25f22830e07bb"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#ae5ca775e8d8c664b6edef818ce1251b9">TimePoint</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html#a0724134c68e584e5bfe25f22830e07bb">getTimestamp</a> () const</td></tr>
<tr class="memdesc:a0724134c68e584e5bfe25f22830e07bb"><td class="mdescLeft">&#160;</td><td class="mdescRight">Get the timestamp of when this message was posted to the bus. <br /></td></tr>
<tr class="separator:a0724134c68e584e5bfe25f22830e07bb"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="friends" name="friends"></a>
Friends</h2></td></tr>
<tr class="memitem:a96d8550db89cd8c6abb7e0d3e8923eb2" id="r_a96d8550db89cd8c6abb7e0d3e8923eb2"><td class="memItemLeft" align="right" valign="top">class&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html#a96d8550db89cd8c6abb7e0d3e8923eb2">Bus</a></td></tr>
<tr class="memdesc:a96d8550db89cd8c6abb7e0d3e8923eb2"><td class="mdescLeft">&#160;</td><td class="mdescRight">Allow the <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html" title="Central message dispatcher for the event bus system.">Bus</a> class to access private members. <br /></td></tr>
<tr class="separator:a96d8550db89cd8c6abb7e0d3e8923eb2"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
<a id="aa8be7248d1a72ecd8c04f3b074a77262" name="aa8be7248d1a72ecd8c04f3b074a77262"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aa8be7248d1a72ecd8c04f3b074a77262">&#9670;&#160;</a></span>Message() <span class="overload">[1/4]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">delete</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Default constructor - deleted. </p>
<p>A <a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a> must always be provided at construction time. </p>
</div>
</div>
<a id="afd5ba4e5e3792ccbdbe4e60abc535cd6" name="afd5ba4e5e3792ccbdbe4e60abc535cd6"></a>
<h2 class="memtitle"><span class="permalink"><a href="#afd5ba4e5e3792ccbdbe4e60abc535cd6">&#9670;&#160;</a></span>~Message()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">virtual ~<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">virtual</span><span class="mlabel">default</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Default destructor. </p>
</div>
</div>
<a id="a985ae29d79eda2bc249a2f9e3c0d1799" name="a985ae29d79eda2bc249a2f9e3c0d1799"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a985ae29d79eda2bc249a2f9e3c0d1799">&#9670;&#160;</a></span>Message() <span class="overload">[2/4]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &amp;&#160;</td>
<td class="paramname"><em>obj</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">delete</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Copy constructor - deleted. </p>
<p><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html" title="Base class for all messages dispatched through the event bus.">Message</a> is non-copyable. </p>
</div>
</div>
<a id="ac1dee51597a2b5ecef4d2750ff010df0" name="ac1dee51597a2b5ecef4d2750ff010df0"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ac1dee51597a2b5ecef4d2750ff010df0">&#9670;&#160;</a></span>Message() <span class="overload">[3/4]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> </td>
<td>(</td>
<td class="paramtype"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &amp;&amp;&#160;</td>
<td class="paramname"><em>obj</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">delete</span><span class="mlabel">noexcept</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Move constructor - deleted. </p>
<p><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html" title="Base class for all messages dispatched through the event bus.">Message</a> is non-movable. </p>
</div>
</div>
<a id="aae6bb865d324bb9b062bf4886668a89c" name="aae6bb865d324bb9b062bf4886668a89c"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aae6bb865d324bb9b062bf4886668a89c">&#9670;&#160;</a></span>Message() <span class="overload">[4/4]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> </td>
<td>(</td>
<td class="paramtype"><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a>&#160;</td>
<td class="paramname"><em>messageTypeID</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span><span class="mlabel">explicit</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Construct a message with the given type identifier. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">messageTypeID</td><td>Unique identifier representing the type of this message. Used by the <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> to route the message to the correct subscribers. </td></tr>
</table>
</dd>
</dl>
<p class="definition">Definition at line <a class="el" href="message_8h_source.html#l00151">151</a> of file <a class="el" href="message_8h_source.html">message.h</a>.</p>
</div>
</div>
<h2 class="groupheader">Member Function Documentation</h2>
<a id="a540c190c4e96ade4e866badaef0c6505" name="a540c190c4e96ade4e866badaef0c6505"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a540c190c4e96ade4e866badaef0c6505">&#9670;&#160;</a></span>operator=() <span class="overload">[1/2]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &amp; operator= </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &amp;&#160;</td>
<td class="paramname"><em>obj</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">delete</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Copy assignment operator - deleted. </p>
<p><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html" title="Base class for all messages dispatched through the event bus.">Message</a> is non-copyable. </p>
</div>
</div>
<a id="a4c54f56e7dacc9f823d63255ba12da4e" name="a4c54f56e7dacc9f823d63255ba12da4e"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a4c54f56e7dacc9f823d63255ba12da4e">&#9670;&#160;</a></span>operator=() <span class="overload">[2/2]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &amp; operator= </td>
<td>(</td>
<td class="paramtype"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &amp;&amp;&#160;</td>
<td class="paramname"><em>obj</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">delete</span><span class="mlabel">noexcept</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Move assignment operator - deleted. </p>
<p><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html" title="Base class for all messages dispatched through the event bus.">Message</a> is non-movable. </p>
</div>
</div>
<a id="aa8b1670a081a29f03ff73fe6e8fd75dd" name="aa8b1670a081a29f03ff73fe6e8fd75dd"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aa8b1670a081a29f03ff73fe6e8fd75dd">&#9670;&#160;</a></span>getMessageTypeID()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a> getMessageTypeID </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td> const</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Get the unique type identifier of this message. </p>
<dl class="section return"><dt>Returns</dt><dd>The <a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a> assigned at construction time. </dd></dl>
<p class="definition">Definition at line <a class="el" href="message_8h_source.html#l00157">157</a> of file <a class="el" href="message_8h_source.html">message.h</a>.</p>
</div>
</div>
<a id="a0724134c68e584e5bfe25f22830e07bb" name="a0724134c68e584e5bfe25f22830e07bb"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a0724134c68e584e5bfe25f22830e07bb">&#9670;&#160;</a></span>getTimestamp()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#ae5ca775e8d8c664b6edef818ce1251b9">TimePoint</a> getTimestamp </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td> const</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Get the timestamp of when this message was posted to the bus. </p>
<p>The timestamp is recorded by the <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> when <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a92c2bc8aa8bcf018ffe954a3e8e34324">Bus::post()</a> is called. It is left at its default-constructed (zero) value if the message has not yet been posted.</p>
<dl class="section return"><dt>Returns</dt><dd>A <a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#ae5ca775e8d8c664b6edef818ce1251b9">TimePoint</a> representing the moment the message was dispatched. </dd></dl>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a92c2bc8aa8bcf018ffe954a3e8e34324" title="Post an already constructed message to the bus.">Bus::post()</a> </dd></dl>
<p class="definition">Definition at line <a class="el" href="message_8h_source.html#l00163">163</a> of file <a class="el" href="message_8h_source.html">message.h</a>.</p>
</div>
</div>
<h2 class="groupheader">Friends And Related Symbol Documentation</h2>
<a id="a96d8550db89cd8c6abb7e0d3e8923eb2" name="a96d8550db89cd8c6abb7e0d3e8923eb2"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a96d8550db89cd8c6abb7e0d3e8923eb2">&#9670;&#160;</a></span>Bus</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">friend class <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">friend</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Allow the <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html" title="Central message dispatcher for the event bus system.">Bus</a> class to access private members. </p>
<p class="definition">Definition at line <a class="el" href="message_8h_source.html#l00055">55</a> of file <a class="el" href="message_8h_source.html">message.h</a>.</p>
</div>
</div>
</div><!-- contents -->
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
SDi toolsBox is licensed under the terms and conditions of the <a href="https://opensource.org/licenses/zlib-license.php" target="_blank">zlib/png license</a>
<br />
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE | ver: 2.x.x - build: 2026-04-28
<br />
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen" /></a> 1.9.8
</small>
</address>
</body>
</html>

View File

@@ -0,0 +1,91 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>SDi toolsBox</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="custom_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">sdi_toolBox
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',false,false,'search.php','Search');
});
/* @license-end */
</script>
<div id="main-nav"></div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="namespacesdi__toolBox.html">sdi_toolBox</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1desktop.html">desktop</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html">eventBus</a></li><li class="navelem"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle"><div class="title">Node Member List</div></div>
</div><!--header-->
<div class="contents">
<p>This is the complete list of members for <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a>, including all inherited members.</p>
<table class="directory">
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#afd326e91fe62057d1b3e1fc5e77f8526">append</a>(const std::shared_ptr&lt; Message &gt; &amp;message) override</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">private</span><span class="mlabel">virtual</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a9aab57a60533a1a80a705bc569a9c589">emit</a>(Args &amp;&amp;...args)</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#ad3c328938178037a51a3f0be5711fa1b">getMessageCount</a>() const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#ad2a3ec43678e1b15703f874bca9a985d">INode</a>()=default</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#a5b3ead2689bd5eed4b3617ae6a5e4a09">INode</a>(const INode &amp;obj)=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#a48dab9422d43ec52a83947b49845e40b">INode</a>(INode &amp;&amp;obj) noexcept=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a8a28311e9640e7d150b254d83424c08c">messageQueue</a></td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#ad5e0dbd36f0d71fce9b00b7f991b2f38">mtx</a></td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></td><td class="entry"><span class="mlabel">mutable</span></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a9ccb487f15b9518a8cb801f14ca36804">Node</a>()=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a8655b18ba4c11b25753d741a958bea87">Node</a>(const Node &amp;obj)=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a3d2a90b0a72088cccae1d9bbbed3ca45">Node</a>(Node &amp;&amp;obj) noexcept=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#aa4d9158beb9bc615b040954434c1db90">Node</a>(Bus &amp;bus)</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">explicit</span></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a7196569c68b87dc2c0ed116d4a8603f6">operator=</a>(const Node &amp;obj)=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a2eeb54ac57183c4201143fc76f5e4b1a">operator=</a>(Node &amp;&amp;obj) noexcept=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#aa663d1ba2c5db32e6e463590bae347f8">sdi_toolBox::desktop::eventBus::INode::operator=</a>(const INode &amp;obj)=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a></td><td class="entry"></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#a08395ac07c088d1d64339d4c0d3b52cb">sdi_toolBox::desktop::eventBus::INode::operator=</a>(INode &amp;&amp;obj) noexcept=delete</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a></td><td class="entry"></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a68168b63fcfb3cc18ba23ccbc2c269b7">popMessage</a>()</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a92c2bc8aa8bcf018ffe954a3e8e34324">post</a>(const std::shared_ptr&lt; Message &gt; &amp;message) const</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a43f475792aedfbbdaf623a8a9065a5c9">subscribe</a>(MessageTypeID eventType)</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a90802ca554f4e38a59d1c326468618f0">syncWaitForMessage</a>()</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#aad4f2b01a3e7c46d0253be40e13f2974">unsubscribe</a>(MessageTypeID eventType)</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#ade72b9b723cf5c7d43f7cc556a466f99">unsubscribeFromAll</a>()</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
<tr class="even"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#a1356f0d04912be3ec8d8ce7a2b0cddd2">~INode</a>()=default</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
<tr class="odd"><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a6fa6bf60f34f1e3efb0e59333428c9c8">~Node</a>()</td><td class="entry"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></td><td class="entry"><span class="mlabel">inline</span><span class="mlabel">virtual</span></td></tr>
</table></div><!-- contents -->
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
SDi toolsBox is licensed under the terms and conditions of the <a href="https://opensource.org/licenses/zlib-license.php" target="_blank">zlib/png license</a>
<br />
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE | ver: 2.x.x - build: 2026-04-28
<br />
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen" /></a> 1.9.8
</small>
</address>
</body>
</html>

View File

@@ -0,0 +1,776 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>SDi toolsBox</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="custom_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">sdi_toolBox
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',false,false,'search.php','Search');
});
/* @license-end */
</script>
<div id="main-nav"></div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="namespacesdi__toolBox.html">sdi_toolBox</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1desktop.html">desktop</a></li><li class="navelem"><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html">eventBus</a></li><li class="navelem"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="summary">
<a href="#pri-methods">Private Member Functions</a> &#124;
<a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node-members.html">List of all members</a> </div>
<div class="headertitle"><div class="title">Node Class Reference</div></div>
</div><!--header-->
<div class="contents">
<p><code>#include &lt;<a class="el" href="node_8h_source.html">node.h</a>&gt;</code></p>
<div class="dynheader">
Inheritance diagram for Node:</div>
<div class="dyncontent">
<div class="center"><img src="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node__inherit__graph.png" border="0" usemap="#aNode_inherit__map" alt="Inheritance graph"/></div>
<map name="aNode_inherit__map" id="aNode_inherit__map">
<area shape="rect" title="Concrete subscriber node in the event bus system." alt="" coords="7,79,63,104"/>
<area shape="rect" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html" title="Abstract interface representing a subscriber node in the event bus system." alt="" coords="5,5,65,31"/>
<area shape="poly" title=" " alt="" coords="38,44,38,79,33,79,33,44"/>
</map>
<center><span class="legend">[<a href="graph_legend.html">legend</a>]</span></center></div>
<div class="dynheader">
Collaboration diagram for Node:</div>
<div class="dyncontent">
<div class="center"><img src="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node__coll__graph.png" border="0" usemap="#aNode_coll__map" alt="Collaboration graph"/></div>
<map name="aNode_coll__map" id="aNode_coll__map">
<area shape="rect" title="Concrete subscriber node in the event bus system." alt="" coords="7,79,63,104"/>
<area shape="rect" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html" title="Abstract interface representing a subscriber node in the event bus system." alt="" coords="5,5,65,31"/>
<area shape="poly" title=" " alt="" coords="38,44,38,79,33,79,33,44"/>
</map>
<center><span class="legend">[<a href="graph_legend.html">legend</a>]</span></center></div>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p>Concrete subscriber node in the event bus system. </p>
<p><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" title="Concrete subscriber node in the event bus system.">Node</a> is the concrete implementation of <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a>. It represents a participant in the event bus that can subscribe to specific message types or to broadcast mode, emit and post messages through the bus, and consume received messages from its internal FIFO queue.</p>
<p>Each <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" title="Concrete subscriber node in the event bus system.">Node</a> holds a reference to the <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> it belongs to. Subscriptions and message transmissions are delegated to the bus. Incoming messages are stored in an internal thread-safe queue and can be retrieved via <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a68168b63fcfb3cc18ba23ccbc2c269b7">popMessage()</a>.</p>
<p>The <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" title="Concrete subscriber node in the event bus system.">Node</a> also supports synchronous waiting: a thread can block on <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a90802ca554f4e38a59d1c326468618f0">syncWaitForMessage()</a> until at least one message is available in the queue.</p>
<p>On destruction, the <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" title="Concrete subscriber node in the event bus system.">Node</a> automatically unsubscribes from all event types and broadcast mode, preventing dangling pointers in the bus routing table.</p>
<dl class="section note"><dt>Note</dt><dd><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" title="Concrete subscriber node in the event bus system.">Node</a> is non-copyable and non-movable. </dd>
<dd>
A <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> reference must be provided at construction time. </dd>
<dd>
The <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" title="Concrete subscriber node in the event bus system.">Node</a> does not take ownership of the <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a>.</dd></dl>
<dl class="section user"><dt>Example usage:</dt><dd><div class="fragment"><div class="line"><a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">sdi_toolBox::desktop::eventBus::Bus</a> bus;</div>
<div class="line"><a class="code hl_class" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">sdi_toolBox::desktop::eventBus::Node</a> node(bus);</div>
<div class="line"> </div>
<div class="line">node.subscribe(MY_EVENT_TYPE);</div>
<div class="line">node.emit&lt;MyMessage&gt;(42);</div>
<div class="line"> </div>
<div class="line">node.syncWaitForMessage();</div>
<div class="line"><span class="keyword">auto</span> msg = std::dynamic_pointer_cast&lt;MyMessage&gt;(node.popMessage());</div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Bus_html"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">sdi_toolBox::desktop::eventBus::Bus</a></div><div class="ttdoc">Central message dispatcher for the event bus system.</div><div class="ttdef"><b>Definition</b> <a href="bus_8h_source.html#l00062">bus.h:63</a></div></div>
<div class="ttc" id="aclasssdi__toolBox_1_1desktop_1_1eventBus_1_1Node_html"><div class="ttname"><a href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">sdi_toolBox::desktop::eventBus::Node</a></div><div class="ttdoc">Concrete subscriber node in the event bus system.</div><div class="ttdef"><b>Definition</b> <a href="node_8h_source.html#l00063">node.h:64</a></div></div>
</div><!-- fragment --></dd></dl>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html" title="Central message dispatcher for the event bus system.">Bus</a> </dd>
<dd>
<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html" title="Abstract interface representing a subscriber node in the event bus system.">INode</a> </dd>
<dd>
<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html" title="Base class for all messages dispatched through the event bus.">Message</a> </dd></dl>
<p class="definition">Definition at line <a class="el" href="node_8h_source.html#l00063">63</a> of file <a class="el" href="node_8h_source.html">node.h</a>.</p>
</div><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr><td colspan="2"><div class="groupHeader">Construction &amp; Destruction</div></td></tr>
<tr class="memitem:a9ccb487f15b9518a8cb801f14ca36804" id="r_a9ccb487f15b9518a8cb801f14ca36804"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a9ccb487f15b9518a8cb801f14ca36804">Node</a> ()=delete</td></tr>
<tr class="memdesc:a9ccb487f15b9518a8cb801f14ca36804"><td class="mdescLeft">&#160;</td><td class="mdescRight">Default constructor - deleted. A <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> reference must be provided. <br /></td></tr>
<tr class="separator:a9ccb487f15b9518a8cb801f14ca36804"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a6fa6bf60f34f1e3efb0e59333428c9c8" id="r_a6fa6bf60f34f1e3efb0e59333428c9c8"><td class="memItemLeft" align="right" valign="top">virtual&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a6fa6bf60f34f1e3efb0e59333428c9c8">~Node</a> ()</td></tr>
<tr class="memdesc:a6fa6bf60f34f1e3efb0e59333428c9c8"><td class="mdescLeft">&#160;</td><td class="mdescRight">Destructor. <br /></td></tr>
<tr class="separator:a6fa6bf60f34f1e3efb0e59333428c9c8"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a8655b18ba4c11b25753d741a958bea87" id="r_a8655b18ba4c11b25753d741a958bea87"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a8655b18ba4c11b25753d741a958bea87">Node</a> (const <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a> &amp;obj)=delete</td></tr>
<tr class="memdesc:a8655b18ba4c11b25753d741a958bea87"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy constructor - deleted. <br /></td></tr>
<tr class="separator:a8655b18ba4c11b25753d741a958bea87"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a3d2a90b0a72088cccae1d9bbbed3ca45" id="r_a3d2a90b0a72088cccae1d9bbbed3ca45"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a3d2a90b0a72088cccae1d9bbbed3ca45">Node</a> (<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a> &amp;&amp;obj) noexcept=delete</td></tr>
<tr class="memdesc:a3d2a90b0a72088cccae1d9bbbed3ca45"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move constructor - deleted. <br /></td></tr>
<tr class="separator:a3d2a90b0a72088cccae1d9bbbed3ca45"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a7196569c68b87dc2c0ed116d4a8603f6" id="r_a7196569c68b87dc2c0ed116d4a8603f6"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a7196569c68b87dc2c0ed116d4a8603f6">operator=</a> (const <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a> &amp;obj)=delete</td></tr>
<tr class="memdesc:a7196569c68b87dc2c0ed116d4a8603f6"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy assignment operator - deleted. <br /></td></tr>
<tr class="separator:a7196569c68b87dc2c0ed116d4a8603f6"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a2eeb54ac57183c4201143fc76f5e4b1a" id="r_a2eeb54ac57183c4201143fc76f5e4b1a"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a2eeb54ac57183c4201143fc76f5e4b1a">operator=</a> (<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a> &amp;&amp;obj) noexcept=delete</td></tr>
<tr class="memdesc:a2eeb54ac57183c4201143fc76f5e4b1a"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move assignment operator - deleted. <br /></td></tr>
<tr class="separator:a2eeb54ac57183c4201143fc76f5e4b1a"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aa4d9158beb9bc615b040954434c1db90" id="r_aa4d9158beb9bc615b040954434c1db90"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#aa4d9158beb9bc615b040954434c1db90">Node</a> (<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> &amp;bus)</td></tr>
<tr class="memdesc:aa4d9158beb9bc615b040954434c1db90"><td class="mdescLeft">&#160;</td><td class="mdescRight">Construct a <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" title="Concrete subscriber node in the event bus system.">Node</a> attached to the given <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a>. <br /></td></tr>
<tr class="separator:aa4d9158beb9bc615b040954434c1db90"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr><td colspan="2"><div class="groupHeader">Synchronization</div></td></tr>
<tr class="memitem:a90802ca554f4e38a59d1c326468618f0" id="r_a90802ca554f4e38a59d1c326468618f0"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a90802ca554f4e38a59d1c326468618f0">syncWaitForMessage</a> ()</td></tr>
<tr class="memdesc:a90802ca554f4e38a59d1c326468618f0"><td class="mdescLeft">&#160;</td><td class="mdescRight">Block the calling thread until a message is received. <br /></td></tr>
<tr class="separator:a90802ca554f4e38a59d1c326468618f0"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr><td colspan="2"><div class="groupHeader">Subscription Management</div></td></tr>
<tr class="memitem:a43f475792aedfbbdaf623a8a9065a5c9" id="r_a43f475792aedfbbdaf623a8a9065a5c9"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a43f475792aedfbbdaf623a8a9065a5c9">subscribe</a> (<a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a> eventType)</td></tr>
<tr class="memdesc:a43f475792aedfbbdaf623a8a9065a5c9"><td class="mdescLeft">&#160;</td><td class="mdescRight">Subscribe this node to a specific message type. <br /></td></tr>
<tr class="separator:a43f475792aedfbbdaf623a8a9065a5c9"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aad4f2b01a3e7c46d0253be40e13f2974" id="r_aad4f2b01a3e7c46d0253be40e13f2974"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#aad4f2b01a3e7c46d0253be40e13f2974">unsubscribe</a> (<a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a> eventType)</td></tr>
<tr class="memdesc:aad4f2b01a3e7c46d0253be40e13f2974"><td class="mdescLeft">&#160;</td><td class="mdescRight">Unsubscribe this node from a specific message type. <br /></td></tr>
<tr class="separator:aad4f2b01a3e7c46d0253be40e13f2974"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ade72b9b723cf5c7d43f7cc556a466f99" id="r_ade72b9b723cf5c7d43f7cc556a466f99"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#ade72b9b723cf5c7d43f7cc556a466f99">unsubscribeFromAll</a> ()</td></tr>
<tr class="memdesc:ade72b9b723cf5c7d43f7cc556a466f99"><td class="mdescLeft">&#160;</td><td class="mdescRight">Unsubscribe this node from all message types and broadcast mode. <br /></td></tr>
<tr class="separator:ade72b9b723cf5c7d43f7cc556a466f99"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr><td colspan="2"><div class="groupHeader">Message Transmission</div></td></tr>
<tr class="memitem:a9aab57a60533a1a80a705bc569a9c589" id="r_a9aab57a60533a1a80a705bc569a9c589"><td class="memTemplParams" colspan="2">template&lt;class T , class... Args&gt; </td></tr>
<tr class="memitem:a9aab57a60533a1a80a705bc569a9c589"><td class="memTemplItemLeft" align="right" valign="top">bool&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a9aab57a60533a1a80a705bc569a9c589">emit</a> (Args &amp;&amp;...args)</td></tr>
<tr class="memdesc:a9aab57a60533a1a80a705bc569a9c589"><td class="mdescLeft">&#160;</td><td class="mdescRight">Construct and emit a message of type <code>T</code> through the bus. <br /></td></tr>
<tr class="separator:a9aab57a60533a1a80a705bc569a9c589"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a92c2bc8aa8bcf018ffe954a3e8e34324" id="r_a92c2bc8aa8bcf018ffe954a3e8e34324"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a92c2bc8aa8bcf018ffe954a3e8e34324">post</a> (const std::shared_ptr&lt; <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &gt; &amp;message) const</td></tr>
<tr class="memdesc:a92c2bc8aa8bcf018ffe954a3e8e34324"><td class="mdescLeft">&#160;</td><td class="mdescRight">Post an already constructed message through the bus. <br /></td></tr>
<tr class="separator:a92c2bc8aa8bcf018ffe954a3e8e34324"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr><td colspan="2"><div class="groupHeader">Message queue management</div></td></tr>
<tr class="memitem:ad3c328938178037a51a3f0be5711fa1b" id="r_ad3c328938178037a51a3f0be5711fa1b"><td class="memItemLeft" align="right" valign="top">size_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#ad3c328938178037a51a3f0be5711fa1b">getMessageCount</a> () const</td></tr>
<tr class="memdesc:ad3c328938178037a51a3f0be5711fa1b"><td class="mdescLeft">&#160;</td><td class="mdescRight">Get the number of messages currently in the node's queue. <br /></td></tr>
<tr class="separator:ad3c328938178037a51a3f0be5711fa1b"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a68168b63fcfb3cc18ba23ccbc2c269b7" id="r_a68168b63fcfb3cc18ba23ccbc2c269b7"><td class="memItemLeft" align="right" valign="top">std::shared_ptr&lt; <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a68168b63fcfb3cc18ba23ccbc2c269b7">popMessage</a> ()</td></tr>
<tr class="memdesc:a68168b63fcfb3cc18ba23ccbc2c269b7"><td class="mdescLeft">&#160;</td><td class="mdescRight">Remove and return the front message from the node's queue (FIFO). <br /></td></tr>
<tr class="separator:a68168b63fcfb3cc18ba23ccbc2c269b7"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="inherit_header pub_methods_classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode"><td colspan="2" onclick="javascript:toggleInherit('pub_methods_classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode')"><img src="closed.png" alt="-"/>&#160;Public Member Functions inherited from <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a></td></tr>
<tr class="memitem:ad2a3ec43678e1b15703f874bca9a985d inherit pub_methods_classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode" id="r_ad2a3ec43678e1b15703f874bca9a985d"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#ad2a3ec43678e1b15703f874bca9a985d">INode</a> ()=default</td></tr>
<tr class="memdesc:ad2a3ec43678e1b15703f874bca9a985d inherit pub_methods_classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode"><td class="mdescLeft">&#160;</td><td class="mdescRight">Default constructor. <br /></td></tr>
<tr class="separator:ad2a3ec43678e1b15703f874bca9a985d inherit pub_methods_classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a1356f0d04912be3ec8d8ce7a2b0cddd2 inherit pub_methods_classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode" id="r_a1356f0d04912be3ec8d8ce7a2b0cddd2"><td class="memItemLeft" align="right" valign="top">virtual&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#a1356f0d04912be3ec8d8ce7a2b0cddd2">~INode</a> ()=default</td></tr>
<tr class="memdesc:a1356f0d04912be3ec8d8ce7a2b0cddd2 inherit pub_methods_classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode"><td class="mdescLeft">&#160;</td><td class="mdescRight">Default destructor. <br /></td></tr>
<tr class="separator:a1356f0d04912be3ec8d8ce7a2b0cddd2 inherit pub_methods_classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a5b3ead2689bd5eed4b3617ae6a5e4a09 inherit pub_methods_classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode" id="r_a5b3ead2689bd5eed4b3617ae6a5e4a09"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#a5b3ead2689bd5eed4b3617ae6a5e4a09">INode</a> (const <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> &amp;obj)=delete</td></tr>
<tr class="memdesc:a5b3ead2689bd5eed4b3617ae6a5e4a09 inherit pub_methods_classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy constructor - deleted. <br /></td></tr>
<tr class="separator:a5b3ead2689bd5eed4b3617ae6a5e4a09 inherit pub_methods_classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a48dab9422d43ec52a83947b49845e40b inherit pub_methods_classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode" id="r_a48dab9422d43ec52a83947b49845e40b"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#a48dab9422d43ec52a83947b49845e40b">INode</a> (<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> &amp;&amp;obj) noexcept=delete</td></tr>
<tr class="memdesc:a48dab9422d43ec52a83947b49845e40b inherit pub_methods_classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move constructor - deleted. <br /></td></tr>
<tr class="separator:a48dab9422d43ec52a83947b49845e40b inherit pub_methods_classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aa663d1ba2c5db32e6e463590bae347f8 inherit pub_methods_classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode" id="r_aa663d1ba2c5db32e6e463590bae347f8"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#aa663d1ba2c5db32e6e463590bae347f8">operator=</a> (const <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> &amp;obj)=delete</td></tr>
<tr class="memdesc:aa663d1ba2c5db32e6e463590bae347f8 inherit pub_methods_classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy assignment operator - deleted. <br /></td></tr>
<tr class="separator:aa663d1ba2c5db32e6e463590bae347f8 inherit pub_methods_classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a08395ac07c088d1d64339d4c0d3b52cb inherit pub_methods_classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode" id="r_a08395ac07c088d1d64339d4c0d3b52cb"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#a08395ac07c088d1d64339d4c0d3b52cb">operator=</a> (<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html">INode</a> &amp;&amp;obj) noexcept=delete</td></tr>
<tr class="memdesc:a08395ac07c088d1d64339d4c0d3b52cb inherit pub_methods_classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move assignment operator - deleted. <br /></td></tr>
<tr class="separator:a08395ac07c088d1d64339d4c0d3b52cb inherit pub_methods_classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pri-methods" name="pri-methods"></a>
Private Member Functions</h2></td></tr>
<tr class="memitem:afd326e91fe62057d1b3e1fc5e77f8526" id="r_afd326e91fe62057d1b3e1fc5e77f8526"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#afd326e91fe62057d1b3e1fc5e77f8526">append</a> (const std::shared_ptr&lt; <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &gt; &amp;message) override</td></tr>
<tr class="memdesc:afd326e91fe62057d1b3e1fc5e77f8526"><td class="mdescLeft">&#160;</td><td class="mdescRight">Append a message to the node's internal queue. <br /></td></tr>
<tr class="separator:afd326e91fe62057d1b3e1fc5e77f8526"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
<a id="a9ccb487f15b9518a8cb801f14ca36804" name="a9ccb487f15b9518a8cb801f14ca36804"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a9ccb487f15b9518a8cb801f14ca36804">&#9670;&#160;</a></span>Node() <span class="overload">[1/4]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a> </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">delete</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Default constructor - deleted. A <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> reference must be provided. </p>
</div>
</div>
<a id="a6fa6bf60f34f1e3efb0e59333428c9c8" name="a6fa6bf60f34f1e3efb0e59333428c9c8"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a6fa6bf60f34f1e3efb0e59333428c9c8">&#9670;&#160;</a></span>~Node()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">~<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a> </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span><span class="mlabel">virtual</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Destructor. </p>
<p>Automatically unsubscribes the node from all specific event types and broadcast mode via <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#ade72b9b723cf5c7d43f7cc556a466f99">unsubscribeFromAll()</a>, preventing dangling pointers in the bus routing table. Also notifies any thread blocked in <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a90802ca554f4e38a59d1c326468618f0">syncWaitForMessage()</a> to unblock it gracefully. </p>
<p class="definition">Definition at line <a class="el" href="node_8h_source.html#l00276">276</a> of file <a class="el" href="node_8h_source.html">node.h</a>.</p>
</div>
</div>
<a id="a8655b18ba4c11b25753d741a958bea87" name="a8655b18ba4c11b25753d741a958bea87"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a8655b18ba4c11b25753d741a958bea87">&#9670;&#160;</a></span>Node() <span class="overload">[2/4]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a> </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a> &amp;&#160;</td>
<td class="paramname"><em>obj</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">delete</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Copy constructor - deleted. </p>
<p><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" title="Concrete subscriber node in the event bus system.">Node</a> is non-copyable. </p>
</div>
</div>
<a id="a3d2a90b0a72088cccae1d9bbbed3ca45" name="a3d2a90b0a72088cccae1d9bbbed3ca45"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a3d2a90b0a72088cccae1d9bbbed3ca45">&#9670;&#160;</a></span>Node() <span class="overload">[3/4]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a> </td>
<td>(</td>
<td class="paramtype"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a> &amp;&amp;&#160;</td>
<td class="paramname"><em>obj</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">delete</span><span class="mlabel">noexcept</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Move constructor - deleted. </p>
<p><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" title="Concrete subscriber node in the event bus system.">Node</a> is non-movable. </p>
</div>
</div>
<a id="aa4d9158beb9bc615b040954434c1db90" name="aa4d9158beb9bc615b040954434c1db90"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aa4d9158beb9bc615b040954434c1db90">&#9670;&#160;</a></span>Node() <span class="overload">[4/4]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a> </td>
<td>(</td>
<td class="paramtype"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> &amp;&#160;</td>
<td class="paramname"><em>bus</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span><span class="mlabel">explicit</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Construct a <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" title="Concrete subscriber node in the event bus system.">Node</a> attached to the given <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a>. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">bus</td><td>Reference to the <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> this node belongs to. The bus must outlive the node. </td></tr>
</table>
</dd>
</dl>
<p class="definition">Definition at line <a class="el" href="node_8h_source.html#l00269">269</a> of file <a class="el" href="node_8h_source.html">node.h</a>.</p>
</div>
</div>
<h2 class="groupheader">Member Function Documentation</h2>
<a id="a7196569c68b87dc2c0ed116d4a8603f6" name="a7196569c68b87dc2c0ed116d4a8603f6"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a7196569c68b87dc2c0ed116d4a8603f6">&#9670;&#160;</a></span>operator=() <span class="overload">[1/2]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a> &amp; operator= </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a> &amp;&#160;</td>
<td class="paramname"><em>obj</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">delete</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Copy assignment operator - deleted. </p>
<p><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" title="Concrete subscriber node in the event bus system.">Node</a> is non-copyable. </p>
</div>
</div>
<a id="a2eeb54ac57183c4201143fc76f5e4b1a" name="a2eeb54ac57183c4201143fc76f5e4b1a"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a2eeb54ac57183c4201143fc76f5e4b1a">&#9670;&#160;</a></span>operator=() <span class="overload">[2/2]</span></h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a> &amp; operator= </td>
<td>(</td>
<td class="paramtype"><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html">Node</a> &amp;&amp;&#160;</td>
<td class="paramname"><em>obj</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">delete</span><span class="mlabel">noexcept</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Move assignment operator - deleted. </p>
<p><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" title="Concrete subscriber node in the event bus system.">Node</a> is non-movable. </p>
</div>
</div>
<a id="a90802ca554f4e38a59d1c326468618f0" name="a90802ca554f4e38a59d1c326468618f0"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a90802ca554f4e38a59d1c326468618f0">&#9670;&#160;</a></span>syncWaitForMessage()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">void syncWaitForMessage </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Block the calling thread until a message is received. </p>
<p>Suspends the calling thread using an atomic wait until at least one message has been appended to the node's internal queue by the <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a>. This method is intended for synchronous event-driven patterns where a thread should idle until work is available.</p>
<dl class="section note"><dt>Note</dt><dd>Returns immediately if a message is already pending in the queue at the time of the call. </dd>
<dd>
If the <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html" title="Concrete subscriber node in the event bus system.">Node</a> is destroyed while a thread is blocked here, the destructor triggers a notification to unblock the waiting thread gracefully. </dd></dl>
<dl class="section warning"><dt>Warning</dt><dd>The caller is responsible for checking the queue after this call returns, as the notification may also be triggered by the destructor with an empty queue. </dd></dl>
<p class="definition">Definition at line <a class="el" href="node_8h_source.html#l00286">286</a> of file <a class="el" href="node_8h_source.html">node.h</a>.</p>
</div>
</div>
<a id="a43f475792aedfbbdaf623a8a9065a5c9" name="a43f475792aedfbbdaf623a8a9065a5c9"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a43f475792aedfbbdaf623a8a9065a5c9">&#9670;&#160;</a></span>subscribe()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">void subscribe </td>
<td>(</td>
<td class="paramtype"><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a>&#160;</td>
<td class="paramname"><em>eventType</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Subscribe this node to a specific message type. </p>
<p>Delegates to <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#aaed1ce9185dbc68270991a68901e1d3e">Bus::subscribe()</a>. The node will receive all messages of the given type posted to the bus. Duplicate subscriptions are ignored.</p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">eventType</td><td>The message type identifier to subscribe to. </td></tr>
</table>
</dd>
</dl>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#aaed1ce9185dbc68270991a68901e1d3e" title="Subscribe a node to a specific message type.">Bus::subscribe()</a> </dd></dl>
<p class="definition">Definition at line <a class="el" href="node_8h_source.html#l00295">295</a> of file <a class="el" href="node_8h_source.html">node.h</a>.</p>
</div>
</div>
<a id="aad4f2b01a3e7c46d0253be40e13f2974" name="aad4f2b01a3e7c46d0253be40e13f2974"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aad4f2b01a3e7c46d0253be40e13f2974">&#9670;&#160;</a></span>unsubscribe()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">void unsubscribe </td>
<td>(</td>
<td class="paramtype"><a class="el" href="namespacesdi__toolBox_1_1desktop_1_1eventBus.html#a9a6bed6d55e3ccf6e4b27ebfa879277c">MessageTypeID</a>&#160;</td>
<td class="paramname"><em>eventType</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Unsubscribe this node from a specific message type. </p>
<p>Delegates to <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a27cc2e333f174e22b360045c7aad959d">Bus::unsubscribe()</a>. If the node was not subscribed to the given type, this call has no effect.</p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">eventType</td><td>The message type identifier to unsubscribe from. </td></tr>
</table>
</dd>
</dl>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a27cc2e333f174e22b360045c7aad959d" title="Unsubscribe a node from a specific message type.">Bus::unsubscribe()</a> </dd></dl>
<p class="definition">Definition at line <a class="el" href="node_8h_source.html#l00301">301</a> of file <a class="el" href="node_8h_source.html">node.h</a>.</p>
</div>
</div>
<a id="ade72b9b723cf5c7d43f7cc556a466f99" name="ade72b9b723cf5c7d43f7cc556a466f99"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ade72b9b723cf5c7d43f7cc556a466f99">&#9670;&#160;</a></span>unsubscribeFromAll()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">void unsubscribeFromAll </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Unsubscribe this node from all message types and broadcast mode. </p>
<p>Delegates to <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#af42df59cac80896d270e4bf2b350676f">Bus::unsubscribeFromAll()</a>. After this call, the node will no longer receive any messages until it re-subscribes.</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#af42df59cac80896d270e4bf2b350676f" title="Unsubscribe a node from all message types and broadcast mode.">Bus::unsubscribeFromAll()</a> </dd></dl>
<p class="definition">Definition at line <a class="el" href="node_8h_source.html#l00307">307</a> of file <a class="el" href="node_8h_source.html">node.h</a>.</p>
</div>
</div>
<a id="a9aab57a60533a1a80a705bc569a9c589" name="a9aab57a60533a1a80a705bc569a9c589"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a9aab57a60533a1a80a705bc569a9c589">&#9670;&#160;</a></span>emit()</h2>
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class T , class... Args&gt; </div>
<table class="memname">
<tr>
<td class="memname">bool emit </td>
<td>(</td>
<td class="paramtype">Args &amp;&amp;...&#160;</td>
<td class="paramname"><em>args</em></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Construct and emit a message of type <code>T</code> through the bus. </p>
<p>Forwards the call to <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a9aab57a60533a1a80a705bc569a9c589">Bus::emit()</a>. Creates a new message of type <code>T</code> using the provided arguments and posts it to the bus.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
<table class="tparams">
<tr><td class="paramname">T</td><td>The message type to emit. Must be derived from <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a>. </td></tr>
<tr><td class="paramname">Args</td><td>Constructor argument types for <code>T</code>. </td></tr>
</table>
</dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">args</td><td>Arguments forwarded to the constructor of <code>T</code>. </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>true</code> if at least one subscriber received the message, <code>false</code> otherwise.</dd></dl>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a9aab57a60533a1a80a705bc569a9c589" title="Construct and emit a message of type T to the bus.">Bus::emit()</a> </dd></dl>
<p class="definition">Definition at line <a class="el" href="node_8h_source.html#l00314">314</a> of file <a class="el" href="node_8h_source.html">node.h</a>.</p>
</div>
</div>
<a id="a92c2bc8aa8bcf018ffe954a3e8e34324" name="a92c2bc8aa8bcf018ffe954a3e8e34324"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a92c2bc8aa8bcf018ffe954a3e8e34324">&#9670;&#160;</a></span>post()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">bool post </td>
<td>(</td>
<td class="paramtype">const std::shared_ptr&lt; <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &gt; &amp;&#160;</td>
<td class="paramname"><em>message</em></td><td>)</td>
<td> const</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Post an already constructed message through the bus. </p>
<p>Forwards the call to <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a92c2bc8aa8bcf018ffe954a3e8e34324">Bus::post()</a>.</p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">message</td><td>Shared pointer to the message to post. Must not be <code>nullptr</code>. </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>true</code> if at least one subscriber received the message, <code>false</code> otherwise.</dd></dl>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html#a92c2bc8aa8bcf018ffe954a3e8e34324" title="Post an already constructed message to the bus.">Bus::post()</a> </dd></dl>
<p class="definition">Definition at line <a class="el" href="node_8h_source.html#l00320">320</a> of file <a class="el" href="node_8h_source.html">node.h</a>.</p>
</div>
</div>
<a id="ad3c328938178037a51a3f0be5711fa1b" name="ad3c328938178037a51a3f0be5711fa1b"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ad3c328938178037a51a3f0be5711fa1b">&#9670;&#160;</a></span>getMessageCount()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">size_t getMessageCount </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td> const</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Get the number of messages currently in the node's queue. </p>
<dl class="section return"><dt>Returns</dt><dd>The number of pending messages waiting to be consumed. </dd></dl>
<dl class="section note"><dt>Note</dt><dd>This operation is thread-safe. </dd></dl>
<p class="definition">Definition at line <a class="el" href="node_8h_source.html#l00326">326</a> of file <a class="el" href="node_8h_source.html">node.h</a>.</p>
</div>
</div>
<a id="a68168b63fcfb3cc18ba23ccbc2c269b7" name="a68168b63fcfb3cc18ba23ccbc2c269b7"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a68168b63fcfb3cc18ba23ccbc2c269b7">&#9670;&#160;</a></span>popMessage()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">std::shared_ptr&lt; <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &gt; popMessage </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Remove and return the front message from the node's queue (FIFO). </p>
<p>Retrieves the oldest message in the queue and removes it. If the queue is empty, returns <code>nullptr</code>.</p>
<dl class="section return"><dt>Returns</dt><dd>A shared pointer to the front <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a>, or <code>nullptr</code> if the queue is empty. </dd></dl>
<dl class="section note"><dt>Note</dt><dd>This operation is thread-safe. </dd></dl>
<p class="definition">Definition at line <a class="el" href="node_8h_source.html#l00334">334</a> of file <a class="el" href="node_8h_source.html">node.h</a>.</p>
</div>
</div>
<a id="afd326e91fe62057d1b3e1fc5e77f8526" name="afd326e91fe62057d1b3e1fc5e77f8526"></a>
<h2 class="memtitle"><span class="permalink"><a href="#afd326e91fe62057d1b3e1fc5e77f8526">&#9670;&#160;</a></span>append()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">void append </td>
<td>(</td>
<td class="paramtype">const std::shared_ptr&lt; <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a> &gt; &amp;&#160;</td>
<td class="paramname"><em>message</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span><span class="mlabel">override</span><span class="mlabel">private</span><span class="mlabel">virtual</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Append a message to the node's internal queue. </p>
<p>Called exclusively by <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Bus.html">Bus</a> when dispatching a message to this node. Pushes the message onto the queue and notifies any thread waiting in <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Node.html#a90802ca554f4e38a59d1c326468618f0">syncWaitForMessage()</a>.</p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">message</td><td>Shared pointer to the message being delivered. </td></tr>
</table>
</dd>
</dl>
<p>Implements <a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html#ac8043e64bbbd7a7a2b324991e96231ef">INode</a>.</p>
<p class="definition">Definition at line <a class="el" href="node_8h_source.html#l00348">348</a> of file <a class="el" href="node_8h_source.html">node.h</a>.</p>
</div>
</div>
<h2 class="groupheader">Member Data Documentation</h2>
<a id="ad5e0dbd36f0d71fce9b00b7f991b2f38" name="ad5e0dbd36f0d71fce9b00b7f991b2f38"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ad5e0dbd36f0d71fce9b00b7f991b2f38">&#9670;&#160;</a></span>mtx</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">std::mutex mtx</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">mutable</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Mutex for thread-safe access to the message queue. </p>
<p class="definition">Definition at line <a class="el" href="node_8h_source.html#l00262">262</a> of file <a class="el" href="node_8h_source.html">node.h</a>.</p>
</div>
</div>
<a id="a8a28311e9640e7d150b254d83424c08c" name="a8a28311e9640e7d150b254d83424c08c"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a8a28311e9640e7d150b254d83424c08c">&#9670;&#160;</a></span>messageQueue</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">std::queue&lt;std::shared_ptr&lt;<a class="el" href="classsdi__toolBox_1_1desktop_1_1eventBus_1_1Message.html">Message</a>&gt; &gt; messageQueue</td>
</tr>
</table>
</div><div class="memdoc">
<p>Queue of messages received by the node. </p>
<p class="definition">Definition at line <a class="el" href="node_8h_source.html#l00263">263</a> of file <a class="el" href="node_8h_source.html">node.h</a>.</p>
</div>
</div>
</div><!-- contents -->
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
SDi toolsBox is licensed under the terms and conditions of the <a href="https://opensource.org/licenses/zlib-license.php" target="_blank">zlib/png license</a>
<br />
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE | ver: 2.x.x - build: 2026-04-28
<br />
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen" /></a> 1.9.8
</small>
</address>
</body>
</html>

View File

@@ -0,0 +1,5 @@
<map id="Node" name="Node">
<area shape="rect" id="Node000001" title="Concrete subscriber node in the event bus system." alt="" coords="7,79,63,104"/>
<area shape="rect" id="Node000002" href="$classsdi__toolBox_1_1desktop_1_1eventBus_1_1INode.html" title="Abstract interface representing a subscriber node in the event bus system." alt="" coords="5,5,65,31"/>
<area shape="poly" id="edge1_Node000001_Node000002" title=" " alt="" coords="38,44,38,79,33,79,33,44"/>
</map>

Some files were not shown because too many files have changed in this diff Show More