Skip to content

Commit 87de255

Browse files
committed
Update DelegateMQ library
1 parent 8fa9ec8 commit 87de255

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1898
-523
lines changed

DelegateMQ/DelegateMQ.h

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,9 @@
102102
// -----------------------------------------------------------------------------
103103
// 4. Asynchronous "Blocking" Delegates (Wait for Result)
104104
// -----------------------------------------------------------------------------
105-
// Depends on std::future/std::promise.
106-
// Valid for StdLib (Windows/Linux) and Qt.
107-
// (RTOS support depends on if the toolchain provides a full C++ STL)
108-
#if defined(DMQ_THREAD_STDLIB) || defined(DMQ_THREAD_QT)
105+
// Depends on Semaphore/Mutex and C++17 (std::any, std::optional).
106+
// Valid for StdLib (Windows/Linux), Qt, ThreadX, and FreeRTOS (if C++17 enabled).
107+
#if defined(DMQ_THREAD_STDLIB) || defined(DMQ_THREAD_QT) || defined(DMQ_THREAD_FREERTOS) || defined(DMQ_THREAD_THREADX)
109108
#include "delegate/DelegateAsyncWait.h"
110109
#endif
111110

@@ -130,7 +129,7 @@
130129
#elif defined(DMQ_THREAD_NONE)
131130
// Bare metal: User must implement their own polling/interrupt logic
132131
#else
133-
#error "Thread implementation not found."
132+
#warning "Thread implementation not found."
134133
#endif
135134

136135
#if defined(DMQ_SERIALIZE_MSGPACK)
@@ -146,7 +145,7 @@
146145
#elif defined(DMQ_SERIALIZE_NONE)
147146
// Create a custom application-specific serializer
148147
#else
149-
#error "Serialize implementation not found."
148+
#warning "Serialize implementation not found."
150149
#endif
151150

152151
#if defined(DMQ_TRANSPORT_ZEROMQ)
@@ -179,21 +178,22 @@
179178
#elif defined(DMQ_TRANSPORT_ARM_LWIP_UDP)
180179
#include "predef/dispatcher/Dispatcher.h"
181180
#include "predef/transport/arm-lwip-udp/ArmLwipUdpTransport.h"
181+
#elif defined(DMQ_TRANSPORT_ARM_LWIP_NETCONN_UDP)
182+
#include "predef/dispatcher/Dispatcher.h"
183+
#include "predef/transport/arm-lwip-netconn-udp/ArmLwipNetconnUdpTransport.h"
182184
#elif defined(DMQ_TRANSPORT_THREADX_UDP)
183185
#include "predef/dispatcher/Dispatcher.h"
184186
#include "predef/transport/threadx-udp/NetXUdpTransport.h"
187+
#elif defined(DMQ_TRANSPORT_STM32_UART)
188+
#include "predef/dispatcher/Dispatcher.h"
189+
#include "predef/transport/stm32-uart/Stm32UartTransport.h"
185190
#elif defined(DMQ_TRANSPORT_ZEPHYR_UDP)
186191
#include "predef/dispatcher/Dispatcher.h"
187192
#include "predef/transport/zephyr-udp/ZephyrUdpTransport.h"
188193
#elif defined(DMQ_TRANSPORT_NONE)
189194
// Create a custom application-specific transport
190195
#else
191-
#error "Transport implementation not found."
192-
#endif
193-
194-
#if defined(DMQ_TRANSPORT_ZEROMQ) || defined(DMQ_TRANSPORT_WIN32_UDP) || defined(DMQ_TRANSPORT_LINUX_UDP) || \
195-
defined(DMQ_TRANSPORT_THREADX_UDP) || defined(DMQ_TRANSPORT_ZEPHYR_UDP)
196-
#include "predef/util/NetworkEngine.h"
196+
#warning "Transport implementation not found."
197197
#endif
198198

199199
#include "predef/util/Fault.h"
@@ -205,4 +205,11 @@
205205
#include "predef/util/TransportMonitor.h"
206206
#endif
207207

208-
#endif
208+
// Only include NetworkEngine if a transport that uses it is active
209+
#if defined(DMQ_TRANSPORT_ZEROMQ) || defined(DMQ_TRANSPORT_WIN32_UDP) || \
210+
defined(DMQ_TRANSPORT_LINUX_UDP) || defined(DMQ_TRANSPORT_STM32_UART) || \
211+
defined(DMQ_TRANSPORT_SERIAL_PORT)
212+
#include "predef/util/NetworkEngine.h"
213+
#endif
214+
215+
#endif

