use generic handler
All checks were successful
Linux arm64 / Build (push) Successful in 15s

This commit is contained in:
2025-07-18 16:45:27 +02:00
parent 2149172b41
commit 143b2f357c
3 changed files with 28 additions and 145 deletions

View File

@@ -33,6 +33,22 @@ class ConcreteMessage : public MessageBase {
return details::WriteMessage(m_Data); return details::WriteMessage(m_Data);
} }
DataType* operator*() {
return &m_Data;
}
DataType* operator->() {
return &m_Data;
}
const DataType* operator*() const {
return &m_Data;
}
const DataType* operator->() const {
return &m_Data;
}
private: private:
DataType m_Data; DataType m_Data;
}; };

View File

@@ -1,133 +0,0 @@
#pragma once
#include <tuple>
namespace sp
{
// This class is inspired by https://arobenko.gitbooks.io/comms-protocols-cpp/content/
// TAll is all the message types, that need to be handled, bundled in std::tuple
template <typename TAll>
class MessageHandler;
// Big boy to process packets 20 by 20, preventing needlessly copying vtable many times at each inheritance stage
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename... TRest>
class MessageHandler<std::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T11, T13, T14, T15, T16, T17, T18, T19, T20, TRest...> > : public MessageHandler<std::tuple<TRest...> >
{
using Base = MessageHandler<std::tuple<TRest...> >;
public:
using Base::Handle; // Don't hide all Handle() functions from base classes
virtual void Handle(const typename T1::DataType& msg) {}
virtual void Handle(const typename T2::DataType& msg) {}
virtual void Handle(const typename T3::DataType& msg) {}
virtual void Handle(const typename T4::DataType& msg) {}
virtual void Handle(const typename T5::DataType& msg) {}
virtual void Handle(const typename T6::DataType& msg) {}
virtual void Handle(const typename T7::DataType& msg) {}
virtual void Handle(const typename T8::DataType& msg) {}
virtual void Handle(const typename T9::DataType& msg) {}
virtual void Handle(const typename T10::DataType& msg) {}
virtual void Handle(const typename T11::DataType& msg) {}
virtual void Handle(const typename T12::DataType& msg) {}
virtual void Handle(const typename T13::DataType& msg) {}
virtual void Handle(const typename T14::DataType& msg) {}
virtual void Handle(const typename T15::DataType& msg) {}
virtual void Handle(const typename T16::DataType& msg) {}
virtual void Handle(const typename T17::DataType& msg) {}
virtual void Handle(const typename T18::DataType& msg) {}
virtual void Handle(const typename T19::DataType& msg) {}
virtual void Handle(const typename T20::DataType& msg) {}
};
// 10 by 10
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename... TRest>
class MessageHandler<std::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TRest...> > : public MessageHandler<std::tuple<TRest...> >
{
using Base = MessageHandler<std::tuple<TRest...> >;
public:
using Base::Handle; // Don't hide all Handle() functions from base classes
virtual void Handle(const typename T1::DataType& msg) {}
virtual void Handle(const typename T2::DataType& msg) {}
virtual void Handle(const typename T3::DataType& msg) {}
virtual void Handle(const typename T4::DataType& msg) {}
virtual void Handle(const typename T5::DataType& msg) {}
virtual void Handle(const typename T6::DataType& msg) {}
virtual void Handle(const typename T7::DataType& msg) {}
virtual void Handle(const typename T8::DataType& msg) {}
virtual void Handle(const typename T9::DataType& msg) {}
virtual void Handle(const typename T10::DataType& msg) {}
};
// 5 by 5
template <
typename T1, typename T2, typename T3, typename T4, typename T5,
typename... TRest>
class MessageHandler<std::tuple<T1, T2, T3, T4, T5, TRest...> > : public MessageHandler<std::tuple<TRest...> >
{
using Base = MessageHandler<std::tuple<TRest...> >;
public:
using Base::Handle; // Don't hide all Handle() functions from base classes
virtual void Handle(const typename T1::DataType& msg) {}
virtual void Handle(const typename T2::DataType& msg) {}
virtual void Handle(const typename T3::DataType& msg) {}
virtual void Handle(const typename T4::DataType& msg) {}
virtual void Handle(const typename T5::DataType& msg) {}
};
// Deal with rest with 4 types
template <typename T1, typename T2, typename T3, typename T4>
class MessageHandler<std::tuple<T1, T2, T3, T4> >
{
public:
virtual ~MessageHandler() {}
virtual void Handle(const typename T1::DataType& msg) {}
virtual void Handle(const typename T2::DataType& msg) {}
virtual void Handle(const typename T3::DataType& msg) {}
virtual void Handle(const typename T4::DataType& msg) {}
};
// Deal with rest with 3 types
template < typename T1, typename T2, typename T3>
class MessageHandler<std::tuple<T1, T2, T3> >
{
public:
virtual ~MessageHandler() {}
virtual void Handle(const typename T1::DataType& msg) {}
virtual void Handle(const typename T2::DataType& msg) {}
virtual void Handle(const typename T3::DataType& msg) {}
};
// Deal with rest with 2 types
template <typename T1, typename T2>
class MessageHandler<std::tuple<T1, T2> >
{
public:
virtual ~MessageHandler() {}
virtual void Handle(const typename T1::DataType& msg) {}
virtual void Handle(const typename T2::DataType& msg) {}
};
// Deal with rest with 1 type
template <typename T1>
class MessageHandler<std::tuple<T1> >
{
public:
virtual ~MessageHandler() {}
virtual void Handle(const typename T1::DataType& msg) {}
};
// Deal with rest with 0 type
template <>
class MessageHandler<std::tuple<> >
{
public:
virtual ~MessageHandler() {}
};
} // sp

