gwnavruntime/visualdebug/visualdebugserver.h Source File

visualdebugserver.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 
8 // primary contact: BRGR - secondary contact: NOBODY
9 #ifndef GwNavRuntime_VisualDebugServer_H
10 #define GwNavRuntime_VisualDebugServer_H
11 
20 #include "../visualsystem/idisplaylistbuilder.h"
21 
22 
23 namespace Kaim
24 {
25 
26 class FileOpenerBase;
27 class File;
28 
29 class ServerStatusChangedCallback;
30 class MessageBlob;
31 class MessageAggregatedBlob;
32 class MessageBlobHandler;
33 class BlobFieldsStore;
34 
35 class Profiler;
36 class FloatStat;
37 class IQuery;
38 
39 class Vec3f;
40 
41 class VisualDebugAttributesManager;
42 
46 class VisualDebugServerConfig
47 {
49 public:
50  static KyUInt32 DefaultServerPort() { return 4888; }
51  static KyUInt32 DefaultBroadcastPort() { return 4887; }
52 
53 public:
55  enum Mode {
58  };
59 
61  enum WaitOnStart {
64  };
65 
70  };
71 
73  enum RunMode {
76  };
77 
78 public:
81  , m_serverPort(0)
82  , m_broadcastPort(0)
83  , m_waitOnStart(DoNotWaitOnStart)
91 #if defined(KY_OS_WIIU)
92  // On Wii U, by default VisualDebugServer is run in another thread with affinity set to OS_THREAD_ATTR_AFFINITY_CORE2
93  // https://www.warioworld.com/wiiu/downloads/getfile.asp?file=NetworkOptimizationOnTheWiiU.zip&size=298882
95 #else
97 #endif
98  {}
99 
110  void UseNavigationLab(KyUInt32 serverPort = DefaultServerPort(), KyUInt32 broadcastPort = DefaultBroadcastPort(), MessageReceiverRegistry* navigationLabCommandHandlers = KY_NULL)
111  {
112 
114  m_navigationLabCommandHandlers = navigationLabCommandHandlers;
115  m_serverPort = serverPort;
116  m_broadcastPort = broadcastPort;
119  }
120 
121  void UseLocalFile(const char* localFileName, FileOpenerBase* localFileOpener = KY_NULL)
122  {
125  m_serverPort = 0;
126  m_localFileName = localFileName;
127  m_localFileOpener = localFileOpener;
128  }
129 
130  void SetLocalFileSizeLimit(KyInt32 localFileMegaBytesLimit) { m_localFileMegaBytesLimit = localFileMegaBytesLimit; }
131 
132  void SetWaitOnStart(WaitOnStart waitOnStart) { m_waitOnStart = waitOnStart; }
133 
135  void SetMemoryConsumption(KyUInt32 expectedKiloBytesPerFrame, KyUInt32 maximumMegaBytesToUse)
136  {
137  m_expectedKiloBytesPerFrame = expectedKiloBytesPerFrame;
138  m_maximumMegaBytes = maximumMegaBytesToUse;
139  }
141  void SetDisconnectionMode(DisconnectionMode disconnectionMode) { m_disconnectionMode = disconnectionMode; }
142 
143  void SetRunMode(RunMode runMode) { m_runMode = runMode; }
144 
145  void SetServerName(const char* serverName) { m_serverName = String(serverName); }
146 
147 public: // internal
149  Mode m_mode;
150 
151  // ------------- Relevant attributes if #m_mode = Mode_UseNavigationLab. -----------
152 
155 
158 
159  WaitOnStart m_waitOnStart;
160 
164  MessageReceiverRegistry* m_navigationLabCommandHandlers;
165 
166  // ------------- Relevant attributes if #m_mode = Mode_UseLocalFile. -----------
167 
169  const char* m_localFileName;
170 
173 
176 
177  // ------------- Memory allocations of messages -----------
178 
183 
184  // ------------- Various attributes -----------
185 
188 
191 
193  String m_serverName;
194 };
195 
196 }
197 
198 // Define KY_DISABLE_VISUALDEBUGSERVER to disable VisualDebugServer
199 // In that case, it will be replaced by fully inlined classe, DisabledVisualDebugServer,
200 // thanks to the define at the end of this file.
201 // If VisualDebugServer is modified, please apply the changes into disabledvisualdebugserver.inl as well.
202 #if defined(KY_BUILD_SHIPPING) || !defined(KY_ENABLE_SOCKETS) || !defined(KY_ENABLE_THREADS)
203 # define KY_DISABLE_VISUALDEBUGSERVER
204 #endif
205 
206 #ifndef KY_DISABLE_VISUALDEBUGSERVER
207 
213 
214 
215 namespace Kaim
216 {
217 
224 class VisualDebugServer
225 {
226  KY_DEFINE_NEW_DELETE_OPERATORS(MemStat_VisualDebug)
227 
228 public:
229 
230  // --------------- Server Status ----------------
231 
234  void NewFrame();
235  void NewFrame(KyUInt32 gameFrameIndex) { NewFrame(); m_gameFrameIndex = gameFrameIndex; }
236 
238  bool IsStarted() const { return m_isStarted; }
239 
241  bool IsConnected() { return (m_isConnected == true && IsConnectionEstablished() == true); }
242 
243  // ------------------ Send Statistics ------------------
245 
246  void SendStats(const char* statName, const KyFloat32 value, const KyFloat32 average, const KyFloat32 max, const KyFloat32 min, const char* groupName);
247  void SendStats(const FloatStat& timeStat, const char* groupName);
248  void SendStats(const char* statName, const FloatStat& timeStat, const char* groupName);
249 
250 
251  // ------------------ Send Single Value ------------------
253 
254  void SendUInt32(const char* statName, const KyUInt32 value, const char* groupName);
255  void SendInt32(const char* statName, const KyInt32 value, const char* groupName);
256  void SendFloat32(const char* statName, const KyFloat32 value, const char* groupName);
257  void SendString(const char* statName, const char* value, const char* groupName);
258 
259  // --------------- Send Game-Specific info ---------------
260 
261  void SendGameCamera(const Vec3f& cameraPos, const Vec3f& cameraLookAtPos, const Vec3f& cameraUp, KyFloat32 fovInDegrees);
262  void SendGameCameraAttitude(const Vec3f& cameraPos, const Vec3f& cameraRight, const Vec3f& cameraUp, const Vec3f& cameraFront, KyFloat32 fovInDegrees);
263 
264  // --------------- Advanced usage : Handling Received Blob Messages ----------------
265 
266  void PauseMessageProcessing() { m_messageProcessingIsPaused = true; }
267  void ResumeMessageProcessing() { m_messageProcessingIsPaused = false; }
268 
269 private:
270  KyResult OpenNavigationLabConnection();
271  KyResult OpenFileConnection();
272 
273  KyResult AggregateMessage(Ptr<BaseBlobHandler> handlerPtr);
274  KyResult CreateAggregateMessage(KyUInt32 deepBlobSize);
275  KyResult SendAggregateMessage();
277  KyResult SetupMessageRegistry(MessageReceiverRegistry* receiverRegistry);
278  KyResult OpenConnection(SocketDispatchMode mode, KyUInt32 port, KyUInt32 broadcastPort, bool initSocketConnection);
279 
280  void AddToStats(KyUInt32 blobtypeId, KyUInt32 deepBlobSize);
281  void ClearStatistics();
282  void SendInternalStatistics();
283 
284  void SendStatGroups();
285  VisualDebugStatGroup* GetStatGroup(const char* groupName);
286  VisualDebugStatGroup* GetOrCreateStatGroup(const char* groupName);
287 
288  void ClearSession(); // clear stats, message, timer, gameFrameIndex
289  void OnDisconnection(); // called in VisualDebugServer's operatingThread to clear the session if OnDisconnectionUnsafeCallback() was called from the socketThread
290  void OnConnection(); // set m_isConnected to true and apply what has to be done in VisualDebugServer's operatingThread on connection
291 
292  KyResult OnConnectionUnsafeCallback(); // called from the socketThread when connection is established
293  KyResult OnDisconnectionUnsafeCallback(); // called from the socketThread when disconnected
294 
295  void UpdateThreadMgr(bool& out_needToWait);
296 
297  // Checks if there is enough memory before creating a new message
298  void CheckMemory();
299 
300  void InitAttributesManager();
301  void CreateProfilingAttributes();
302  void CreateAdvancedProfilingAttributes();
303  void UpdateProfilingAttributes();
304  void UpdateAdvancedProfilingAttributes();
305 
306  // Indicate if the step of synchronization is disabled or not, used internally
307  void DisableSynchronization(bool disabled) { m_synchronizationStepDisabled = disabled; }
308 
309  // \return true if synchronizing is required, false is sync is done or disabled
310  bool Synchronize();
311 
312 public: // internal
313 
314  // --------------- For internal use only ----------------
317 
320 
321  KyResult Start(const VisualDebugServerConfig& config);
322  KyResult ReStart() { return Start(m_config); }
323  void Stop();
324 
327  static KyUInt32 GetInfiniteWaitDelay() { return KY_WAIT_INFINITE; }
328 
330  bool WaitWhileEstablishingConnection(KyUInt32 maxDelayMilliseconds);
331 
333  void Flush();
334 
339  void SetSimulationTime(KyFloat32 simulationTimeInSeconds) { m_simulationTimeInSeconds = simulationTimeInSeconds; }
340 
343  template <class T>
344  KyResult Send(BaseBlobBuilder<T>& blobBuilder)
345  {
346  const KyUInt32 blobType = T::GetBlobTypeId();
347  Ptr<BaseBlobHandler> blobHandler = m_handlerRegistry.Get(blobType);
348  if (blobHandler == KY_NULL)
349  {
350  blobHandler = *KY_NEW BlobHandler<T>;
351  m_handlerRegistry.SetVal(blobType, blobHandler);
352  }
353 
354  blobBuilder.Build((BlobHandler<T>&)*blobHandler);
355  return this->AggregateMessage(blobHandler);
356  }
357 
362  KyResult Send(BaseBlobHandler& blobHandler);
363 
364  // Send a IQuery if the inheriting query supports it
365  // _NOTE_: Currently, only used in order to send back the result of a query requested by the NavigationLab.
366  KyResult Send(IQuery* query);
367 
373  Ptr<Net::AMP::Message> GetNextReceivedMessage();
375  KyResult HandleMessage(Ptr<Net::AMP::Message> msg);
376 
378  void SetAdvancedInternalStatistics(bool enable) { m_enableAdvancedInternalStatistics = enable; }
379 
381  void SetThreadId(ThreadId threadId) { m_operatingThreadId = threadId; }
382 
384  ThreadId GetThreadId() const { return m_operatingThreadId; }
385 
387  bool CanSafelyOperate() const { return (m_operatingThreadId == GetCurrentThreadId()); }
388 
391  bool IsConnectionEstablished() const;
392 
394  bool IsSynchronizing() { return (m_isConnected == false && IsConnectionEstablished() == true); }
395 
396  // Wait until all messages are sent (or if connection is lost or ended client-side).
397  void WaitForEmptiedSendQueue();
398 
400  KyUInt32 GetFrameIndex() const { return m_gameFrameIndex; }
402  // Called when EndOfSynchronizationBlob is received, done internally by a receiver set by the VisualDebugServer.
403  void OnSynchronizationDone() { m_isSynchronized = true; }
404 
405  Net::AMP::ThreadMgr* GetThreadMgr() { return m_socketThreadMgr.GetPtr(); }
406  const Net::AMP::ThreadMgr* GetThreadMgr() const { return m_socketThreadMgr.GetPtr(); }
409  MemoryHeap* GetHeap() { return Memory::GetHeapByAddress(m_socketThreadMgr.GetPtr()); }
410 
411  // return a pointer because it allows DisabledVisualDebugServer::GetConfig() to return KY_NULL
412  const VisualDebugServerConfig* GetConfig() const { return &m_config; }
413 
414  UserBlobRegistry<IDisplayListBuilder>* GetDisplayListBuilderRegistry() { return m_displayListBuilderRegistry; }
415 
416 private:
417  // Config
418  VisualDebugServerConfig m_config; // The config passed to Start()
419  KyUInt32 m_gameFrameIndex; // The current frame index
420  KyFloat32 m_simulationTimeInSeconds;
421  Profiler* m_gameFrameTimeProfiler;
422  bool m_synchronizationStepDisabled;
423 
424  // Status
425  bool m_isStarted; // Set to true between calls to Start and Stop
426  bool m_isConnectionEstablished;
427  bool m_isSynchronized; // Set to true when EndOfSynchronization is received y the client, not though m_isConnected is not yet set to true, NewFrame needs to be called.
428  bool m_isConnected; // set to true if m_isConnectionEstablished is true on a call to NewFrame that successfully ended the synchronization, so IsConnected can be used to ensure only full frames are sent
429  bool m_wasDisconnected; // Used to cancel previous m_aggregatedBlobMsg
430  ThreadId m_operatingThreadId; // ThreadId of the thread that Send functions and Update are supposed to be called from
431 
432  // Socket/Thread management
433  Ptr<Net::AMP::ThreadMgr> m_socketThreadMgr;
434  Ptr<Net::AMP::DiscardMessageHandler> m_msgDiscarder; // used to discard messages we are not interested in
435  Ptr<MessageBlobHandler> m_msgBlobHandler; // used to handle received MessageBlob
436  SocketDispatcherFactory* m_socketFactory; // in charge of creating the socket depending on VisualDebugServerConfig::Mode
437  Ptr<File> m_file; // used when mode is Mode_UseLocalFile
438 
439  friend class ServerStatusChangedCallback;
440  Ptr<ServerStatusChangedCallback> m_statusCallback; // Callback for connection status change
441  Event m_connectedEvent;
442 
443  // Message construction
444  typedef UserPtrBlobRegistry<BaseBlobHandler> BlobHandlerRegistry;
445  BlobHandlerRegistry m_handlerRegistry;
446  MessageAggregatedBlob* m_aggregatedBlobMsg;
447 
448  // Message reception
449  List<Net::AMP::Message> m_msgList;
450  Kaim::UInt32 m_msgListSize;
451 
452  // Stats
453  KyUInt32 m_messagesNotSentOnWait;
454  KyUInt32 m_memoryLimitReached; // Records if the memory limit was reached during this frame
455  KyFloat32 m_totalFlushTimeMs; // Time spend waiting for the Send queue to be emptied (either in NewFrame or in Flush, or even in CheckMemory)
456 
457  KyUInt32 m_sentBlobCountInFrame;
458  KyUInt32 m_sentBlobSizeInFrame;
459  KyUInt32 m_sentMessageCountInFrame;
460  KyUInt32 m_receivedMessageCountInFrame;
461 
462  UserBlobRegistry<SentBlobTypeStats> m_sentBlobTypeStatsRegistry;
463 
464  KyArray<VisualDebugStatGroup> m_statGroups;
465  bool m_enableAdvancedInternalStatistics;
467  VisualDebugAttributesManager* m_visualDebugAttributesManager;
468  VisualDebugAttributeGroup* m_profilingVisualDebug;
469  VisualDebugAttributeGroup* m_advancedProfilingVisualDebug;
470 
471  bool m_messageProcessingIsPaused;
473  // displayListBuilderRegistry, to verify that QueryBlobs have a DisplayListBuilder before sending them to the NavLab
474  Ptr<UserBlobRegistry<IDisplayListBuilder> > m_displayListBuilderRegistry;
475 };
476 
477 } // namespace Kaim
478 
479 #else
480 // Here we use a separated file in order to easily maintain both versions by comparing the two files (visualdebugserver.h and disabledvisualdebugserver.inl)
482 
483 // This allows to forward declare VisualDebugServer
484 // and to use DisabledVisualDebugServer separately in unit tests
485 namespace Kaim
486 {
487 
488 class VisualDebugServer : public DisabledVisualDebugServer
489 {
490 };
491 
492 }
493 #endif
494 
495 #endif // GwNavRuntime_VisualDebugServer_H
496 
DisconnectionMode
Define how to detect disconnections.
Definition: visualdebugserver.h:71
Base interface for a class that opens a file on disk.
Definition: fileopener.h:35
DisconnectionMode m_disconnectionMode
Define how to detect disconnections.
Definition: visualdebugserver.h:212
const char * m_localFileName
mandatory if m_mode = Mode_UseLocalFile.
Definition: visualdebugserver.h:186
KyInt32 KyResult
Defines a type that can be returned by methods or functions in the Gameware Navigation SDK to indicat...
Definition: types.h:254
KyUInt32 GetFrameIndex() const
Retrieves the number of the current frame.
Definition: visualdebugserver.h:466
static KyUInt32 GetInfiniteWaitDelay()
Defines a special value that can be passed to VisualDebugServer::WaitWhileEstablishingConnection() in...
Definition: visualdebugserver.h:387
KyResult Send(BaseBlobBuilder< T > &blobBuilder)
Sends a blob from a BlobBuilder, the blob will be built into the message, no copy occurs...
Definition: visualdebugserver.h:407
use socket errors to detect disconnections (recommended)
Definition: visualdebugserver.h:72
KyResult HandleMessage(Ptr< Net::AMP::Message > msg)
Handle the given message.
KyUInt32 m_expectedKiloBytesPerFrame
Specifies the expected amount of memory to allocate per frame. Used to define size of a message...
Definition: visualdebugserver.h:203
String m_serverName
Associate a name to the server to ease identification of this server when connecting from the Navigat...
Definition: visualdebugserver.h:218
Writes all visual debug information to a file on the platform.
Definition: visualdebugserver.h:61
MemoryHeap * GetHeap()
Definition: visualdebugserver.h:475
void SetAdvancedInternalStatistics(bool enable)
Enable additional statistics to be sent. These statistics are mainly useful for internal development/...
Definition: visualdebugserver.h:443
bool IsConnected()
Tells if it's worth calling the Send* functions.
Definition: visualdebugserver.h:276
void Flush()
Effectively, send/write all messages (exactly they are passed to the OS).
void SetThreadId(ThreadId threadId)
Set the ThreadId that Send and Update are supposed to be called from. By default, assigned when calli...
Definition: visualdebugserver.h:446
int KyInt32
Type used internally to represent a 32-bit integer.
Definition: types.h:35
#define KY_NULL
Null value.
Definition: types.h:247
KyInt32 m_localFileMegaBytesLimit
The size limit of the local file, when this limit is reached, the VisualDebugServer disconnects...
Definition: visualdebugserver.h:192
KyResult HandleAllReceivedMessages()
Get and handle all received messages based on the MessageReceiverRegistry parameter provided to Start...
void SetSimulationTime(KyFloat32 simulationTimeInSeconds)
Usually, set by Kaim::World with the given simulation time passed to Kaim::World::Update().
Definition: visualdebugserver.h:401
Mode m_mode
The visual debug information destination mode.
Definition: visualdebugserver.h:157
KyUInt32 m_maximumMegaBytes
Specifies the maximum amount of memory this VisualDebugServer is allowed to allocate for creating mes...
Definition: visualdebugserver.h:201
void SetMemoryConsumption(KyUInt32 expectedKiloBytesPerFrame, KyUInt32 maximumMegaBytesToUse)
Define memory limitations for the VisualDebugServer.
Definition: visualdebugserver.h:140
Ptr< Net::AMP::Message > GetNextReceivedMessage()
Return next received message.
bool CanSafelyOperate() const
Check if it is safe to call Update and Send functions.
Definition: visualdebugserver.h:452
void NewFrame()
Indicates the beginning of a new game frame.
Configure the VisualDebugServer.
Definition: visualdebugserver.h:48
A group of Key / valuetype / arrayof values, where the keys and types are created once...
Definition: visualdebugattributes.h:109
KyUInt32 m_broadcastPort
The port used to broadcast the existence of this server.
Definition: visualdebugserver.h:169
FloatStat maintains current, average, min, max statistics in a sliding window of frames.
Definition: floatstat.h:23
RunMode
Determine how the data are sent.
Definition: visualdebugserver.h:77
Definition: gamekitcrowddispersion.h:20
run in current thread (recommended for most platforms)
Definition: visualdebugserver.h:78
bool WaitWhileEstablishingConnection(KyUInt32 maxDelayMilliseconds)
Wait for the connection to be established (pass GetInfiniteWaitDelay() to wait infinitely if no conne...
Sends visual debug information to the NavigationLab over the Network.
Definition: visualdebugserver.h:60
#define KY_DEFINE_NEW_DELETE_OPERATORS(MemStat)
This macro defines new and delete operators.
Definition: memory.h:137
bool IsStarted() const
Definition: visualdebugserver.h:273
The VisualDebugServer manages the sending of data to clients.
Definition: visualdebugserver.h:254
Net::AMP::ThreadMgr * GetThreadMgr()
Accessor to the internal ThreadMgr.
Definition: visualdebugserver.h:471
KyUInt32 m_serverPort
The port used to listen to NavigationLab incoming connections.
Definition: visualdebugserver.h:166
use secondary threads for sending blobs
Definition: visualdebugserver.h:79
bool IsConnectionEstablished() const
Indicates whether the ThreadManager has established a connection to a network socket or if the localF...
FileOpenerBase * m_localFileOpener
if m_localFileOpener is NULL, DefaultFileOpener will be used
Definition: visualdebugserver.h:189
unsigned int KyUInt32
Type used internally to represent an unsigned 32-bit integer.
Definition: types.h:36
MessageReceiverRegistry * m_navigationLabCommandHandlers
Optional, handles the commands that come from the Gameware Navigation from the Network.
Definition: visualdebugserver.h:177
Mode
Enumerates the visual debug information destination.
Definition: visualdebugserver.h:59
bool IsSynchronizing()
Tells if currently synchronizing, in this state Send should only be called to send synchronization da...
Definition: visualdebugserver.h:460
KyResult HandleNextReceivedMessage()
Start will block until a connection occurs.
Definition: visualdebugserver.h:67
RunMode m_runMode
Define how to run the server, either directly in the current thread (recommended), or using secondary threads.
Definition: visualdebugserver.h:215
ThreadId GetThreadId() const
Get the ThreadId that Send and Update are supposed to be called from.
Definition: visualdebugserver.h:449
Start won't wait for a connection.
Definition: visualdebugserver.h:66
void UseNavigationLab(KyUInt32 serverPort=DefaultServerPort(), KyUInt32 broadcastPort=DefaultBroadcastPort(), MessageReceiverRegistry *navigationLabCommandHandlers=0)
Reduce chances of selecting conflicting ports by looking at :
Definition: visualdebugserver.h:115
float KyFloat32
Type used internally to represent a 32-bit floating-point number.
Definition: types.h:43
This class defines a three-dimensional vector whose coordinates are stored using floating-point numbe...
Definition: vec3f.h:23
use heartbeat messages to detect disconnections (disconnection can occur when breakpointing) ...
Definition: visualdebugserver.h:73
WaitOnStart
Define the behavior for VisualDebugServer::Start.
Definition: visualdebugserver.h:65