Skip to content
This repository has been archived by the owner on Dec 11, 2023. It is now read-only.

Commit

Permalink
feat: add new deps polym
Browse files Browse the repository at this point in the history
  • Loading branch information
Nambers committed Nov 2, 2023
1 parent 818670e commit 2e64197
Show file tree
Hide file tree
Showing 2 changed files with 185 additions and 0 deletions.
108 changes: 108 additions & 0 deletions single_include/3rd_include/polym/Msg.hpp
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_;
};

}
77 changes: 77 additions & 0 deletions single_include/3rd_include/polym/Queue.hpp
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_;
};

}

0 comments on commit 2e64197

Please sign in to comment.