Plasma Engine  2.0
Loading...
Searching...
No Matches
Message.h
1#pragma once
2
3#include <Foundation/Algorithm/HashingUtils.h>
4#include <Foundation/Reflection/Reflection.h>
5#include <Foundation/Types/UniquePtr.h>
6
7using plMessageId = plUInt16;
10
21class PL_FOUNDATION_DLL plMessage : public plReflectedClass
22{
23 PL_ADD_DYNAMIC_REFLECTION(plMessage, plReflectedClass);
24
25protected:
26 explicit plMessage(size_t messageSize)
27 {
28 const auto sizeOffset = (reinterpret_cast<uintptr_t>(&m_Id) - reinterpret_cast<uintptr_t>(this)) + sizeof(m_Id);
29 memset((void*)plMemoryUtils::AddByteOffset(this, sizeOffset), 0, messageSize - sizeOffset);
30 m_uiSize = static_cast<plUInt16>(messageSize);
31#if PL_ENABLED(PL_COMPILE_FOR_DEBUG)
32 m_uiDebugMessageRouting = 0;
33#endif
34 }
35
36public:
37 PL_ALWAYS_INLINE plMessage()
38 : plMessage(sizeof(plMessage))
39 {
40 }
41
42 virtual ~plMessage() = default;
43
45 virtual plInt32 GetSortingKey() const { return 0; }
46
48 PL_ALWAYS_INLINE plMessageId GetId() const { return m_Id; }
49
51 PL_ALWAYS_INLINE plUInt16 GetSize() const { return m_uiSize; }
52
54 PL_ALWAYS_INLINE plUInt64 GetHash() const { return plHashingUtils::xxHash64(this, m_uiSize); }
55
63 virtual void Serialize(plStreamWriter& inout_stream) const { PL_ASSERT_NOT_IMPLEMENTED; }
64
66 virtual void Deserialize(plStreamReader& inout_stream, plUInt8 uiTypeVersion) { PL_ASSERT_NOT_IMPLEMENTED; }
67
68#if PL_ENABLED(PL_COMPILE_FOR_DEBUG)
71 PL_ALWAYS_INLINE void SetDebugMessageRouting(bool bDebug) { m_uiDebugMessageRouting = bDebug; }
72
73 PL_ALWAYS_INLINE bool GetDebugMessageRouting() const { return m_uiDebugMessageRouting; }
74#endif
75
76protected:
77 PL_ALWAYS_INLINE static plMessageId GetNextMsgId() { return s_NextMsgId++; }
78
79 plMessageId m_Id;
80
81#if PL_ENABLED(PL_COMPILE_FOR_DEBUG)
82 plUInt16 m_uiSize : 15;
83 plUInt16 m_uiDebugMessageRouting : 1;
84#else
85 plUInt16 m_uiSize;
86#endif
87
88 static plMessageId s_NextMsgId;
89
90
92 // Transferring and replicating messages
93 //
94
95public:
101 static void PackageForTransfer(const plMessage& msg, plStreamWriter& inout_stream);
102
107 static plUniquePtr<plMessage> ReplicatePackedMessage(plStreamReader& inout_stream);
108
109private:
110};
111
113#define PL_DECLARE_MESSAGE_TYPE(messageType, baseType) \
114private: \
115 PL_ADD_DYNAMIC_REFLECTION(messageType, baseType); \
116 static plMessageId MSG_ID; \
117 \
118protected: \
119 PL_ALWAYS_INLINE explicit messageType(size_t messageSize) \
120 : baseType(messageSize) \
121 { \
122 m_Id = messageType::MSG_ID; \
123 } \
124 \
125public: \
126 static plMessageId GetTypeMsgId() \
127 { \
128 static plMessageId id = plMessage::GetNextMsgId(); \
129 return id; \
130 } \
131 \
132 PL_ALWAYS_INLINE messageType() \
133 : messageType(sizeof(messageType)) \
134 { \
135 }
136
138#define PL_IMPLEMENT_MESSAGE_TYPE(messageType) plMessageId messageType::MSG_ID = messageType::GetTypeMsgId();
139
140
142template <typename T>
144{
145 using MessageType = T;
146};
static plUInt64 xxHash64(const void *pKey, size_t uiSizeInByte, plUInt64 uiSeed=0)
Calculates the 64bit xxHash of the given key.
Definition HashingUtils.cpp:215
static T * AddByteOffset(T *pPtr, std::ptrdiff_t offset)
Returns the address stored in ptr plus the given byte offset iOffset, cast to type T.
Base class for all message types. Each message type has it's own id which is used to dispatch message...
Definition Message.h:22
PL_ALWAYS_INLINE plMessageId GetId() const
Returns the id for this message type.
Definition Message.h:48
virtual void Deserialize(plStreamReader &inout_stream, plUInt8 uiTypeVersion)
Definition Message.h:66
PL_ALWAYS_INLINE plUInt64 GetHash() const
Calculates a hash of the message.
Definition Message.h:54
PL_ALWAYS_INLINE plUInt16 GetSize() const
Returns the size in byte of this message.
Definition Message.h:51
virtual plInt32 GetSortingKey() const
Derived message types can override this method to influence sorting order. Smaller keys are processed...
Definition Message.h:45
virtual void Serialize(plStreamWriter &inout_stream) const
Implement this for efficient transmission across process boundaries (e.g. network transfer etc....
Definition Message.h:63
All classes that should be dynamically reflectable, need to be derived from this base class.
Definition DynamicRTTI.h:86
Interface for binary in (read) streams.
Definition Stream.h:22
Interface for binary out (write) streams.
Definition Stream.h:107
A Unique ptr manages an object and destroys that object when it goes out of scope....
Definition UniquePtr.h:10
Base class for all message senders.
Definition Message.h:144