DelegateMQ/External.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ endif()
109109
# ---------------------------------------------------------------------------
110110
# lwIP library (For ARM/Embedded)
111111
# ---------------------------------------------------------------------------
112-
if(DMQ_TRANSPORT STREQUAL "DMQ_TRANSPORT_ARM_LWIP_UDP")
112+
if(DMQ_TRANSPORT STREQUAL "DMQ_TRANSPORT_ARM_LWIP_UDP" OR DMQ_TRANSPORT STREQUAL "DMQ_TRANSPORT_ARM_LWIP_NETCONN_UDP")
113+
113114
# Adjust this path if your lwIP root is different
114115
set(LWIP_ROOT "${DMQ_ROOT_DIR}/../../../lwip")
115116

@@ -119,7 +120,6 @@ if(DMQ_TRANSPORT STREQUAL "DMQ_TRANSPORT_ARM_LWIP_UDP")
119120

120121
# Often required for lwipopts.h or arch/cc.h.
121122
# NOTE: You may need to customize this depending on where your project keeps 'lwipopts.h'
122-
# For now, we point to the generic 'contrib' ports if present, or just the root.
123123
set(LWIP_INCLUDE_DIR_3 "${LWIP_ROOT}/contrib/ports/unix/port/include")
124124

125125
set(LWIP_INCLUDE_DIRS

DelegateMQ/Predef.cmake

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,15 @@ elseif (DMQ_TRANSPORT STREQUAL "DMQ_TRANSPORT_SERIAL_PORT")
8989
elseif (DMQ_TRANSPORT STREQUAL "DMQ_TRANSPORT_ARM_LWIP_UDP")
9090
add_compile_definitions(DMQ_TRANSPORT_ARM_LWIP_UDP)
9191
file(GLOB TRANSPORT_SOURCES "${DMQ_ROOT_DIR}/predef/transport/arm-lwip-udp/*.h")
92+
elseif (DMQ_TRANSPORT STREQUAL "DMQ_TRANSPORT_ARM_LWIP_NETCONN_UDP")
93+
add_compile_definitions(DMQ_TRANSPORT_ARM_LWIP_NETCONN_UDP)
94+
file(GLOB TRANSPORT_SOURCES "${DMQ_ROOT_DIR}/predef/transport/arm-lwip-netconn-udp/*.h")
9295
elseif (DMQ_TRANSPORT STREQUAL "DMQ_TRANSPORT_THREADX_UDP")
9396
add_compile_definitions(DMQ_TRANSPORT_THREADX_UDP)
9497
file(GLOB TRANSPORT_SOURCES "${DMQ_ROOT_DIR}/predef/transport/threadx-udp/*.h")
98+
elseif (DMQ_TRANSPORT STREQUAL "DMQ_TRANSPORT_STM32_UART")
99+
add_compile_definitions(DMQ_TRANSPORT_STM32_UART)
100+
file(GLOB TRANSPORT_SOURCES "${DMQ_ROOT_DIR}/predef/transport/stm32-uart/*.h")
95101
elseif (DMQ_TRANSPORT STREQUAL "DMQ_TRANSPORT_ZEPHYR_UDP")
96102
add_compile_definitions(DMQ_TRANSPORT_ZEPHYR_UDP)
97103
file(GLOB TRANSPORT_SOURCES "${DMQ_ROOT_DIR}/predef/transport/zephyr-udp/*.h")

DelegateMQ/delegate/Delegate.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,12 +705,20 @@ class DelegateFunction<RetType(Args...)> : public Delegate<RetType(Args...)> {
705705
/// @param[in] func The `std::function` to bind to the delegate. This function must
706706
/// match the signature of the delegate.
707707
void Bind(FunctionType func) {
708+
#if !defined(__cpp_exceptions) || defined(DMQ_ASSERTS)
709+
// No exceptions: Direct assignment.
710+
// If the STL needs to allocate memory here and fails,
711+
// it will likely abort() internally on embedded systems.
712+
m_func = func;
713+
#else
714+
// Exceptions enabled: Safe to try-catch.
708715
try {
709716
m_func = func;
710717
}
711718
catch (const std::bad_alloc&) {
712719
BAD_ALLOC();
713720
}
721+
#endif
714722
}
715723

716724
/// Compares two ClassType objects using the '<' operator.

DelegateMQ/delegate/DelegateAsyncWait.h

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -437,12 +437,27 @@ class DelegateFreeAsyncWait<RetType(Args...)> : public DelegateFree<RetType(Args
437437
/// Get the asynchronous function return value
438438
/// @return The destination thread target function return value
439439
RetType GetRetVal() noexcept {
440+
// Use pointer cast if exceptions are disabled OR if user requested Asserts-only mode
441+
#if !defined(__cpp_exceptions) || defined(DMQ_ASSERTS)
442+
// Fast, non-throwing check suitable for Embedded/Real-time
443+
auto* p = std::any_cast<RetType>(&m_retVal);
444+
if (p) return *p;
445+
446+
// Optional: If you want to trap this error in debug mode
447+
#if defined(DMQ_ASSERTS)
448+
ASSERT();
449+
#endif
450+
451+
return RetType();
452+
#else
453+
// Standard C++ behavior with Exception Handling
440454
try {
441455
return std::any_cast<RetType>(m_retVal);
442456
}
443457
catch (const std::bad_any_cast&) {
444-
return RetType(); // Return a default value if error
458+
return RetType();
445459
}
460+
#endif
446461
}
447462

448463
///@brief Get the destination thread that the target function is invoked on.
@@ -858,12 +873,27 @@ class DelegateMemberAsyncWait<TClass, RetType(Args...)> : public DelegateMember<
858873
/// Get the asynchronous function return value
859874
/// @return The destination thread target function return value
860875
RetType GetRetVal() noexcept {
876+
// Use pointer cast if exceptions are disabled OR if user requested Asserts-only mode
877+
#if !defined(__cpp_exceptions) || defined(DMQ_ASSERTS)
878+
// Fast, non-throwing check suitable for Embedded/Real-time
879+
auto* p = std::any_cast<RetType>(&m_retVal);
880+
if (p) return *p;
881+
882+
// Optional: If you want to trap this error in debug mode
883+
#if defined(DMQ_ASSERTS)
884+
ASSERT();
885+
#endif
886+
887+
return RetType();
888+
#else
889+
// Standard C++ behavior with Exception Handling
861890
try {
862891
return std::any_cast<RetType>(m_retVal);
863892
}
864893
catch (const std::bad_any_cast&) {
865-
return RetType(); // Return a default value if error
894+
return RetType();
866895
}
896+
#endif
867897
}
868898

869899
///@brief Get the destination thread that the target function is invoked on.
@@ -1196,12 +1226,27 @@ class DelegateMemberAsyncWaitSp<TClass, RetType(Args...)> : public DelegateMembe
11961226
/// Get the asynchronous function return value
11971227
/// @return The destination thread target function return value
11981228
RetType GetRetVal() noexcept {
1229+
// Use pointer cast if exceptions are disabled OR if user requested Asserts-only mode
1230+
#if !defined(__cpp_exceptions) || defined(DMQ_ASSERTS)
1231+
// Fast, non-throwing check suitable for Embedded/Real-time
1232+
auto* p = std::any_cast<RetType>(&m_retVal);
1233+
if (p) return *p;
1234+
1235+
// Optional: If you want to trap this error in debug mode
1236+
#if defined(DMQ_ASSERTS)
1237+
ASSERT();
1238+
#endif
1239+
1240+
return RetType();
1241+
#else
1242+
// Standard C++ behavior with Exception Handling
11991243
try {
12001244
return std::any_cast<RetType>(m_retVal);
12011245
}
12021246
catch (const std::bad_any_cast&) {
1203-
return RetType(); // Return a default value if error
1247+
return RetType();
12041248
}
1249+
#endif
12051250
}
12061251

12071252
///@brief Get the destination thread that the target function is invoked on.
@@ -1536,12 +1581,27 @@ class DelegateFunctionAsyncWait<RetType(Args...)> : public DelegateFunction<RetT
15361581
/// Get the asynchronous function return value
15371582
/// @return The destination thread target function return value
15381583
RetType GetRetVal() noexcept {
1584+
// Use pointer cast if exceptions are disabled OR if user requested Asserts-only mode
1585+
#if !defined(__cpp_exceptions) || defined(DMQ_ASSERTS)
1586+
// Fast, non-throwing check suitable for Embedded/Real-time
1587+
auto* p = std::any_cast<RetType>(&m_retVal);
1588+
if (p) return *p;
1589+
1590+
// Optional: If you want to trap this error in debug mode
1591+
#if defined(DMQ_ASSERTS)
1592+
ASSERT();
1593+
#endif
1594+
1595+
return RetType();
1596+
#else
1597+
// Standard C++ behavior with Exception Handling
15391598
try {
15401599
return std::any_cast<RetType>(m_retVal);
15411600
}
15421601
catch (const std::bad_any_cast&) {
1543-
return RetType(); // Return a default value if error
1602+
return RetType();
15441603
}
1604+
#endif
15451605
}
15461606

15471607
///@brief Get the destination thread that the target function is invoked on.

DelegateMQ/delegate/DelegateMsg.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class DelegateMsg
3030
/// Constructor
3131
/// @param[in] invoker - the invoker instance the delegate is registered with.
3232
DelegateMsg(std::shared_ptr<IThreadInvoker> invoker, Priority priority) :
33-
m_priority(priority), m_invoker(invoker)
33+
m_invoker(invoker), m_priority(priority)
3434
{
3535
}
3636

DelegateMQ/delegate/DelegateOpt.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
#if defined(DMQ_THREAD_FREERTOS)
1111
#include "predef/util/FreeRTOSClock.h"
1212
#include "predef/util/FreeRTOSMutex.h"
13+
#include "predef/util/FreeRTOSConditionVariable.h"
1314
#elif defined(DMQ_THREAD_THREADX)
1415
#include "predef/util/ThreadXClock.h"
1516
#include "predef/util/ThreadXMutex.h"
17+
#include "predef/util/ThreadXConditionVariable.h"
1618
#elif defined(DMQ_THREAD_ZEPHYR)
1719
#include "predef/util/ZephyrClock.h"
1820
#include "predef/util/ZephyrMutex.h"
@@ -21,6 +23,9 @@
2123
#include "predef/util/CmsisRtos2Mutex.h"
2224
#elif defined(DMQ_THREAD_NONE)
2325
#include "predef/util/BareMetalClock.h"
26+
#else
27+
// Windows / Linux / macOS (Standard Library)
28+
#include <condition_variable>
2429
#endif
2530

2631
namespace dmq
@@ -62,11 +67,13 @@ namespace dmq
6267
// Use the custom FreeRTOS wrapper
6368
using Mutex = dmq::FreeRTOSMutex;
6469
using RecursiveMutex = dmq::FreeRTOSRecursiveMutex;
70+
using ConditionVariable = dmq::FreeRTOSConditionVariable;
6571

6672
#elif defined(DMQ_THREAD_THREADX)
6773
// Use the custom ThreadX wrapper
6874
using Mutex = dmq::ThreadXMutex;
6975
using RecursiveMutex = dmq::ThreadXRecursiveMutex;
76+
using ConditionVariable = dmq::ThreadXConditionVariable;
7077

7178
#elif defined(DMQ_THREAD_ZEPHYR)
7279
// Use the custom Zephyr wrapper
@@ -91,16 +98,19 @@ namespace dmq
9198
// Windows / Linux / macOS / Qt
9299
using Mutex = std::mutex;
93100
using RecursiveMutex = std::recursive_mutex;
101+
using ConditionVariable = std::condition_variable;
94102
#endif
95103
}
96104

97105
// @TODO: Select the desired software fault handling (see Predef.cmake).
98106
#ifdef DMQ_ASSERTS
107+
#include "predef/util/Fault.h"
99108
#include <cassert>
100109
// Use assert error handling. Change assert to a different error
101110
// handler as required by the target application.
102111
#define BAD_ALLOC() assert(false && "Memory allocation failed!")
103112
#else
113+
#include "predef/util/Fault.h"
104114
#include <new>
105115
// Use exception error handling
106116
#define BAD_ALLOC() throw std::bad_alloc()
@@ -113,10 +123,12 @@ namespace dmq
113123
// See master CMakeLists.txt for info on enabling the fixed-block allocator.
114124
#ifdef DMQ_ALLOCATOR
115125
// Use stl_allocator fixed-block allocator for dynamic storage allocation
126+
#include "predef/allocator/xstring.h"
116127
#include "predef/allocator/xlist.h"
117128
#include "predef/allocator/xsstream.h"
118129
#include "predef/allocator/stl_allocator.h"
119130
#else
131+
#include <string>
120132
#include <list>
121133
#include <sstream>
122134

@@ -134,6 +146,9 @@ namespace dmq
134146

135147
typedef std::basic_ostringstream<char, std::char_traits<char>> xostringstream;
136148
typedef std::basic_stringstream<char, std::char_traits<char>> xstringstream;
149+
150+
typedef std::string xstring;
151+
typedef std::wstring xwstring;
137152
#endif
138153

139154
// @TODO: Select the desired logging (see Predef.cmake).

0 commit comments

Comments
 (0)