This repository has been archived by the owner on Dec 11, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
#pragma once | ||
#include <memory> | ||
#include <utility> | ||
|
||
namespace PolyM { | ||
|
||
/** Type for Msg unique identifiers */ | ||
using MsgUID = unsigned long long; | ||
|
||
/** | ||
* Msg represents a simple message that doesn't have any payload data. | ||
* Msg ID identifies the type of the message. Msg ID can be queried with getMsgId(). | ||
*/ | ||
class Msg | ||
{ | ||
public: | ||
/** | ||
* Construct a Msg. | ||
* | ||
* @param msgId Msg ID of this Msg. | ||
*/ | ||
Msg(int msgId); | ||
|
||
virtual ~Msg() = default; | ||
Msg(const Msg&) = delete; | ||
Msg& operator=(const Msg&) = delete; | ||
|
||
/** "Virtual move constructor" */ | ||
virtual std::unique_ptr<Msg> move(); | ||
|
||
/** | ||
* Get Msg ID. | ||
* Msg ID identifies message type. | ||
* Multiple Msg instances can have the same Msg ID. | ||
*/ | ||
int getMsgId() const; | ||
|
||
/** | ||
* Get Msg UID. | ||
* Msg UID is the unique ID associated with this message. | ||
* All Msg instances have a unique Msg UID. | ||
*/ | ||
MsgUID getUniqueId() const; | ||
|
||
/** Get the raw payload data */ | ||
[[nodiscard]] virtual void* getRawPayLoad() const { | ||
return nullptr; | ||
} | ||
|
||
protected: | ||
Msg(Msg&&) = default; | ||
Msg& operator=(Msg&&) = default; | ||
|
||
private: | ||
int msgId_; | ||
MsgUID uniqueId_; | ||
}; | ||
|
||
/** | ||
* DataMsg<PayloadType> is a Msg with payload of type PayloadType. | ||
* Payload is constructed when DataMsg is created and the DataMsg instance owns the payload data. | ||
*/ | ||
template <typename PayloadType> | ||
class DataMsg : public Msg | ||
{ | ||
public: | ||
/** | ||
* Construct DataMsg | ||
* @param msgId Msg ID | ||
* @param args Arguments for PayloadType ctor | ||
*/ | ||
template <typename ... Args> | ||
DataMsg(int msgId, Args&& ... args) | ||
: Msg(msgId), | ||
pl_(new PayloadType(std::forward<Args>(args) ...)) | ||
{ | ||
} | ||
|
||
virtual ~DataMsg() = default; | ||
DataMsg(const DataMsg&) = delete; | ||
DataMsg& operator=(const DataMsg&) = delete; | ||
|
||
/** "Virtual move constructor" */ | ||
virtual std::unique_ptr<Msg> move() override | ||
{ | ||
return std::unique_ptr<Msg>(new DataMsg<PayloadType>(std::move(*this))); | ||
} | ||
|
||
/** Get the payload data */ | ||
PayloadType& getPayload() const | ||
{ | ||
return *pl_; | ||
} | ||
|
||
/** Get the raw payload data */ | ||
[[nodiscard]] void* getRawPayLoad() const override { | ||
return reinterpret_cast<void*>(pl_.get()); | ||
} | ||
|
||
protected: | ||
DataMsg(DataMsg&&) = default; | ||
DataMsg& operator=(DataMsg&&) = default; | ||
|
||
private: | ||
std::unique_ptr<PayloadType> pl_; | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
#pragma once | ||
#include "Msg.hpp" | ||
#include <memory> | ||
|
||
namespace PolyM { | ||
|
||
/** | ||
* Queue is a thread-safe message queue. | ||
* It supports one-way messaging and request-response pattern. | ||
*/ | ||
class Queue | ||
{ | ||
public: | ||
Queue(); | ||
|
||
~Queue(); | ||
|
||
/** | ||
* Put Msg to the end of the queue. | ||
* | ||
* @param msg Msg to put to the queue. | ||
*/ | ||
void put(Msg&& msg); | ||
|
||
/** | ||
* Get message from the head of the queue. | ||
* Blocks until at least one message is available in the queue, or until timeout happens. | ||
* If get() returns due to timeout, returns a nullptr. | ||
* | ||
* @param timeoutMillis How many ms to wait for message until timeout happens. | ||
* 0 = wait indefinitely. | ||
*/ | ||
std::unique_ptr<Msg> get(int timeoutMillis = 0); | ||
|
||
/** | ||
* Get message from the head of the queue. | ||
* Returns an empty pointer if no message is available. | ||
*/ | ||
std::unique_ptr<Msg> tryGet(); | ||
|
||
/** | ||
* Make a request. | ||
* Call will block until response is given with respondTo(). | ||
* If request() returns due to timeout, returns a nullptr. | ||
* | ||
* @param msg Request message. Is put to the queue so it can be retrieved from it with get(). | ||
* @param timeoutMillis How many ms to wait for response until timeout happens. | ||
* 0 = wait indefinitely. | ||
*/ | ||
std::unique_ptr<Msg> request(Msg&& msg, int timeoutMillis = 0, void (*on_put_callback)() = nullptr); | ||
|
||
/** | ||
* Respond to a request previously made with request(). | ||
* If the requestID has been found, return true. | ||
* | ||
* @param reqUid Msg UID of the request message. | ||
* @param responseMsg Response message. The requester will receive it as the return value of | ||
* request(). | ||
*/ | ||
bool respondTo(MsgUID reqUid, Msg&& responseMsg); | ||
|
||
/** | ||
* Get the size of the queue | ||
*/ | ||
size_t size(); | ||
|
||
/** | ||
* Clear all messages in queue | ||
*/ | ||
void clear(); | ||
|
||
private: | ||
class Impl; | ||
std::unique_ptr<Impl> impl_; | ||
}; | ||
|
||
} |