View File

@@ -1,16 +1,16 @@
#include <sp/protocol/ConcreteMessage.h> #include <sp/common/GenericHandler.h>
#include <sp/protocol/MessageDispatcher.h>
#include <sp/protocol/MessageFactory.h>
#include <sp/protocol/MessageHandler.h>
#include <sp/io/MessageStream.h> #include <sp/io/MessageStream.h>
#include <sp/io/StdIo.h> #include <sp/io/StdIo.h>
#include <sp/protocol/BitField.h> #include <sp/protocol/BitField.h>
#include <sp/protocol/ConcreteMessage.h>
#include <sp/protocol/MessageDispatcher.h>
#include <sp/protocol/MessageFactory.h>
#include <sp/extensions/Compress.h> #include <sp/extensions/Compress.h>
#include <cstdint> #include <cstdint>
#include <iostream>
#include <fstream> #include <fstream>
#include <iostream>
enum class PacketID { KeepAlive = 0 }; enum class PacketID { KeepAlive = 0 };
@@ -30,12 +30,12 @@ using KeepAliveMessage = Message<KeepAlivePacket, PacketID::KeepAlive>;
using AllMessages = std::tuple<KeepAliveMessage>; using AllMessages = std::tuple<KeepAliveMessage>;
class PacketHandler : public sp::MessageHandler<AllMessages> {}; class PacketHandler : public sp::GenericHandler<AllMessages> {};
class MyHandler : public PacketHandler { class MyHandler : public PacketHandler {
public: public:
virtual void Handle(const KeepAlivePacket& msg) { virtual void Handle(const KeepAliveMessage& msg) override {
std::cout << "I recieved a keep alive : " << *msg.one << " : " << *msg.two << "\n"; std::cout << "I recieved a keep alive : " << *msg->one << " : " << *msg->two << "\n";
} }
}; };
@@ -64,17 +64,17 @@ int main() {
auto compress = std::make_shared<sp::ZlibCompress>(); auto compress = std::make_shared<sp::ZlibCompress>();
std::ofstream file {"test.bin"}; std::ofstream file{"test.bin"};
PacketStream p(std::make_shared<sp::StdOuput>(file), compress); PacketStream p(std::make_shared<sp::StdOuput>(file));
p.WriteMessage(m); p.WriteMessage(m);
file.flush(); file.flush();
std::ifstream file2 {"test.bin"}; std::ifstream file2{"test.bin"};
PacketStream p2(std::make_shared<sp::StdInput>(file2), compress); PacketStream p2(std::make_shared<sp::StdInput>(file2));
auto message2 = p2.ReadMessage(); auto message2 = p2.ReadMessage();