gwnavruntime/visualdebug/amp/Amp_MessageRegistry.h Source File

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