@@ -20,6 +20,8 @@ The C++ delegates library can invoke any callable function synchronously, asynch
2020 - [ Build Options] ( #build-options )
2121 - [ Example Projects] ( #example-projects )
2222 - [ ` bare-metal ` ] ( #bare-metal )
23+ - [ ` win32-pipe-serializer ` ] ( #win32-pipe-serializer )
24+ - [ ` win32-upd-serializer ` ] ( #win32-upd-serializer )
2325 - [ ` zeromq-serializer ` ] ( #zeromq-serializer )
2426 - [ ` zeromq-msgpack-cpp ` ] ( #zeromq-msgpack-cpp )
2527 - [ ` system-architecture ` ] ( #system-architecture )
@@ -201,7 +203,25 @@ Remote delegate example with no external libraries.
201203| Interface | Implementation |
202204| --- | --- |
203205| `ISerializer` | Insertion `operator<<` and extraction `operator>>` operators.
204- | `IDispatcher` | Shared sender/receiver `std::stringstream`.
206+ | `IDispatcher` | Shared sender/receiver `std::stringstream` for dispatcher transport.
207+
208+ ### `win32-pipe-serializer`
209+
210+ Remote delegate example with Windows pipe and `serialize`.
211+
212+ | Interface | Implementation |
213+ | --- | --- |
214+ | `ISerializer` | `serialize` class.
215+ | `IDispatcher` | Windows data pipe for dispatcher transport.
216+
217+ ### `win32-upd-serializer`
218+
219+ Remote delegate example with Windows UDP socket and `serialize`.
220+
221+ | Interface | Implementation |
222+ | --- | --- |
223+ | `ISerializer` | `serialize` class.
224+ | `IDispatcher` | Windows UDP socket for dispatcher transport.
205225
206226### `zeromq-serializer`
207227
@@ -210,7 +230,7 @@ Remote delegate example using ZeroMQ and `serialize`.
210230| Interface | Implementation |
211231| --- | --- |
212232| `ISerializer` | `serialize` class.
213- | `IDispatcher` | ZeroMQ library.
233+ | `IDispatcher` | ZeroMQ library for dispatcher transport .
214234
215235### `zeromq-msgpack-cpp`
216236
@@ -219,7 +239,7 @@ Remote delegate example using ZeroMQ and MessagePack libraries.
219239| Interface | Implementation |
220240| --- | --- |
221241| `ISerializer` | MessagePack library.
222- | `IDispatcher` | ZeroMQ library.
242+ | `IDispatcher` | ZeroMQ library for dispatcher transport .
223243
224244### `system-architecture`
225245
@@ -228,7 +248,7 @@ Remote delegate example showing a complex system architecture using ZeroMQ and M
228248| Interface | Implementation |
229249| --- | --- |
230250| `ISerializer` | MessagePack library. |
231- | `IDispatcher` | ZeroMQ library. |
251+ | `IDispatcher` | ZeroMQ library for dispatcher transport . |
232252
233253# DelegateMQ Dependencies
234254
@@ -887,17 +907,17 @@ The `IThread` interface is used to send a delegate and argument data through a m
887907class IThread
888908{
889909public:
890- /// Destructor
891- virtual ~IThread() = default;
892-
893- /// Dispatch a DelegateMsg onto this thread. The implementer is responsible
894- /// for getting the DelegateMsg into an OS message queue. Once DelegateMsg
895- /// is on the correct thread of control, the DelegateInvoker::Invoke() function
896- /// must be called to execute the delegate.
897- /// @param[in] msg - a pointer to the delegate message that must be created dynamically.
898- /// @pre Caller *must* create the DelegateMsg argument dynamically.
899- /// @post The destination thread calls Invoke().
900- virtual void DispatchDelegate(std::shared_ptr<DelegateMsg> msg) = 0;
910+ /// Destructor
911+ virtual ~IThread() = default;
912+
913+ /// Dispatch a DelegateMsg onto this thread. The implementer is responsible
914+ /// for getting the DelegateMsg into an OS message queue. Once DelegateMsg
915+ /// is on the correct thread of control, the DelegateInvoker::Invoke() function
916+ /// must be called to execute the delegate.
917+ /// @param[in] msg - a pointer to the delegate message that must be created dynamically.
918+ /// @pre Caller *must* create the DelegateMsg argument dynamically.
919+ /// @post The destination thread calls Invoke().
920+ virtual void DispatchDelegate(std::shared_ptr<DelegateMsg> msg) = 0;
901921};
902922```
903923
@@ -919,16 +939,16 @@ if (thread) {
919939``` cpp
920940void Thread::DispatchDelegate (std::shared_ptr< DelegateMQ::DelegateMsg > msg)
921941{
922- if (m_thread == nullptr)
923- throw std::invalid_argument("Thread pointer is null");
942+ if (m_thread == nullptr)
943+ throw std::invalid_argument("Thread pointer is null");
924944
925- // Create a new ThreadMsg
945+ // Create a new ThreadMsg
926946 std::shared_ptr<ThreadMsg> threadMsg(new ThreadMsg(MSG_DISPATCH_DELEGATE, msg));
927947
928- // Add dispatch delegate msg to queue and notify worker thread
929- std::unique_lock<std::mutex> lk(m_mutex);
930- m_queue.push(threadMsg);
931- m_cv.notify_one();
948+ // Add dispatch delegate msg to queue and notify worker thread
949+ std::unique_lock<std::mutex> lk(m_mutex);
950+ m_queue.push(threadMsg);
951+ m_cv.notify_one();
932952}
933953```
934954
@@ -946,10 +966,10 @@ void Thread::DispatchDelegate(std::shared_ptr<DelegateMQ::DelegateMsg> msg)
946966class IDelegateInvoker
947967{
948968public:
949- /// Called to invoke the bound target function by the destination thread of control.
950- /// @param[in] msg - the incoming delegate message.
951- /// @return `true` if function was invoked; `false` if failed.
952- virtual bool Invoke(std::shared_ptr<DelegateMsg> msg) = 0;
969+ /// Called to invoke the bound target function by the destination thread of control.
970+ /// @param[in] msg - the incoming delegate message.
971+ /// @return `true` if function was invoked; `false` if failed.
972+ virtual bool Invoke(std::shared_ptr<DelegateMsg> msg) = 0;
953973};
954974```
955975
@@ -958,57 +978,57 @@ The `Thread::Process()` thread loop is shown below. `Invoke()` is called for eac
958978``` cpp
959979void Thread::Process ()
960980{
961- m_timerExit = false;
962- std::thread timerThread(&Thread::TimerThread, this);
963-
964- while (1)
965- {
966- std::shared_ptr<ThreadMsg> msg;
967- {
968- // Wait for a message to be added to the queue
969- std::unique_lock<std::mutex> lk(m_mutex);
970- while (m_queue.empty())
971- m_cv.wait(lk);
972-
973- if (m_queue.empty())
974- continue;
975-
976- msg = m_queue.front();
977- m_queue.pop();
978- }
979-
980- switch (msg->GetId())
981- {
982- case MSG_DISPATCH_DELEGATE:
983- {
984- // Get pointer to DelegateMsg data from queue msg data
985- auto delegateMsg = msg->GetData();
986- ASSERT_TRUE (delegateMsg);
987-
988- auto invoker = delegateMsg->GetDelegateInvoker();
989- ASSERT_TRUE (invoker);
990-
991- // Invoke the delegate destination target function
992- bool success = invoker->Invoke(delegateMsg);
993- ASSERT_TRUE (success);
994- break;
995- }
996-
997- case MSG_TIMER:
998- Timer::ProcessTimers ();
999- break;
1000-
1001- case MSG_EXIT_THREAD:
1002- {
1003- m_timerExit = true;
1004- timerThread.join();
1005- return;
1006- }
1007-
1008- default:
1009- throw std::invalid_argument("Invalid message ID");
1010- }
1011- }
981+ m_timerExit = false;
982+ std::thread timerThread(&Thread::TimerThread, this);
983+
984+ while (1)
985+ {
986+ std::shared_ptr<ThreadMsg> msg;
987+ {
988+ // Wait for a message to be added to the queue
989+ std::unique_lock<std::mutex> lk(m_mutex);
990+ while (m_queue.empty())
991+ m_cv.wait(lk);
992+
993+ if (m_queue.empty())
994+ continue;
995+
996+ msg = m_queue.front();
997+ m_queue.pop();
998+ }
999+
1000+ switch (msg->GetId())
1001+ {
1002+ case MSG_DISPATCH_DELEGATE:
1003+ {
1004+ // Get pointer to DelegateMsg data from queue msg data
1005+ auto delegateMsg = msg->GetData();
1006+ ASSERT_TRUE (delegateMsg);
1007+
1008+ auto invoker = delegateMsg->GetDelegateInvoker();
1009+ ASSERT_TRUE (invoker);
1010+
1011+ // Invoke the delegate destination target function
1012+ bool success = invoker->Invoke(delegateMsg);
1013+ ASSERT_TRUE (success);
1014+ break;
1015+ }
1016+
1017+ case MSG_TIMER:
1018+ Timer::ProcessTimers ();
1019+ break;
1020+
1021+ case MSG_EXIT_THREAD:
1022+ {
1023+ m_timerExit = true;
1024+ timerThread.join();
1025+ return;
1026+ }
1027+
1028+ default:
1029+ throw std::invalid_argument("Invalid message ID");
1030+ }
1031+ }
10121032}
10131033```
10141034
0 commit comments