CTR Pia  4.11.3
Game Communication Engine
clone_CloneElementBase.h
1 /*---------------------------------------------------------------------------*
2  Project: Pia
3  File: clone_CloneElementBase.h
4 
5  Copyright Nintendo. All rights reserved.
6 
7  These coded instructions, statements, and computer programs contain
8  proprietary information of Nintendo of America Inc. and/or Nintendo
9  Company Ltd., and are protected by Federal copyright law. They may
10  not be disclosed to third parties or copied or duplicated in any form,
11  in whole or in part, without the prior written consent of Nintendo.
12  *---------------------------------------------------------------------------*/
13 
14 
15 #pragma once
16 
17 #include <pia/clone/clone_definitions.h>
18 #include <pia/common/common_TreeMapNode.h>
19 #include <pia/common/common_ListNode.h>
20 
21 namespace nn
22 {
23 namespace pia
24 {
25 namespace clone
26 {
27 
28 class CloneBase;
29 class CloneProtocol;
30 class IDataPacker;
31 class IDataUnpacker;
32 class CloneProfilerBase;
33 
34 /*!
35 @brief This is the base class for managing data that is sent and received.
36 @date 2013-11-25 Added a profiling feature.
37 @date 2013-07-18 Initial version.
38 
39 */
41 {
42 protected:
43 /*!
44 @brief Instantiates the object with default parameters (default constructor).
45 */
47 
48 
49 public:
50 /*!
51 @brief Destroys the object.
52 */
53  virtual ~CloneElementBase();
54 
55 
56 /*!
57 @brief Specifies the type of the ID for identifying clone elements.
58 */
59  typedef u16 Id;
60 
61 
62 /*!
63 @brief Gets the ID.
64 @return Returns the ID specified when registering the object with <tt>CloneBase</tt>. Returns <tt>0</tt> if the object is not registered with <tt>CloneBase</tt>.
65 (If <tt>0</tt> was specified as the ID when registering the object, <tt>0</tt> may be returned as a valid value.)
66 */
67  Id GetId() const
68  {
69  return m_TreeMapNode.GetKey();
70  }
71 
72 
73 /*!
74 @brief Gets the <tt>CloneBase</tt> this object is registered to.
75 @return Returns the <tt>CloneBase</tt> this object is registered to.
76 */
77  const CloneBase* GetCloneBase() const
78  {
79  return m_pCloneBase;
80  }
81 
82 
83 /*!
84 @brief Gets the <tt>CloneProtocol</tt> of the <tt>CloneBase</tt> this object is registered to.
85 @return Returns the <tt>CloneProtocol</tt> of the <tt>CloneBase</tt> this object is registered to.
86 */
87  const CloneProtocol* GetProtocol() const;
88 
89 
90 /*!
91 @brief Determines whether the object is registered with <tt>CloneBase</tt>.
92 @return Returns <tt>true</tt> if it is registered with <tt>CloneBase</tt>.
93 */
95  {
96  return m_pCloneBase != NULL;
97  }
98 
99 
100 /*!
101 @brief Determines whether the object is registered with <tt>CloneProtocol</tt>.
102 @return Returns <tt>true</tt> if it is registered with <tt>CloneProtocol</tt>.
103 */
104  bool IsRegisteredWithProtocol() const;
105 
106 
107 /*!
108 @brief Determines whether a value can be set.
109 @return Returns <tt>true</tt> if a value can be set.
110 */
111  bool IsReadyToSetValue() const;
112 
113 
114  //! @name Profiling
115  //! @{
116 
117 /*!
118 @brief Sets an object to manage send/receive profiling.
119 @details Clone element send/receive tasks can be profiled by configuring <tt>CloneProfiler</tt>.
120 This calculation includes all exchanges of data between this clone element and other clone elements, so the data exchanges between clone elements on the local station are also included in the value.
121 @details Even when compression is enabled, the uncompressed size is used in the calculation.
122 @details A <tt>CloneProfiler</tt> instance that is already configured can be released by specifying <tt>NULL</tt> in the arguments.
123 @param[in] pSendProfiler Specifies the <tt>CloneProfiler</tt> that manages the send profiling.
124 Specify <tt>NULL</tt> if not necessary.
125 @param[in] pReceiveProfiler Specifies the <tt>CloneProfiler</tt> that manages the receive profiling.
126 Specify <tt>NULL</tt> if not necessary.
127 @return Returns a <tt>Result</tt> value for which the <tt>IsSuccess</tt> function returns <tt>true</tt> if execution succeeds. You must make sure that the implementation of this function in your application does not return any errors.
128 @retval ResultInvalidArgument Indicates that an argument is invalid. Programming error. Fix your program so that this error is not returned.
129 
130 */
131  nn::Result SetProfiler(CloneProfilerBase* pSendProfiler, CloneProfilerBase* pReceiveProfiler);
132 
133 
134 /*!
135 @brief Gets the object configured to manage send profiling.
136 @return The object configured to manage send profiling. Returns <tt>NULL</tt> if nothing has been set.
137 @see SetProfiler
138 */
140  {
141  return m_pSendProfiler;
142  }
143 
144 
145 /*!
146 @brief Gets the object configured to manage receive profiling.
147 @return The object configured to manage receive profiling. Returns <tt>NULL</tt> if nothing has been set.
148 @see SetProfiler
149 */
151  {
152  return m_pReceiveProfiler;
153  }
154 
155 
156 /*!
157 @brief Resets the results of send/receive profiling.
158 @see SetProfiler
159 */
160  void ResetProfiler();
161 
162 
163 /*!
164 @brief Gets the send count for the last <tt>@ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE"</tt> times <tt>common::Scheduler::Dispatch</tt> was called.
165 @param[in] stationIndex The <tt>StationIndex</tt> that is subject to profiling.
166 @return The send count for the last <tt>@ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE"</tt> times <tt>common::Scheduler::Dispatch</tt> was called.
167 Returns <tt>0</tt> if no object is configured to manage send profiling.
168 @see SetProfiler
169 */
170  u32 GetProfiledLatestSendCount(StationIndex stationIndex) const;
171 
172 
173 /*!
174 @brief Gets the total amount of data, in bytes, sent during the last <tt>@ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE"</tt> times of <tt>common::Scheduler::Dispatch</tt> being called.
175 @param[in] stationIndex The <tt>StationIndex</tt> that is subject to profiling.
176 @return The total amount of data, in bytes, sent during the last <tt>@ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE"</tt> times of <tt>common::Scheduler::Dispatch</tt> being called.
177 Returns <tt>0</tt> if no object is configured to manage send profiling.
178 @see SetProfiler
179 */
180  u32 GetProfiledLatestSendSize(StationIndex stationIndex) const;
181 
182 
183 /*!
184 @brief Gets the number of times sent since <tt>ResetProfiler</tt> was called.
185 @param[in] stationIndex The <tt>StationIndex</tt> that is subject to profiling.
186 @return The number of times sent since <tt>ResetProfiler</tt> was called.
187 Returns <tt>0</tt> if no object is configured to manage send profiling.
188 @see SetProfiler, ResetProfiler
189 */
190  u32 GetProfiledTotalSendCount(StationIndex stationIndex) const;
191 
192 
193 /*!
194 @brief Gets the amount of data, in bytes, sent since <tt>ResetProfiler</tt> was called.
195 @param[in] stationIndex The <tt>StationIndex</tt> that is subject to profiling.
196 @return The amount of data, in bytes, sent since <tt>ResetProfiler</tt> was called.
197 Returns <tt>0</tt> if no object is configured to manage send profiling.
198 @see SetProfiler, ResetProfiler
199 */
200  u32 GetProfiledTotalSendSize(StationIndex stationIndex) const;
201 
202 
203 /*!
204 @brief Gets the receive count for the last <tt>@ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE"</tt> times <tt>common::Scheduler::Dispatch</tt> was called.
205 @param[in] stationIndex The <tt>StationIndex</tt> that is subject to profiling.
206 @return The receive count for the last <tt>@ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE"</tt> times <tt>common::Scheduler::Dispatch</tt> was called.
207 Returns <tt>0</tt> if no object is configured to manage receive profiling.
208 @see SetProfiler
209 */
210  u32 GetProfiledLatestReceiveCount(StationIndex stationIndex) const;
211 
212 
213 /*!
214 @brief Gets the total amount of data, in bytes, received during the last <tt>@ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE"</tt> times of <tt>common::Scheduler::Dispatch</tt> being called.
215 @param[in] stationIndex The <tt>StationIndex</tt> that is subject to profiling.
216 @return The total amount of data, in bytes, received during the last <tt>@ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE"</tt> times of <tt>common::Scheduler::Dispatch</tt> being called.
217 Returns <tt>0</tt> if no object is configured to manage receive profiling.
218 @see SetProfiler
219 */
220  u32 GetProfiledLatestReceiveSize(StationIndex stationIndex) const;
221 
222 
223 /*!
224 @brief Gets the number of times received since <tt>ResetProfiler</tt> was called.
225 @param[in] stationIndex The <tt>StationIndex</tt> that is subject to profiling.
226 @return The number of times received since <tt>ResetProfiler</tt> was called.
227 Returns <tt>0</tt> if no object is configured to manage receive profiling.
228 @see SetProfiler, ResetProfiler
229 */
230  u32 GetProfiledTotalReceiveCount(StationIndex stationIndex) const;
231 
232 
233 /*!
234 @brief Gets the amount of data, in bytes, received since <tt>ResetProfiler</tt> was called.
235 @param[in] stationIndex The <tt>StationIndex</tt> that is subject to profiling.
236 @return The amount of data, in bytes, received since <tt>ResetProfiler</tt> was called.
237 Returns <tt>0</tt> if no object is configured to manage receive profiling.
238 @see SetProfiler, ResetProfiler
239 */
240  u32 GetProfiledTotalReceiveSize(StationIndex stationIndex) const;
241 
242  //! @}
243 
244 
245  //! @cond PRIVATE
246 
247 public:
248  static s32 GetTreeMapNodeOffset()
249  {
250  return offsetof(CloneElementBase, m_TreeMapNode);
251  }
252 
253  virtual bool IsSupportedClone(int cloneType) const
254  {
255  NN_PIA_DUMMY_PARAM(cloneType);
256  return true;
257  }
258  void AttachCloneBase(CloneBase* pCloneBase);
259  void DetachCloneBase();
260 
261  CloneProfilerBase* GetSendProfilerPtr()
262  {
263  return m_pSendProfiler;
264  }
265  CloneProfilerBase* GetReceiveProfilerPtr()
266  {
267  return m_pReceiveProfiler;
268  }
269 
270  enum Type
271  {
272  TYPE_UNRELIABLE = 0x1000,
273  TYPE_RELIABLE = 0x2000,
274  TYPE_EVENT = 0x3000,
275  TYPE_RECKONING = 0x4000,
276  TYPE_RELIABLE_LARGE = 0x5000
277  };
278 
279  virtual u16 GetType() const = 0;
280  virtual size_t GetSize() const = 0;
281 
282  virtual bool IsInitialized() const
283  {
284  return true;
285  }
286 
287  virtual void ClearData() = 0;
288  virtual void AddDest(StationIndex stationId)
289  {
290  NN_PIA_DUMMY_PARAM(stationId);
291  }
292  virtual void RemoveDest(StationIndex stationId)
293  {
294  NN_PIA_DUMMY_PARAM(stationId);
295  }
296  virtual void AddParticipant(StationIndex stationId)
297  {
298  NN_PIA_DUMMY_PARAM(stationId);
299  }
300  virtual void Complement(StationIndex stationId)
301  {
302  NN_PIA_DUMMY_PARAM(stationId);
303  }
304  virtual void Lock()
305  {
306  }
307 
308  virtual void RequestInitialData()
309  {
310  }
311 
312  u32 GetStationNum() const;
313 
314 public:
315  class ISendToken
316  {
317  public:
318  ISendToken()
319  : m_ListNode()
320  {
321  }
322  bool IsInList() const
323  {
324  return m_ListNode.IsFreeListNode() == false;
325  }
326  virtual Type GetElementType() const = 0;
327  virtual u32 GetDestBitmap() const = 0;
328  virtual bool IsResend() const
329  {
330  return false;
331  }
332  virtual size_t GetChunkSize() const = 0;
333  virtual void WriteChunk(void* pChunkBuffer) const = 0;
334  virtual CloneElementBase* GetElement() = 0;
335  static s32 GetListNodeOffset()
336  {
337  return offsetof(ISendToken, m_ListNode);
338  }
339 
340  private:
341  common::ListNode m_ListNode;
342  };
343 
344 
345  class ResendableSendToken : public ISendToken
346  {
347  public:
348  ResendableSendToken()
349  : ISendToken(), m_LastSendTime(INVALID_SYSTEM_TIME), m_IsSendDelay(false), m_SendCount(0)
350  {
351  for (int i = 0; i < MAX_STATION_NUM; ++i)
352  {
353  m_LastSendTimeArray[i] = INVALID_SYSTEM_TIME;
354  m_SendCountArray[i] = 0;
355  }
356  }
357  virtual bool IsResend() const
358  {
359  return true;
360  }
361  SystemTime GetLastSendTime(StationIndex stationIndex) const
362  {
363  if (stationIndex == STATION_INDEX_INVALID)
364  {
365  return m_LastSendTime;
366  }
367  else
368  {
369  PIA_ASSERT(IsUnicast());
370  PIA_ASSERT(stationIndex < MAX_STATION_NUM);
371  return m_LastSendTimeArray[stationIndex];
372  }
373  }
374  bool IsSendDelay() const
375  {
376  return m_IsSendDelay;
377  }
378  void SetLastSendTime(SystemTime time, StationIndex stationIndex)
379  {
380  if (stationIndex == STATION_INDEX_INVALID)
381  {
382  m_LastSendTime = time;
383  }
384  else
385  {
386  PIA_ASSERT(IsUnicast());
387  PIA_ASSERT(stationIndex < MAX_STATION_NUM);
388  m_LastSendTimeArray[stationIndex] = time;
389  }
390  }
391  void EnableSendDelay(bool isSendDelay)
392  {
393  m_IsSendDelay = isSendDelay;
394  }
395  // Overridden to return <tt>true</tt> in token classes that resend using unicast.
396  virtual bool IsUnicast() const
397  {
398  return false;
399  }
400  void SetSendCount(u32 sendCount, StationIndex stationIndex)
401  {
402  if (stationIndex == STATION_INDEX_INVALID)
403  {
404  m_SendCount = sendCount;
405  }
406  else
407  {
408  PIA_ASSERT(IsUnicast());
409  PIA_ASSERT(stationIndex < MAX_STATION_NUM);
410  m_SendCountArray[stationIndex] = sendCount;
411  }
412  }
413  void IncrementSendCount(StationIndex stationIndex)
414  {
415  if (stationIndex == STATION_INDEX_INVALID)
416  {
417  ++m_SendCount;
418  }
419  else
420  {
421  PIA_ASSERT(IsUnicast());
422  PIA_ASSERT(stationIndex < MAX_STATION_NUM);
423  ++m_SendCountArray[stationIndex];
424  }
425  }
426  u32 GetSendCount(StationIndex stationIndex) const
427  {
428  if (stationIndex == STATION_INDEX_INVALID)
429  {
430  return m_SendCount;
431  }
432  else
433  {
434  PIA_ASSERT(IsUnicast());
435  PIA_ASSERT(stationIndex < MAX_STATION_NUM);
436  return m_SendCountArray[stationIndex];
437  }
438  }
439 
440  private:
441  SystemTime m_LastSendTime;
442  SystemTime m_LastSendTimeArray[MAX_STATION_NUM];
443  bool m_IsSendDelay;
444  u32 m_SendCount;
445  u32 m_SendCountArray[MAX_STATION_NUM];
446  };
447 
448 
449  class ConversibleResendableSendToken : public ResendableSendToken
450  {
451  public:
452  ConversibleResendableSendToken()
453  : ResendableSendToken(), m_IsResend(false)
454  {
455  }
456  virtual bool IsResend() const
457  {
458  return m_IsResend;
459  }
460  void SetResend(bool isResend)
461  {
462  m_IsResend = isResend;
463  }
464 
465  private:
466  bool m_IsResend;
467  };
468 
469 protected:
470  void AddSendData(ISendToken* pToken);
471  void AddSendDelayData(ResendableSendToken* pToken);
472  void CancelSendData(ISendToken* pToken);
473 
474 protected:
475  void ErrorDropEvent();
476 
477 private:
478  // Copying and assignment are prohibited.
480  CloneElementBase& operator=(const CloneElementBase& rhs);
481 
482 private:
483  common::TreeMapNode<Id> m_TreeMapNode;
484  CloneBase* m_pCloneBase;
485 
486 public:
487  template <typename Element, typename CP>
488  class DefinitionBase
489  {
490  protected:
491  DefinitionBase()
492  {
493  CP::GetElementDefinition()->Register(Element::GetTypeStatic(), Element::Receive, Element::GetDataChunkHeaderSize());
494  }
495  };
496 
497  template <typename Element>
498  class Definition : public DefinitionBase<Element, CloneProtocol>
499  {
500  public:
501  Definition()
502  : DefinitionBase<Element, CloneProtocol>()
503  {
504  }
505  };
506 
507 private:
508  CloneProfilerBase* m_pSendProfiler;
509  CloneProfilerBase* m_pReceiveProfiler;
510 
511 public:
512  template <int TEST_ID, typename Arg>
513  static void Test(const CloneElementBase& obj, Arg* pArg = NULL);
514 
515  //! @endcond
516 };
517 }
518 }
519 } // end of namespace nn::pia::clone
u32 GetProfiledTotalReceiveSize(StationIndex stationIndex) const
Gets the amount of data, in bytes, received since ResetProfiler was called.
This is the base class for managing data that is sent and received. .
Definition: clone_CloneElementBase.h:40
u32 GetProfiledLatestSendSize(StationIndex stationIndex) const
Gets the total amount of data, in bytes, sent during the last CloneProfiler::LATEST_BUFFER_SIZE times...
u32 GetProfiledTotalReceiveCount(StationIndex stationIndex) const
Gets the number of times received since ResetProfiler was called.
void ResetProfiler()
Resets the results of send/receive profiling.
const CloneProfilerBase * GetSendProfiler() const
Gets the object configured to manage send profiling.
Definition: clone_CloneElementBase.h:139
u32 GetProfiledLatestSendCount(StationIndex stationIndex) const
Gets the send count for the last CloneProfiler::LATEST_BUFFER_SIZE times common::Scheduler::Dispatch ...
StationIndex
Enumerates StationIndex values.
Definition: platformCtr.h:44
Definition: assert.h:115
ID indicating a station that is not present in the session.
Definition: platformCtr.h:59
Represents a protocol for sharing values between stations.
Definition: clone_CloneProtocol.h:51
bool IsInitialized(void)
Gets whether the clone module is initialized.
u32 GetProfiledLatestReceiveSize(StationIndex stationIndex) const
Gets the total amount of data, in bytes, received during the last CloneProfiler::LATEST_BUFFER_SIZE t...
This base class manages PiaClone profiling.
Definition: clone_CloneProfilerBase.h:33
u32 GetProfiledTotalSendSize(StationIndex stationIndex) const
Gets the amount of data, in bytes, sent since ResetProfiler was called.
This is the base class for managing sending and receiving. .
Definition: clone_CloneBase.h:38
const size_t MAX_STATION_NUM
The maximum value for the number of stations that can participate in a Pia session.
Definition: platformCtr.h:64
const CloneBase * GetCloneBase() const
Gets the CloneBase this object is registered to.
Definition: clone_CloneElementBase.h:77
bool IsRegisteredWithProtocol() const
Determines whether the object is registered with CloneProtocol.
nn::Result SetProfiler(CloneProfilerBase *pSendProfiler, CloneProfilerBase *pReceiveProfiler)
Sets an object to manage send/receive profiling.
bool IsReadyToSetValue() const
Determines whether a value can be set.
virtual ~CloneElementBase()
Destroys the object.
const CloneProfilerBase * GetReceiveProfiler() const
Gets the object configured to manage receive profiling.
Definition: clone_CloneElementBase.h:150
u32 GetProfiledTotalSendCount(StationIndex stationIndex) const
Gets the number of times sent since ResetProfiler was called.
bool IsRegisteredWithCloneBase() const
Determines whether the object is registered with CloneBase.
Definition: clone_CloneElementBase.h:94
u32 GetProfiledLatestReceiveCount(StationIndex stationIndex) const
Gets the receive count for the last CloneProfiler::LATEST_BUFFER_SIZE times common::Scheduler::Dispat...
u16 Id
Specifies the type of the ID for identifying clone elements.
Definition: clone_CloneElementBase.h:59
const CloneProtocol * GetProtocol() const
Gets the CloneProtocol of the CloneBase this object is registered to.
Id GetId() const
Gets the ID.
Definition: clone_CloneElementBase.h:67