CTR-Pia  5.4.3
Game Communication Engine
 全て クラス ネームスペース 関数 変数 型定義 列挙型 列挙型の値 ページ
clone_CloneBase.h
1 /*--------------------------------------------------------------------------------*
2  Copyright (C)Nintendo All rights reserved.
3 
4  These coded instructions, statements, and computer programs contain proprietary
5  information of Nintendo and/or its licensed developers and are protected by
6  national and international copyright laws. They may not be disclosed to third
7  parties or copied or duplicated in any form, in whole or in part, without the
8  prior written consent of Nintendo.
9 
10  The content herein is highly confidential and should be handled accordingly.
11  *--------------------------------------------------------------------------------*/
12 
13 
14 #pragma once
15 
16 #include <nn/pia/clone/clone_Definitions.h>
17 #include <nn/pia/clone/clone_CloneElementBase.h>
18 #include <nn/pia/common/common_TreeMapNode.h>
19 #include <nn/pia/common/common_OffsetTreeMap.h>
20 #include <nn/pia/common/common_OffsetList.h>
21 
22 namespace nn
23 {
24 namespace pia
25 {
26 namespace clone
27 {
28 
29 class CloneProtocol;
30 
31 /*!
32  @brief 送受信を管理する基底クラスです。
33  */
34 class CloneBase
35 {
36 public:
37 protected:
38  /*!
39  @brief デフォルトコンストラクタです。
40  */
41  CloneBase();
42 
43 
44 public:
45  /*!
46  @brief デストラクタです。
47  */
48  virtual ~CloneBase();
49 
50 
51  /*!
52  @brief このオブジェクトが登録されている CloneProtocol を取得します。
53  @return このオブジェクトが登録されている CloneProtocol です。
54  */
55  const CloneProtocol* GetProtocol() const
56  {
57  return m_pProtocol;
58  }
59 
60 
61  /*!
62  @brief クローンを識別するための ID の型です。
63  */
64  typedef uint32_t Id;
65 
66 
67  /*!
68  @brief ID を取得します。
69  @return CloneProtocol に登録する際に指定したIDです。 CloneProtocol に登録されていない場合は 0 を返します。
70  */
71  Id GetId() const
72  {
73  return static_cast<Id>(m_TreeMapNode.GetKey() & 0xffffffff);
74  }
75 
76 
77  /*!
78  @brief CloneProtocol に登録されているかどうかを判定します。
79  @return CloneProtocol に登録されていれば true を返します。
80  */
82  {
83  return m_pProtocol != NULL;
84  }
85 
86 
87  /*!
88  @brief クローンエレメントを登録します。
89  @details このオブジェクトが CloneProtocol に登録されていない状態で呼び出す必要があります。
90  @param[in] pElement 登録するクローンエレメントです。
91  @param[in] elementId 登録するクローンエレメントの ID です。
92  @return 成功すれば、IsSuccess() が true を返す Result が返されます。
93  @retval ResultInvalidState このオブジェクトが CloneProtocol に登録されています。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
94  @retval ResultInvalidArgument 引数が不正です。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
95  @retval ResultAlreadyExists 指定された ID には既にクローンエレメントが登録されています。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
96  */
98 
99 
100  /*!
101  @brief クローンエレメントの登録を解除します。
102  @details このオブジェクトが CloneProtocol に登録されていない状態で呼び出す必要があります。
103  @param[in] pElement 登録解除するクローンエレメントです。
104  @return 成功すれば、IsSuccess() が true を返す Result が返されます。この関数がエラーを返さないようにアプリケーションを実装する必要があります。
105  @retval ResultInvalidState このオブジェクトが CloneProtocol に登録されています。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
106  @retval ResultInvalidArgument 引数が不正です。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
107  */
109 
110 
111  /*!
112  @brief クローンエレメントの登録を解除します。
113  @details このオブジェクトが CloneProtocol に登録されていない状態で呼び出す必要があります。
114  @param[in] elementId 登録解除するクローンエレメントの ID です。
115  @return 成功すれば、IsSuccess() が true を返す Result が返されます。この関数がエラーを返さないようにアプリケーションを実装する必要があります。
116  @retval ResultInvalidState このオブジェクトが CloneProtocol に登録されています。 プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
117  @retval ResultNotSet 指定された ID にはクローンエレメントが登録されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
118  */
120 
121 
122  /*!
123  @brief 指定された ID のクローンエレメントを検索します。
124  @param[in] elementId 検索するクローンエレメントです。
125  @return 指定された ID のクローンエレメントを返します。存在しなければ NULL を返します。
126  */
128  {
129  return m_ElementCollection.Find(elementId);
130  }
131 
132 
133  /*!
134  @brief 指定された ID のクローンエレメントを検索します。
135  @param[in] elementId 検索するクローンエレメントです。
136  @return 指定された ID のクローンエレメントを返します。存在しなければ NULL を返します。
137  */
139  {
140  return m_ElementCollection.Find(elementId);
141  }
142 
143 
144  /*!
145  @brief このオブジェクトが動作中かどうかを取得します。
146  @details CloneProtocol に登録されていて、実際に値の送受信ができる状態であれば動作中と扱います。
147  CloneProtocol への登録/登録解除処理中や、 CloneProtocol の開始/終了処理中は動作中ではありません。
148  @return 動作中なら true を返します。
149  */
150  bool IsActive() const
151  {
152  return (m_State == State_Active);
153  }
154 
155 
156  //! @name プロファイリング
157  //! @{
158 
159  /*!
160  @brief 送受信のプロファイリング管理オブジェクトを設定します。
161  @details CloneProfiler を設定すると、登録されているクローンエレメントおよびクローン自身が行った送受信をプロファイリングできます。
162  ここでの計測は、このクローンが他のクローンと行うすべてのデータのやり取りが計上されるため、
163  自ステーション内でのクローン間のデータのやり取りも値に含まれます。
164  @details 複数のクローンエレメントが同時に送信する場合、クローン単位で一つにまとめられるため、
165  多くの場合、クローンエレメントの送受信回数の合計よりクローンの送受信回数の方が小さくなります。
166  @details 圧縮を有効にしていた場合、計測されるサイズは圧縮された状態でのサイズです。
167  そのため、登録しているクローンエレメントで計測された送受信サイズの合計より、数値上は小さい値が計測される場合があります。
168  @details 引数に NULL を指定すると、既に設定してある CloneProfiler を解除する事ができます。
169  @param[in] pSendProfiler 送信のプロファイリングを管理する CloneProfiler を指定します。
170  必要ない場合は NULL を指定する必要があります。
171  @param[in] pReceiveProfiler 受信のプロファイリングを管理する CloneProfiler を指定します。
172  必要ない場合は NULL を指定する必要があります。
173  @return 成功すれば、IsSuccess() が true を返す Result が返されます。この関数がエラーを返さないようにアプリケーションを実装する必要があります。
174  @retval ResultInvalidArgument 引数が不正です。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
175  */
176  Result SetProfiler(CloneProfilerBase* pSendProfiler, CloneProfilerBase* pReceiveProfiler);
177 
178 
179  /*!
180  @brief 設定されている送信プロファイリング管理オブジェクトを取得します。
181  @return 設定されている送信プロファイリング管理オブジェクトです。設定されていない場合は NULL を返します。
182  @see SetProfiler
183  */
185  {
186  return m_pSendProfiler;
187  }
188 
189 
190  /*!
191  @brief 設定されている受信プロファイリング管理オブジェクトを取得します。
192  @return 設定されている受信プロファイリング管理オブジェクトです。設定されていない場合は NULL を返します。
193  @see SetProfiler
194  */
196  {
197  return m_pReceiveProfiler;
198  }
199 
200 
201  /*!
202  @brief 送受信のプロファイリングされた結果をリセットします。
203  @see SetProfiler
204  */
205  void ResetProfiler();
206 
207 
208  /*!
209  @brief 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に送信した クローンメッセージの個数を取得します。
210  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
211  @return 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に送信したクローンメッセージの個数です。
212  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
213  @see SetProfiler
214  */
215  uint32_t GetProfiledLatestSendCount(StationIndex stationIndex) const;
216 
217 
218  /*!
219  @brief 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に送信したクローンメッセージのサイズ(バイト)を取得します。
220  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
221  @return 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に送信したクローンメッセージのサイズ(バイト)です。
222  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
223  @see SetProfiler
224  */
225  uint32_t GetProfiledLatestSendSize(StationIndex stationIndex) const;
226 
227 
228  /*!
229  @brief 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に送信したクローンメッセージの圧縮前のサイズ(バイト)を取得します。
230  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
231  @return 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に送信したクローンメッセージの圧縮前のサイズ(バイト)です。
232  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
233  @see SetProfiler
234  */
235  uint32_t GetProfiledLatestSendNoCompressedSize(StationIndex stationIndex) const;
236 
237 
238  /*!
239  @brief 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間にユニキャストで送信したクローンメッセージの個数を取得します。
240  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
241  @return 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間にユニキャストで送信したクローンメッセージの個数です。
242  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
243  @see SetProfiler
244  */
245  uint32_t GetProfiledLatestSendUnicastCount(StationIndex stationIndex) const;
246 
247 
248  /*!
249  @brief 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間にユニキャストで送信したクローンメッセージのサイズ(バイト)を取得します。
250  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
251  @return 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間にユニキャストで送信したクローンメッセージのサイズ(バイト)です。
252  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
253  @see SetProfiler
254  */
255  uint32_t GetProfiledLatestSendUnicastSize(StationIndex stationIndex) const;
256 
257 
258  /*!
259  @brief 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に送信したシステム用クローンメッセージの個数を取得します。
260  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
261  @return 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に送信したシステム用クローンメッセージの個数です。
262  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
263  @see SetProfiler
264  */
265  uint32_t GetProfiledLatestSendSystemCount(StationIndex stationIndex) const;
266 
267 
268  /*!
269  @brief 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に送信したシステム用クローンメッセージのサイズ(バイト)を取得します。
270  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
271  @return 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に送信したシステム用クローンメッセージのサイズ(バイト)です。
272  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
273  @see SetProfiler
274  */
275  uint32_t GetProfiledLatestSendSystemSize(StationIndex stationIndex) const;
276 
277 
278  /*!
279  @brief ResetProfiler 以降に送信したクローンメッセージの個数を取得します。
280  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
281  @return ResetProfiler() 以降に送信したクローンメッセージの個数です。
282  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
283  @see SetProfiler, ResetProfiler
284  */
285  uint32_t GetProfiledTotalSendCount(StationIndex stationIndex) const;
286 
287 
288  /*!
289  @brief ResetProfiler 以降に送信したクローンメッセージのサイズ(バイト)を取得します。
290  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
291  @return ResetProfiler() 以降に送信したクローンメッセージのサイズ(バイト)です。
292  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
293  @see SetProfiler, ResetProfiler
294  */
295  uint32_t GetProfiledTotalSendSize(StationIndex stationIndex) const;
296 
297 
298  /*!
299  @brief ResetProfiler 以降に送信したクローンメッセージの圧縮前のサイズ(バイト)を取得します。
300  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
301  @return ResetProfiler() 以降に送信したクローンメッセージの圧縮前のサイズ(バイト)です。
302  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
303  @see SetProfiler, ResetProfiler
304  */
305  uint32_t GetProfiledTotalSendNoCompressedSize(StationIndex stationIndex) const;
306 
307 
308  /*!
309  @brief ResetProfiler 以降にユニキャストで送信したクローンメッセージの個数を取得します。
310  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
311  @return ResetProfiler() 以降にユニキャストで送信したクローンメッセージの個数です。
312  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
313  @see SetProfiler, ResetProfiler
314  */
315  uint32_t GetProfiledTotalSendUnicastCount(StationIndex stationIndex) const;
316 
317 
318  /*!
319  @brief ResetProfiler 以降にユニキャストで送信したクローンメッセージのサイズ(バイト)を取得します。
320  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
321  @return ResetProfiler() 以降にユニキャストで送信したクローンメッセージのサイズ(バイト)です。
322  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
323  @see SetProfiler, ResetProfiler
324  */
325  uint32_t GetProfiledTotalSendUnicastSize(StationIndex stationIndex) const;
326 
327 
328  /*!
329  @brief ResetProfiler 以降に送信したシステム用クローンメッセージの個数を取得します。
330  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
331  @return ResetProfiler() 以降に送信したシステム用クローンメッセージの個数です。
332  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
333  @see SetProfiler, ResetProfiler
334  */
335  uint32_t GetProfiledTotalSendSystemCount(StationIndex stationIndex) const;
336 
337 
338  /*!
339  @brief ResetProfiler 以降に送信したシステム用クローンメッセージのサイズ(バイト)を取得します。
340  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
341  @return ResetProfiler() 以降に送信したシステム用クローンメッセージのサイズ(バイト)です。
342  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
343  @see SetProfiler, ResetProfiler
344  */
345  uint32_t GetProfiledTotalSendSystemSize(StationIndex stationIndex) const;
346 
347 
348  /*!
349  @brief 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に受信したクローンメッセージの個数を取得します。
350  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
351  @return 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に受信したクローンメッセージの個数です。
352  受信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
353  @see SetProfiler
354  */
355  uint32_t GetProfiledLatestReceiveCount(StationIndex stationIndex) const;
356 
357 
358  /*!
359  @brief 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に受信したクローンメッセージのサイズ(バイト)を取得します。
360  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
361  @return 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に受信したクローンメッセージのサイズ(バイト)です。
362  受信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
363  @see SetProfiler
364  */
365  uint32_t GetProfiledLatestReceiveSize(StationIndex stationIndex) const;
366 
367 
368  /*!
369  @brief ResetProfiler 以降に受信したクローンメッセージの個数を取得します。
370  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
371  @return ResetProfiler() 以降に受信したクローンメッセージの個数です。
372  受信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
373  @see SetProfiler, ResetProfiler
374  */
375  uint32_t GetProfiledTotalReceiveCount(StationIndex stationIndex) const;
376 
377 
378  /*!
379  @brief ResetProfiler 以降に受信したクローンメッセージのサイズ(バイト)を取得します。
380  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
381  @return ResetProfiler() 以降に受信したクローンメッセージのサイズ(バイト)です。
382  受信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
383  @see SetProfiler, ResetProfiler
384  */
385  uint32_t GetProfiledTotalReceiveSize(StationIndex stationIndex) const;
386 
387  //! @}
388 
389  virtual void Trace(uint64_t flag) const;
390 
391  //! @cond PRIVATE
392 
393 public:
394  enum Type
395  {
396  Type_Send = 0x01,
397  Type_Receive = 0x02,
398  Type_Atomic = 0x03,
399  Type_Sequential = 0x04
400  };
401 
402  virtual Type GetTypeVirtual() const = 0;
403 
404 
405  typedef uint64_t Key;
406 
407 
408  static int32_t GetTreeMapNodeOffset()
409  {
410  NN_PIA_PRAGMA_PUSH_WARNINGS
411  NN_PIA_DISABLE_WARNING_CLANG_INVALID_OFFSETOF
412  return offsetof(CloneBase, m_TreeMapNode);
413  NN_PIA_PRAGMA_POP_WARNINGS
414  }
415 
416  void UnregisterElementForce(CloneElementBase* pElement);
417 
418  bool CheckElementSize(uint32_t sizeMax);
419  void AttachProtocol(CloneProtocol* pProtocol);
420  void DetachProtocol();
421 
422  Type GetType() const
423  {
424  return static_cast<Type>(m_TreeMapNode.GetKey() >> 48);
425  }
426  StationIndex GetStationIndex() const
427  {
428  return static_cast<StationIndex>((m_TreeMapNode.GetKey() >> 32) & 0xff);
429  }
430  Key GetKey() const
431  {
432  return m_TreeMapNode.GetKey();
433  }
434  static Key ToKey(Type type, StationIndex stationIndex, Id id)
435  {
436  return (static_cast<uint64_t>(type) << 48) | (static_cast<uint64_t>(stationIndex) << 32) | id;
437  }
438 
439 
440  enum State
441  {
442  State_Inactive = 0,
443  State_Active,
444  State_SendingRest,
445  State_SendFinished,
446  State_Ended,
447  State_SendingRestForUnregister,
448  State_SendFinishedForUnregister,
449  State_EndedForUnregister
450  };
451 
452  State GetState() const
453  {
454  return m_State;
455  }
456 
457  CloneProfilerBase* GetSendProfilerPtr()
458  {
459  return m_pSendProfiler;
460  }
461  CloneProfilerBase* GetReceiveProfilerPtr()
462  {
463  return m_pReceiveProfiler;
464  }
465 
466 public:
467  void Startup();
468  void Cleanup();
469  void End();
470  void Unregister();
471  void ClearData();
472 
473  void Enter(StationIndex stationIndex)
474  {
475  OnEnter(stationIndex);
476  }
477  void Exit(StationIndex stationIndex)
478  {
479  OnExit(stationIndex);
480  }
481  void Disconnect(StationIndex stationIndex, bool isValid)
482  {
483  OnDisconnect(stationIndex, isValid);
484  }
485 
486  void UpdateState();
487  bool IsReceiveData() const
488  {
489  return m_State != State_Inactive;
490  }
491 
492  bool IsSendingData(StationIndex stationIndex, bool isDebug = false) const;
493  void TraceSendDataList() const;
494 
495 protected:
496  virtual void OnStartup()
497  {
498  }
499  virtual void OnCleanup()
500  {
501  }
502  virtual void OnEnd()
503  {
504  }
505  virtual void OnSendFinished()
506  {
507  }
508  virtual bool IsEndProcessFinished()
509  {
510  return true;
511  }
512 
513  virtual void OnEnter(StationIndex stationIndex)
514  {
515  (void)stationIndex;
516  }
517  virtual void OnExit(StationIndex stationIndex)
518  {
519  (void)stationIndex;
520  }
521  virtual void OnDisconnect(StationIndex stationIndex, bool isValid)
522  {
523  (void)stationIndex;
524  (void)isValid;
525  }
526  virtual void OnRegister()
527  {
528  }
529 
530 public:
531  virtual bool IsReadyToSetValue() const
532  {
533  return false;
534  }
535  virtual uint32_t GetDestBitmap() const = 0;
536  virtual bool IsInRequest() const
537  {
538  return false;
539  }
540 
541  virtual uint8_t GetLocalRegisterCount() const
542  {
543  return 0;
544  }
545  virtual uint64_t GetRegisterCountAll() const
546  {
547  return 0;
548  }
549  virtual bool IsMatchLocalRegisterCount(uint64_t registerCountAll) const
550  {
551  NN_PIA_UNUSED(registerCountAll);
552  return true;
553  }
554 
555  void AddSendData(CloneElementBase::ISendToken* pToken);
556  void CancelSendData(CloneElementBase::ISendToken* pToken);
557  void ErrorEventDropped();
558 
559 
560 private:
561  typedef common::OffsetList<CloneElementBase::ISendToken> SendDataList;
562  typedef common::OffsetList<CloneElementBase::ResendableSendToken> ResendableDataList;
563 
564 public:
565  class DataTokenAccessor
566  {
567  public:
568  DataTokenAccessor(CloneBase* pClone, SystemTime time, SystemTime resendSpan, bool isUnicast, StationIndex stationIndex);
569  CloneElementBase::ISendToken* Get() const
570  {
571  return m_pToken;
572  }
573  void Reset(bool isUnicast, StationIndex stationIndex, SystemTime resendSpan);
574  void Next();
575  void Commit(uint32_t dispatchCount, uint32_t destBitmap);
576 
577  private:
578  void NextToken();
579  void NextUnicastToken();
580 
581  private:
582  CloneBase* m_pClone;
583  SystemTime m_Time;
584  SystemTime m_ResendSpan;
585  CloneElementBase::ISendToken* m_pToken;
586  bool m_IsUnicast;
587  StationIndex m_TargetStationIndex;
588  uint32_t m_TargetBitmap;
589 
590  enum ListState
591  {
592  ListState_First,
593  ListState_Resend,
594  ListState_End,
595  ListState_NoData,
596  ListState_Comitted
597  };
598  ListState m_ListState;
599  };
600 
601 protected:
602  void AddDataDest(StationIndex stationIndex);
603  void RemoveDataDest(StationIndex stationIndex);
604  void AddDataParticipant(StationIndex stationIndex);
605  void ComplementData(StationIndex stationIndex);
606  void LockData();
607 
608 public:
609  enum CommandType
610  {
611  CommandType_Announce,
612  CommandType_Request,
613  CommandType_End,
614  CommandType_Lock
615  };
616 
617  enum
618  {
619  INVALID_COMMAND_INDEX = 0
620  };
621 
622  class CommandToken
623  {
624  protected:
625  explicit CommandToken(CloneBase* pClone)
626  : m_ListNode(), m_pClone(pClone), m_LastSendTime(InvalidSystemTime)
627  {
628  }
629 
630  public:
631  bool IsInList() const
632  {
633  return m_ListNode.IsFreeListNode() == false;
634  }
635  virtual CommandType GetType() const = 0;
636  virtual uint32_t GetDestStationBitmap() const = 0;
637  Id GetCloneId() const
638  {
639  return m_pClone->GetId();
640  }
641  SystemTime GetLastSendTime(StationIndex stationIndex) const
642  {
643  if (stationIndex == StationIndex_Invalid)
644  {
645  return m_LastSendTime;
646  }
647  else
648  {
649  PIA_ASSERT(IsUnicast());
650  PIA_ASSERT(stationIndex < MaxStationNum);
651  return m_LastSendTimeArray[stationIndex];
652  }
653  }
654  void SetLastSendTime(SystemTime time, StationIndex stationIndex)
655  {
656  if (stationIndex == StationIndex_Invalid)
657  {
658  m_LastSendTime = time;
659  }
660  else
661  {
662  PIA_ASSERT(IsUnicast());
663  PIA_ASSERT(stationIndex < MaxStationNum);
664  m_LastSendTimeArray[stationIndex] = time;
665  }
666  }
667  const CloneBase* GetClone() const
668  {
669  return m_pClone;
670  }
671  static int32_t GetListNodeOffset()
672  {
673  NN_PIA_PRAGMA_PUSH_WARNINGS
674  NN_PIA_DISABLE_WARNING_CLANG_INVALID_OFFSETOF
675  return offsetof(CommandToken, m_ListNode);
676  NN_PIA_PRAGMA_POP_WARNINGS
677  }
678  CloneBase* GetClonePtr()
679  {
680  return m_pClone;
681  }
682  // 再送をユニキャストで行うトークンクラスでオーバーライドし、true を返すようにする
683  virtual bool IsUnicast() const
684  {
685  return false;
686  }
687 
688  private:
689  common::ListNode m_ListNode;
690  CloneBase* m_pClone;
691  SystemTime m_LastSendTime;
692  SystemTime m_LastSendTimeArray[MaxStationNum];
693  };
694 
695 
696  class ClockCommandToken : public CommandToken
697  {
698  protected:
699  ClockCommandToken(CloneBase* pClone)
700  : CommandToken(pClone)
701  {
702  }
703 
704  public:
705  virtual ClockValue GetClock() const = 0;
706  };
707 
708 
709  class DataToken
710  {
711  public:
712  explicit DataToken(CloneBase* pClone)
713  : m_ListNode(), m_pClone(pClone)
714  {
715  }
716  bool IsInList() const
717  {
718  return m_ListNode.IsFreeListNode() == false;
719  }
720  CloneBase* GetClone()
721  {
722  return m_pClone;
723  }
724  bool IsReadyToEraseFromList() const
725  {
726  return m_pClone->IsSendDataEmpty();
727  }
728  static int32_t GetListNodeOffset()
729  {
730  NN_PIA_PRAGMA_PUSH_WARNINGS
731  NN_PIA_DISABLE_WARNING_CLANG_INVALID_OFFSETOF
732  return offsetof(DataToken, m_ListNode);
733  NN_PIA_PRAGMA_POP_WARNINGS
734  }
735 
736  private:
737  common::ListNode m_ListNode;
738  CloneBase* m_pClone;
739  };
740 
741 protected:
742  CloneProtocol* GetProtocolPtr()
743  {
744  return m_pProtocol;
745  }
746 
747  void RequestInitialData();
748 
749 
750 protected:
751  bool IsSendDataEmpty() const
752  {
753  return m_SendDataList.IsEmpty() && m_ResendDataList.IsEmpty();
754  }
755 
756 private:
757  common::TreeMapNode<Key> m_TreeMapNode;
758  CloneProtocol* m_pProtocol;
759 
760  State m_State;
761 
762  typedef common::OffsetTreeMap<CloneElementBase::Id, CloneElementBase> ElementCollection;
763  ElementCollection m_ElementCollection;
764 
765 
766  SendDataList m_SendDataList;
767  ResendableDataList m_ResendDataList;
768 
769  DataToken m_DataToken;
770 
771 private:
772  CloneProfilerBase* m_pSendProfiler;
773  CloneProfilerBase* m_pReceiveProfiler;
774 
775 public:
776  template <int TEST_ID, typename Arg>
777  static void Test(const CloneBase& obj, Arg* pArg = NULL);
778 
779 private:
780  // n2920: クライアント監視機能用
781  void SetElementNumToMonitoringData();
782 
783  NN_PIA_DISALLOW_COPY(CloneBase);
784  //! @endcond
785 };
786 }
787 }
788 } // end of namespace nn::pia::clone