gwnavruntime/visualdebug/amp/Amp_MessageRegistry.h Source File

Amp_MessageRegistry.h
Go to the documentation of this file.
1 /*
2 * Copyright 2016 Autodesk, Inc. All rights reserved.
3 * Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
4 * or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
5 */
6 
7 #pragma once
8 
15 
16 namespace Kaim
17 {
18 namespace Net
19 {
20 namespace AMP
21 {
22 
23 class ThreadMgr;
24 
25 // Only a base class, it is used directly by the registry.
26 class BaseMessageTypeDescriptor : public NewOverrideBase<Stat_Default_Mem>
27 {
28 public:
29  virtual ~BaseMessageTypeDescriptor() { }
30 
31  const String& GetMessageTypeName() const { return MessageTypeName; }
32  UInt32 GetMessageLatestVersion() const { return MessageLatestVersion; }
33  UInt32 GetMessageType() const { return MessageType; }
34  UInt32 GetPeerMessageType() const { return PeerMessageType; }
35  bool CanHandle(IMessageHandler::Mode handlerMode) const { return MessageHandler!=NULL && MessageHandler->HandleMode() == handlerMode; }
36  void Handle(Message* msg) const { MessageHandler->Handle(msg); }
37 
38  virtual BaseMessageTypeDescriptor* Clone() const = 0;
39  virtual Message* CreateMessage(MemoryHeap* heap) const = 0;
40 
41 protected:
42  BaseMessageTypeDescriptor(const char* messageTypeName, UInt32 messageLatestVersion, UInt32 messageType, Ptr<IMessageHandler> messageHandler)
43  : MessageHandler(messageHandler)
44  , MessageTypeName(messageTypeName)
45  , MessageLatestVersion(messageLatestVersion)
46  , MessageType(messageType)
47  , PeerMessageType(messageType)
48  {
49  }
50 
51  friend class MessageTypeRegistry;
52 
53  Ptr<IMessageHandler> MessageHandler;
54  String MessageTypeName;
55  UInt32 MessageLatestVersion;
56  UInt32 MessageType;
57  UInt32 PeerMessageType;
58 };
59 
60 // MessageTypeDescriptor is used directly by the registry.
61 // TMessage is expected to inherit from Message class
62 template <class TMessage>
63 class MessageTypeDescriptor : public BaseMessageTypeDescriptor
64 {
65 private:
66  friend class MessageTypeRegistry;
67 
68  MessageTypeDescriptor(const char* messageTypeName, UInt32 messageLatestVersion, UInt32 messageType, Ptr<IMessageHandler> messageHandler)
69  :BaseMessageTypeDescriptor(messageTypeName, messageLatestVersion, messageType, messageHandler)
70  {
71  }
72 
73  virtual MessageTypeDescriptor<TMessage>* Clone() const { return KY_NEW(MessageTypeDescriptor<TMessage>)(MessageTypeName, MessageLatestVersion, MessageType, MessageHandler); }
74  virtual TMessage* CreateMessage(MemoryHeap* heap) const
75  {
76  TMessage* msg = KY_HEAP_NEW(heap) TMessage();
77  msg->SetMessageType(MessageType);
78  return msg;
79  }
80 };
81 
82 // This is class is used to register different kind of messages and is in charge to assign them an id/index
83 // It can also be used to translate/convert message type
84 class MessageTypeRegistry
85 {
86 public:
87 
88  void Clear();
89 
90  MessageTypeRegistry();
91 
92  ~MessageTypeRegistry()
93  {
94  for (UInt32 i = 0; i < Descriptors.GetSize(); ++i)
95  delete Descriptors[i];
96  Descriptors.Clear();
97  }
98 
99 
100  // If handler is NULL it means that the message is not treated
101  // TMessage is expected to inherit from Message class
102  template<class TMessage>
103  void AddMessageType(Ptr<IMessageHandler> handler)
104  {
105  // Call GetMessageTypeDescriptor_Unique in order to prevent conflicting hashId
106  BaseMessageTypeDescriptor* myDescriptor = GetMessageTypeDescriptor_Unique(TMessage::GetTypeName());
107  if (myDescriptor == NULL)
108  {
109  UInt32 localMsgType = static_cast<Kaim::UInt32>(Descriptors.GetSize());
110  MessageTypeDescriptor<TMessage>* descriptor = KY_NEW MessageTypeDescriptor<TMessage>(TMessage::GetTypeName(), TMessage::GetLatestVersion() , localMsgType, handler);
111  StringToMsgType.SetCaseInsensitive(TMessage::GetTypeName(), localMsgType);
112  Descriptors.PushBack(descriptor);
113  }
114  else
115  {
116  if (myDescriptor->GetMessageTypeName() != TMessage::GetTypeName())
117  {
118  KY_DEBUG_ERRORN(("MessageType '%s-%u' ignored, it conflicts with descriptor %u, %s-%u",
119  TMessage::GetTypeName(), TMessage::GetLatestVersion(),
120  static_cast<unsigned int>(myDescriptor->GetMessageType()),
121  myDescriptor->GetMessageTypeName().ToCStr(), static_cast<unsigned int>(myDescriptor->GetMessageLatestVersion())));
122  return;
123  }
124 
125  KY_DEBUG_WARNINGN_IF(myDescriptor->MessageHandler != NULL, ("Handler of descriptor %u, %s-%u is overridden",
126  static_cast<unsigned int>(myDescriptor->GetMessageType()),
127  myDescriptor->GetMessageTypeName().ToCStr(), static_cast<unsigned int>(myDescriptor->GetMessageLatestVersion())));
128  myDescriptor->MessageHandler = handler;
129  }
130  }
131 
132  void AddMessageTypeRegistry(const MessageTypeRegistry& other);
133 
134  BaseMessageTypeDescriptor* GetMessageTypeDescriptor(const String& messageTypeName) const
135  {
136  BaseMessageTypeDescriptor* descriptor = GetMessageTypeDescriptor_Unique(messageTypeName);
137  if (descriptor->GetMessageTypeName() == messageTypeName)
138  return descriptor;
139  return NULL;
140  }
141 
142  // TMessage is expected to inherit from Message class
143  template<class TMessage>
144  UInt32 GetMessageType() const
145  {
146  return GetMessageType(TMessage::GetTypeName());
147  }
148 
149  UInt32 GetMessageType(const String& messageTypeName) const
150  {
151  const BaseMessageTypeDescriptor* descriptor = GetMessageTypeDescriptor(messageTypeName);
152  return (descriptor ? descriptor->GetMessageType() : Message::InvalidMsgType);
153  }
154 
155  UInt32 GetMessageTypeCount() const
156  {
157  return (UInt32)Descriptors.GetSize();
158  }
159 
160  BaseMessageTypeDescriptor* GetMessageTypeDescriptor(UInt32 localMsgType) const
161  {
162  if (localMsgType < Descriptors.GetSize())
163  return Descriptors[localMsgType];
164 
165  return NULL;
166  }
167 
168  UInt32 GetLocalMessageType(UInt32 peerMsgType) const
169  {
170  if (MappingEnabled)
171  {
172  if (peerMsgType < MsgTypeConverter.GetSize())
173  {
174  return MsgTypeConverter[peerMsgType];
175  }
176  return Message::InvalidMsgType; //in that case there is a problem, the type are not properly mapped
177  }
178 
179  return peerMsgType; // use the same
180  }
181 
182  UInt32 GetPeerMessageType(UInt32 localMsgType) const
183  {
184  if (MappingEnabled)
185  {
186  if (localMsgType < Descriptors.GetSize())
187  {
188  return Descriptors[localMsgType]->GetPeerMessageType();
189  }
190 
191  return Message::InvalidMsgType;
192  }
193 
194  return localMsgType;
195  }
196 
197  struct RegistryEntry
198  {
199  String MsgTypeName;
200  UInt32 Version;
201  };
202  void MapMsgTypes(RegistryEntry* peerRegistryData, UInt32 dataSize);
203  void DisableMapping() { MappingEnabled = false; }
204  bool IsMappingEnabled() const { return MappingEnabled!=0; }
205 
206  // TMessage is expected to inherit from Message class
207  template<class TMessage>
208  TMessage* CreateMessage( void* memoryHeap, bool doMapType) const
209  {
210  return static_cast<TMessage*>(CreateMessage(memoryHeap, doMapType, TMessage::GetTypeName()));
211  }
212 
213  Message* CreateMessage( void* memoryHeap, bool doMapType, const String& messageTypeName) const;
214 
215  Message* CreateMessageRegistry(void* memoryHeap, bool doMapType) const;
216 
217 private:
218  // Doesn't check the real name
219  BaseMessageTypeDescriptor* GetMessageTypeDescriptor_Unique(const String& messageTypeName) const
220  {
221  const UInt32* pMsgType = StringToMsgType.GetCaseInsensitive(messageTypeName);
222  return (pMsgType && (*pMsgType < Descriptors.GetSize()) ? Descriptors[*pMsgType] : NULL);
223  }
224 
225 protected:
226  // entry count must be the same between Descriptors and StringToMsgType
227  Array<BaseMessageTypeDescriptor*> Descriptors;
228  StringHash<UInt32> StringToMsgType; //associate a MsgTypeName to an entry in Descriptors
229 
230  Array<UInt32> MsgTypeConverter; //associate peerMsgType to an entry in Descriptors (aka localMsgType)
231  UInt32 MappingEnabled;
232 };
233 
234 
235 }
236 }
237 }
238 
std::uint32_t UInt32
uint32_t
Definition: SF_Types.h:137
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17