generated from cpp-best-practices/cmake_template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Give monitors an optional parameter that can be used as a handle wh…
…en making extensions - Update the pub/sub monitor to use this functionality.
- Loading branch information
Showing
22 changed files
with
350 additions
and
221 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 |
---|---|---|
@@ -1,21 +1,31 @@ | ||
#pragma once | ||
#include "PubSub/IMessage.hpp" | ||
namespace PubSubMonitoring { | ||
struct FloatMessage : public IMessage { | ||
explicit FloatMessage(float f = 0.0f, std::string name = "FloatMessage") : mData{f}, mName(std::move(name)) {} | ||
const void *GetData() const override { return &mData; } | ||
void *GetData() override { return &mData; } | ||
int GetSize() const override { return sizeof(mData); } | ||
const std::string& GetName() const override { return mName; } | ||
struct FloatMessage : public IMessage | ||
{ | ||
explicit FloatMessage(std::string name = "FloatMessage") : mName(std::move(name)) {} | ||
FloatMessage(float f = 0.0f, std::string name = "FloatMessage") : mData{ f }, mName(std::move(name)) {} | ||
const void *GetData() const override { return &mData; } | ||
void *GetData() override { return &mData; } | ||
int GetSize() const override { return sizeof(mData); } | ||
const std::string &GetName() const override { return mName; } | ||
|
||
float GetF() const { return mData.f; } | ||
void SetF(float f) { mData.f = f; } | ||
float GetF() const { return mData.f; } | ||
void SetF(float f) { mData.f = f; } | ||
|
||
private: | ||
struct Data { | ||
float f = 0.0f; | ||
} mData; | ||
bool operator>=(const FloatMessage &other) const { return mData.f >= other.mData.f; } | ||
bool operator<=(const FloatMessage &other) const { return mData.f <= other.mData.f; } | ||
bool operator>(const FloatMessage &other) const { return mData.f > other.mData.f; } | ||
bool operator<(const FloatMessage &other) const { return mData.f < other.mData.f; } | ||
bool operator==(const FloatMessage &other) const { return mData.f == other.mData.f; } | ||
bool operator!=(const FloatMessage &other) const { return mData.f != other.mData.f; } | ||
|
||
const std::string mName = "FloatMessage"; | ||
}; | ||
} | ||
private: | ||
struct Data | ||
{ | ||
float f = 0.0f; | ||
} mData; | ||
|
||
const std::string mName = "FloatMessage"; | ||
}; | ||
}// namespace PubSubMonitoring |
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
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 |
---|---|---|
@@ -1,91 +1,105 @@ | ||
#pragma once | ||
|
||
#include "PubSub/IPubSub.hpp" | ||
#include "PubSub/IMessage.hpp" | ||
#include "PubSub/IPubSub.hpp" | ||
#include <functional> | ||
#include <monitoring/monitor.hpp> | ||
#include <tuple> | ||
|
||
namespace PubSubMonitoring { | ||
namespace intern | ||
namespace intern { | ||
template<typename TupleT, typename Fn> void for_each_tuple(Fn &&fn, TupleT &&tp) | ||
{ | ||
template <typename TupleT, typename Fn> | ||
void for_each_tuple(Fn&& fn, TupleT&& tp) { | ||
std::apply | ||
( | ||
[&fn](auto&& ...args) | ||
{ | ||
(fn(std::forward<decltype(args)>(args)), ...); | ||
}, std::forward<TupleT>(tp) | ||
); | ||
} | ||
std::apply([&fn](auto &&...args) { (fn(std::forward<decltype(args)>(args)), ...); }, std::forward<TupleT>(tp)); | ||
} | ||
}// namespace intern | ||
|
||
template<typename MessagesTpl, typename MonitorT> | ||
struct PubSubMonitor | ||
{ | ||
PubSubMonitor(IPubSub &pubsub, MessagesTpl messages, MonitorT monitor) : mPubSub(pubsub), mMessages(std::move(messages)), mMonitor(std::move(monitor)) | ||
{ | ||
intern::for_each_tuple([&](auto &arg) { mPubSub.Subscribe(arg, [&] { Check(); }); }, mMessages); | ||
} | ||
|
||
~PubSubMonitor() | ||
{ | ||
intern::for_each_tuple([&](auto& arg) { mPubSub.Unsubscribe(arg); }, mMessages); | ||
} | ||
|
||
private: | ||
void Check() | ||
{ | ||
std::apply([&](auto&&... args) { mMonitor(std::forward<decltype(args)>(args)...); }, mMessages); | ||
} | ||
|
||
IPubSub& mPubSub; | ||
MessagesTpl mMessages; | ||
MonitorT mMonitor; | ||
}; | ||
|
||
template<typename MessagesT, typename MonitorT> | ||
struct MonitorRequirementsHandlers | ||
struct SubscribeAndCheckFunc | ||
{ | ||
SubscribeAndCheckFunc(IPubSub &pubsub) : mPubSub(pubsub) {} | ||
|
||
void SetCheckFunc(std::function<void(void)> checkFunc) { mCheckFunc = std::move(checkFunc); } | ||
|
||
template<typename Message> void operator()(Message &&message) | ||
{ | ||
MonitorRequirementsHandlers(MessagesT messages, MonitorT monitor) : mMessages(std::move(messages)), mMonitor(std::move(monitor)) {} | ||
mPubSub.Subscribe(message, [&] { mCheckFunc(); }); | ||
} | ||
|
||
[[nodiscard]] auto With(IPubSub& pubsub) | ||
{ | ||
return PubSubMonitor(pubsub, mMessages, mMonitor); | ||
} | ||
private: | ||
IPubSub &mPubSub; | ||
std::function<void(void)> mCheckFunc; | ||
}; | ||
|
||
private: | ||
MessagesT mMessages; | ||
MonitorT mMonitor; | ||
}; | ||
template<typename MessagesT, typename MonitorT> struct PubSubMonitor | ||
{ | ||
PubSubMonitor(IPubSub &pubsub, MessagesT messages, MonitorT monitor) | ||
: mPubSub(pubsub), mMessages(std::move(messages)), mMonitor(std::move(monitor)) | ||
{ | ||
mMonitor.GetOpt().SetCheckFunc([&] { Check(); }); | ||
intern::for_each_tuple([&](auto &arg) { mPubSub.Subscribe(arg, [&] { Check(); }); }, mMessages); | ||
Check(); | ||
} | ||
|
||
~PubSubMonitor() | ||
{ | ||
intern::for_each_tuple([&](auto &arg) { mPubSub.Unsubscribe(arg); }, mMessages); | ||
} | ||
|
||
template<typename MessagesT, typename ConditionsT> | ||
struct MonitorRequirements | ||
private: | ||
void Check() | ||
{ | ||
MonitorRequirements(MessagesT messages, ConditionsT conditions) : mMessages(std::move(messages)), mConditions(std::move(conditions)) {} | ||
std::apply([&](auto &&...args) { mMonitor(std::forward<decltype(args)>(args)...); }, mMessages); | ||
} | ||
|
||
IPubSub &mPubSub; | ||
MessagesT mMessages; | ||
MonitorT mMonitor; | ||
}; | ||
|
||
template<typename... HandlersT> | ||
[[nodiscard]] auto Handler(HandlersT&&... handlers) | ||
{ | ||
return MonitorRequirementsHandlers(mMessages, Monitoring::Monitor(mConditions, std::forward<HandlersT>(handlers)...)); | ||
} | ||
template<typename MessagesT, typename RequirementsT> struct MonitorWithRequirements | ||
{ | ||
MonitorWithRequirements(MessagesT messages, IPubSub &pubsub, RequirementsT requirements) | ||
: mMessages(std::move(messages)), mPubSub(pubsub), mRequirements(std::move(requirements)) | ||
{} | ||
|
||
template<typename... HandlersT> [[nodiscard]] auto Handler(HandlersT &&...handlers) | ||
{ | ||
auto mergedHandlers = [handlers = std::forward_as_tuple(handlers...)](bool result) { | ||
std::apply([result](auto &&...handlers) { (..., handlers(result)); }, handlers); | ||
Check warning on line 68 in examples/pubsub/PubSubMonitor.hpp GitHub Actions / Analyze (cpp, gcc-11, Ninja Multi-Config, Debug, ON)
|
||
}; | ||
auto subscribeAndCheckFunc = SubscribeAndCheckFunc(mPubSub); | ||
return PubSubMonitor(mPubSub, mMessages, Monitoring::Monitor(mRequirements, mergedHandlers, subscribeAndCheckFunc)); | ||
} | ||
|
||
private: | ||
MessagesT mMessages; | ||
ConditionsT mConditions; | ||
}; | ||
private: | ||
MessagesT mMessages; | ||
IPubSub &mPubSub; | ||
RequirementsT mRequirements; | ||
}; | ||
|
||
template<typename MessagesT> struct MonitorWith | ||
{ | ||
MonitorWith(MessagesT messages, IPubSub &pubsub) : mMessages(std::move(messages)), mPubSub(pubsub) {} | ||
|
||
template<typename... MessageT> | ||
struct Monitor | ||
template<typename RequirementsT> [[nodiscard]] auto Require(RequirementsT &&requirements) | ||
{ | ||
Monitor(MessageT... messages) : mMessages(messages...) {} | ||
return MonitorWithRequirements(mMessages, mPubSub, std::forward<RequirementsT>(requirements)); | ||
} | ||
|
||
private: | ||
MessagesT mMessages; | ||
IPubSub &mPubSub; | ||
}; | ||
|
||
|
||
template<typename... MessageT> struct Monitor | ||
{ | ||
Monitor(MessageT... messages) : mMessages(messages...) {} | ||
|
||
template<typename ConditionsT> | ||
[[nodiscard]] auto Require(ConditionsT conditions) { return MonitorRequirements(mMessages, conditions); } | ||
[[nodiscard]] auto With(IPubSub &pubsub) { return MonitorWith(mMessages, pubsub); } | ||
|
||
private: | ||
std::tuple<MessageT...> mMessages; | ||
}; | ||
private: | ||
std::tuple<MessageT...> mMessages; | ||
}; | ||
|
||
}// namespace PubSubMonitoring |
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
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,41 @@ | ||
#pragma once | ||
|
||
#include "FloatMessage.hpp" | ||
#include "IntMessage.hpp" | ||
#include <monitoring/conditions/minmax.hpp> | ||
|
||
namespace Monitoring { | ||
template<typename T, typename GetterT, typename CompT> auto ParamComparison(GetterT getter, T otherVal, CompT comp) | ||
{ | ||
auto lamb = [otherVal = std::move(otherVal), getter = std::move(getter), comp = std::move(comp), subscribed = false]( | ||
auto &subscriber, const auto &val) mutable { | ||
if (!subscribed) { | ||
subscriber(otherVal); | ||
subscribed = true; | ||
} | ||
return comp(otherVal, getter(val)); | ||
}; | ||
return lamb; | ||
} | ||
|
||
template<typename Getter> auto Max(Getter getter, PubSubMonitoring::FloatMessage max) | ||
{ | ||
return ParamComparison(std::move(getter), std::move(max), std::greater_equal<PubSubMonitoring::FloatMessage>()); | ||
} | ||
|
||
template<> auto Max(PubSubMonitoring::FloatMessage max) | ||
{ | ||
return Max(Intern::Identity<PubSubMonitoring::FloatMessage>(), std::move(max)); | ||
} | ||
|
||
template<typename Getter> auto Min(Getter getter, PubSubMonitoring::FloatMessage min) | ||
{ | ||
return ParamComparison(std::move(getter), std::move(min), std::less_equal<PubSubMonitoring::FloatMessage>()); | ||
} | ||
|
||
template<> auto Min(PubSubMonitoring::FloatMessage min) | ||
{ | ||
return Min(Intern::Identity<PubSubMonitoring::FloatMessage>(), std::move(min)); | ||
} | ||
|
||
}// namespace Monitoring |
Oops, something went wrong.