CTR-Pia  5.4.3
Game Communication Engine
 全て クラス ネームスペース 関数 変数 型定義 列挙型 列挙型の値 ページ
clone_CloneProtocol.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/common/common_PacketDefine.h>
17 #include <nn/pia/common/common_OffsetTreeMap.h>
18 #include <nn/pia/common/common_OffsetList.h>
19 #include <nn/pia/transport/transport_Protocol.h>
20 #include <nn/pia/clone/clone_Definitions.h>
21 #include <nn/pia/clone/clone_SendClone.h>
22 #include <nn/pia/clone/clone_ReceiveClone.h>
23 #include <nn/pia/clone/clone_AtomicSharingClone.h>
24 #include <nn/pia/clone/clone_SequentialSharingClone.h>
25 
26 namespace nn
27 {
28 namespace pia
29 {
30 namespace clone
31 {
32 
33 class Clock;
34 class IDataPacker;
35 class IDataUnpacker;
36 class CompressDataUnpacker;
37 
38 
39 /*!
40  @brief ステーション間で値の共有を行うためのプロトコルです。<br/>
41  */
43 {
44 public:
45  PIA_PROTOCOL_TYPE_INFO(nn::pia::transport::ProtocolTypeClone);
46 
47  /*!
48  @cond PRIVATE
49  @brief デフォルトコンストラクタです。
50  */
51  CloneProtocol();
52  //! @endcond
53 
54 
55  /*!
56  @cond PRIVATE
57  @brief デストラクタです。
58  */
59  virtual ~CloneProtocol();
60  //! @endcond
61 
62 
63  /*!
64  @brief 順序比較関数です。
65  @param[in] clock 比較を行う時刻です。
66  @param[in] stationA 比較対象のステーションの @ref StationIndex です。
67  @param[in] stationB 比較対象のステーションの @ref StationIndex です。
68  @return 時刻が clock の時に stationA より stationB の方が前に起こったと扱う場合は負の値を、
69  後に起こったと扱う場合は正の値を返します。
70  @details stationA と stationB が同じ値で呼び出されることはありません。
71  @details この関数は、ある時刻において順序関係が矛盾しないようになっている必要があります。
72  例えば、 ClockPriorityJudgeFunction(clock, stationA, stationB) < 0 であるならば、
73  ClockPriorityJudgeFunction(clock, stationB, stationA) > 0 とならなければなりません。
74  また、 ClockPriorityJudgeFunction(clock, stationA, stationB) < 0 かつ ClockPriorityJudgeFunction(clock, stationB, stationC) < 0 であるならば
75  ClockPriorityJudgeFunction(clock, stationA, statoinC) < 0 とならなければなりません。
76  @details ただし、別の時刻においては順序関係が一致しなくても構いません。
77  すなわち、ClockPriorityJudgeFunction(clock1, stationA, stationB) < 0 である場合に、
78  ClockPriorityJudgeFunction(clock2, stationA, stationB) > 0 となることは問題ありません。
79  */
80  typedef int (*ClockPriorityJudgeFunction)(ClockValue clock, StationIndex stationA, StationIndex stationB);
81 
82 
83  static const uint32_t CompressionLevelNone = 0; //!< @ref CloneProtocol::Setting::dataCompressionLevel で指定する送信データの圧縮レベル(圧縮なし)です。
84  static const uint32_t CompressionLevelLow = 1; //!< @ref CloneProtocol::Setting::dataCompressionLevel で指定する送信データの圧縮レベル(速度重視)です。
85  static const uint32_t CompressionLevelMiddle = 5; //!< @ref CloneProtocol::Setting::dataCompressionLevel で指定する送信データの圧縮レベルです。
86  static const uint32_t CompressionLevelHigh = 9; //!< @ref CloneProtocol::Setting::dataCompressionLevel で指定する送信データの圧縮レベル(圧縮率重視)です。
87 
88  /*!
89  @brief 初期化時に指定する設定構造体です。
90  @details 通信するステーション間で同じ値を指定する必要があります。
91  */
92  struct Setting
93  {
94  public:
95  /*!
96  @brief デフォルトコンストラクタです。
97  @details デフォルト値で初期化されます。
98  */
101  clockPerSec(1000.0f),
102  clockPerFrame(1),
103  clockRegulationRate(0.1f),
107  ackBufferNum(32)
108  {
109  }
110 
111 
112  /*!
113  @brief 何を基準として時刻を進めるかを表します。
114  */
116  {
117  ClockType_Rtc = 0, //!< RTC を基準に時刻を進めます。
118  ClockType_Frame //!< CloneProtocol::UpdateClock() の呼び出し回数を基準に時刻を進めます。
119  };
120 
121 
122  /*!
123  @brief 時刻を進める基準を指定します。
124  @details @ref CloneProtocol::Setting::ClockType_Rtc を指定した場合は、RTC を基準に時刻を進めます。
125  開始時に時刻調整がされた後はステーション間で時刻がずれることを考慮する必要はありませんが、
126  CloneProtocol::UpdateClock() の呼び出しのタイミングによって、1 フレームあたりに進む時刻が一定ではなくなります。
127  時刻を進める速さを clockPerSec で指定する必要があります。
128  @details @ref CloneProtocol::Setting::ClockType_Frame を指定した場合は、通常は CloneProtocol::UpdateClock() 呼び出しあたりに進む時刻の値が一定になります。
129  ただし、処理落ちなどで CloneProtocol::UpdateClock() の呼び出し回数がステーション間でずれた場合に、
130  ステーション間で時刻が一致しなくなる可能性があります。
131  時刻を進める速さを clockPerFrame で指定する必要があります。
132  @details 時刻管理の詳細についてはプログラミングマニュアルを参照してください。
133  @see clockPerSec
134  @see clockPerFrame
135  */
137 
138 
139  /*!
140  @brief 1 秒あたりに進める時刻の値を指定します。
141  @details @ref CloneProtocol::Setting::clockType に @ref CloneProtocol::Setting::ClockType_Rtc 以外を指定した場合は、この設定は無視されます。
142  @see clockType
143  */
144  float clockPerSec;
145 
146 
147  /*!
148  @brief 1 フレームあたりに進める時刻の値を指定します。
149  @details @ref CloneProtocol::Setting::clockType に @ref CloneProtocol::Setting::ClockType_Frame 以外を指定した場合は、この設定は無視されます。
150  @see clockType
151  */
152  uint32_t clockPerFrame;
153 
154 
155  /*!
156  @brief 時刻の再調整を行う際に、時刻の進め方を加速/減速する割合を指定します。
157  @details CloneProtocol::RegulateClock() で時刻を再調整する際、ここで指定した割合だけ通常時の時刻の進み方より速く/遅く時刻を進めます。
158  例えば 0.1 を指定した場合、他のステーションより時刻が遅れている場合は、通常時と比べ 110% の速さで時刻が進みます。
159  逆に他のステーションより時刻が進んでいる場合は、通常時と比べ 90% の速さで時刻が進みます。
160  */
162 
163 
164  /*!
165  @brief 別のステーション間で同時刻に起こった事柄を、どちらが先に起こった事として扱うかを判定する方法を表します。
166  */
168  {
169  ClockPriorityJudgeMethod_Simple = 0, //!< ステーション ID の値の小さいステーションで起こった事柄の方が先として扱います。
170  ClockPriorityJudgeMethod_Impartial, //!< 時刻ごとに優先順を変えることにより、長期的にはステーション間で有利不利が出ないように判定します。
171  ClockPriorityJudgeMethod_UserDefine //!< 判定方法をアプリケーションで指定します。
172  };
173 
174 
175  /*!
176  @brief 別のステーション間で同時刻に起こった事柄を、どちらが先に起こった事として扱うかを判定する方法を指定します。
177  @details @ref CloneProtocol::Setting::ClockPriorityJudgeMethod_UserDefine を指定した場合は、判定関数を @ref CloneProtocol::Setting::clockPriorityJudgeFunction に指定する必要があります。
178  @see clockPriorityJudgeFunction
179  */
181 
182 
183  /*!
184  @brief 別のステーション間で同時刻に起こった事柄を、どちらが先に起こった事として扱うかを判定する関数を指定します。
185  @details @ref CloneProtocol::Setting::clockPriorityJudgeMethod に @ref CloneProtocol::Setting::ClockPriorityJudgeMethod_UserDefine 以外を指定した場合は、この設定は無視されます。
186  @see clockPriorityJudgeMethod;
187  */
189 
190 
191  /*!
192  @brief 送信データの圧縮レベルを指定します。
193  @details @ref CloneProtocol::CompressionLevelNone を指定すると圧縮を行いません。
194  @ref CloneProtocol::CompressionLevelLow が速度重視、@ref CloneProtocol::CompressionLevelHigh が圧縮率重視となります。
195  @ref CloneProtocol::CompressionLevelMiddle はその中間です。
196  デフォルト値は @ref CloneProtocol::CompressionLevelNone です。
197  これらの値以外はサポート対象外です。
198  プラットフォームの CPU 性能によって処理時間が大きく変動します。
199  */
201 
202 
203  /*!
204  @brief Ack 用バッファの数を指定します。
205  @details バッファ 1 個につき、約 1.5 KB のメモリを消費します。1 以上の値を指定する必要があります。実際に通信中に使用されたバッファの数の最大値は、@ref CloneProtocol::GetAckBufferUsedNumMax() で取得できます。
206  @see GetAckBufferUsedNumMax
207  */
209  };
210 
211 
212  /*!
213  @brief 初期化します。 clone::BeginSetup() ~ clone::EndSetup() 間で呼び出す必要があります。
214  @param[in] setting 各種設定情報です。
215  すべてのステーション間で、同じ値を設定する必要があります。異なる値を設定した場合の動作は不定です。
216  @return 成功すれば、IsSuccess() が true を返す Result が返されます。この関数がエラーを返さないようにアプリケーションを実装する必要があります。
217  @retval ResultAlreadyInitialized 既に初期化されています。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
218  @retval ResultInvalidArgument 引数が不正です。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
219  @see Finalize
220  */
221  Result Initialize(const Setting& setting);
222 
223 
224  /*!
225  @brief 終了処理を行います。
226  @see Initialize
227  */
228  void Finalize();
229 
230 
231  /*!
232  @brief 使用するクローンエレメントの SerializePolicy::GetSerializedSize() で定義できる値の最大値を取得します。
233  @details この値より大きなクローンエレメントを登録してあるクローンを RegisterXXXClone() に渡すと、 @ref ResultInvalidArgument が返ります。
234  @details この値は 1 パケットに収めることのできる最大サイズです。
235  使用する通信モジュールやそこで設定する MTU の設定によって値が変わります。
236  この値は、CloneProtocol::Initialize() 以降取得することができます。
237  @return 使用するクローンエレメントの SerializePolicy::Size で指定できる値の最大値です。
238  */
239  uint32_t GetElementSizeMax() const
240  {
241  return m_ElementSizeMax;
242  }
243 
244 
245  /*!
246  @brief SendClone を指定の ID に登録します。
247  @param[in] pClone 登録する SendClone です。
248  @param[in] cloneId 登録する ID です。
249  @return 成功すれば、IsSuccess() が true を返す Result が返されます。
250  @retval ResultNotInitialized 初期化されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
251  @retval ResultInvalidArgument 引数が不正です。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
252  @retval ResultAlreadyExists 指定された ID には既に登録されています。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
253  */
255  {
256  return RegisterClone(SendClone::ToKey(cloneId), pClone);
257  }
258 
259 
260  /*!
261  @brief SendClone を登録解除します。
262  @details 送信途中のものがある場合は送信しきってから登録解除されます。
263  そのため、この関数が成功したとしても pClone->@ref SendClone::IsRegisteredWithProtocol() "IsRegisteredWithProtocol()" が
264  false になるまで pClone を使いまわしたり同じ ID に再登録したりできません。
265  @param[in] pClone 登録解除する SendClone です。
266  @return 成功すれば、IsSuccess() が true を返す Result が返されます。この関数がエラーを返さないようにアプリケーションを実装する必要があります。
267  @retval ResultNotInitialized 初期化されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
268  @retval ResultInvalidArgument 引数が不正です。この CloneProtocol に登録されていない SendClone が指定されています。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
269  */
271  {
272  return UnregisterClone(pClone);
273  }
274 
275 
276  /*!
277  @brief SendClone を登録解除します。
278  @details 送信途中のものがある場合は送信しきってから登録解除されます。
279  そのため、この関数が成功したとしても登録解除した SendClone::IsRegisteredWithProtocol() が false になるまで
280  その SendClone を使いまわしたり同じ ID に再登録したりできません。
281  @param[in] cloneId 登録解除する SendClone の ID です。
282  @return 成功すれば、IsSuccess() が true を返す Result が返されます。
283  @retval ResultNotInitialized 初期化されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
284  @retval ResultNotSet 指定された ID には登録されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
285  */
287  {
288  return UnregisterClone(SendClone::ToKey(cloneId));
289  }
290 
291 
292  /*!
293  @brief 指定した ID の SendClone を検索して取得します。
294  @param[in] cloneId 検索する SendClone の ID です。
295  @return 指定された ID の SendClone です。指定した ID のものが無い場合は、NULL を返します。
296  */
298  {
299  return static_cast<SendClone*>(m_CloneCollection.Find(SendClone::ToKey(cloneId)));
300  }
301 
302 
303  /*!
304  @brief 指定した ID の SendClone を検索して取得します。
305  @param[in] cloneId 検索する SendClone の ID です。
306  @return 指定された ID の SendClone です。指定した ID のものが無い場合は、NULL を返します。
307  */
309  {
310  return static_cast<const SendClone*>(m_CloneCollection.Find(SendClone::ToKey(cloneId)));
311  }
312 
313 
314  /*!
315  @brief ReceiveClone を指定の ID に登録します。
316  @param[in] pClone 登録する ReceiveClone です。
317  @param[in] sendStationIndex 送信側の SendClone のある @ref StationIndex です。
318  @param[in] cloneId 登録する ID です。
319  @return 成功すれば、IsSuccess() が true を返す Result が返されます。
320  @retval ResultNotInitialized 初期化されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
321  @retval ResultInvalidArgument 引数が不正です。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
322  @retval ResultAlreadyExists 指定された ID には既に登録されています。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
323  */
324  Result RegisterReceiveClone(ReceiveClone* pClone, StationIndex sendStationIndex, CloneBase::Id cloneId);
325 
326 
327  /*!
328  @brief ReceiveClone を登録解除します。
329  @details 送信途中のものがある場合は送信しきってから登録解除されます。
330  そのため、この関数が成功したとしても pClone->@ref ReceiveClone::IsRegisteredWithProtocol() "IsRegisteredWithProtocol()" が
331  false になるまで pClone を使いまわしたり同じ ID に再登録したりできません。
332  (ステーションの不正切断時の代理送信等のため ReceiveClone も送信を行う事があります。)
333  @param[in] pClone 登録解除する ReceiveClone です。
334  @return 成功すれば、IsSuccess() が true を返す Result が返されます。この関数がエラーを返さないようにアプリケーションを実装する必要があります。
335  @retval ResultNotInitialized 初期化されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
336  @retval ResultInvalidArgument 引数が不正です。この CloneProtocol に登録されていない ReceiveClone が指定されています。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
337  */
339  {
340  return UnregisterClone(pClone);
341  }
342 
343 
344  /*!
345  @brief ReceiveClone を登録解除します。
346  @details 送信途中のものがある場合は送信しきってから登録解除されます。
347  そのため、この関数が成功したとしても登録解除した ReceiveClone::IsRegisteredWithProtocol() が false になるまで
348  その ReceiveClone を使いまわしたり同じ ID に再登録したりできません。
349  (ステーションの不正切断時の代理送信等のため ReceiveClone も送信を行う事があります。)
350  @param[in] sendStationIndex 送信側の SendClone のある @ref StationIndex です。
351  @param[in] cloneId 登録解除する ReceiveClone の ID です。
352  @return 成功すれば、IsSuccess() が true を返す Result が返されます。
353  @retval ResultNotInitialized 初期化されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
354  @retval ResultInvalidArgument 引数が不正です。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
355  @retval ResultNotSet 指定された ID には登録されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
356  */
357  Result UnregisterReceiveClone(StationIndex sendStationIndex, CloneBase::Id cloneId);
358 
359 
360  /*!
361  @brief 指定した ID の ReceiveClone を検索して取得します。
362  @param[in] sendStationIndex 送信側の SendClone のある @ref StationIndex です。
363  @param[in] cloneId 検索する ReceiveClone の ID です。
364  @return 指定された ID の ReceiveClone です。指定した ID のものが無い場合は、NULL を返します。
365  */
366  ReceiveClone* SearchReceiveClone(StationIndex sendStationIndex, CloneBase::Id cloneId);
367 
368 
369  /*!
370  @brief 指定した ID の ReceiveClone を検索して取得します。
371  @param[in] sendStationIndex 送信側の SendClone のある @ref StationIndex です。
372  @param[in] cloneId 検索する ReceiveClone の ID です。
373  @return 指定された ID の ReceiveClone です。指定した ID のものが無い場合は、NULL を返します。
374  */
375  const ReceiveClone* SearchReceiveClone(StationIndex sendStationIndex, CloneBase::Id cloneId) const;
376 
377 
378  /*!
379  @brief AtomicSharingClone を指定の ID に登録します。
380  @param[in] pClone 登録する AtomicSharingClone です。
381  @param[in] cloneId 登録する ID です。
382  @return 成功すれば、IsSuccess() が true を返す Result が返されます。
383  @retval ResultNotInitialized 初期化されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
384  @retval ResultInvalidArgument 引数が不正です。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
385  @retval ResultAlreadyExists 指定された ID には既に登録されています。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
386  */
388  {
389  return RegisterClone(AtomicSharingClone::ToKey(cloneId), pClone);
390  }
391 
392 
393  /*!
394  @brief AtomicSharingClone を登録解除します。
395  @details 送信途中のものがある場合は送信しきってから登録解除されます。
396  そのため、この関数が成功したとしても pClone->@ref AtomicSharingClone::IsRegisteredWithProtocol() "IsRegisteredWithProtocol()" が
397  false になるまで pClone を使いまわしたり同じ ID に再登録したりできません。
398  (ステーションの不正切断時の代理送信等のため、送信権を取得していなくても送信を行う事があります。)
399  @param[in] pClone 登録解除する AtomicSharingClone です。
400  @return 成功すれば、IsSuccess() が true を返す Result が返されます。この関数がエラーを返さないようにアプリケーションを実装する必要があります。
401  @retval ResultNotInitialized 初期化されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
402  @retval ResultInvalidArgument 引数が不正です。この CloneProtocol に登録されていない AtomicSharingClone が指定されています。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
403  */
405  {
406  return UnregisterClone(pClone);
407  }
408 
409 
410  /*!
411  @brief AtomicSharingClone を登録解除します。
412  @details 送信途中のものがある場合は送信しきってから登録解除されます。
413  そのため、この関数が成功したとしても登録解除した AtomicSharingClone::IsRegisteredWithProtocol() が false になるまで
414  その AtomicSharingClone を使いまわしたり同じ ID に再登録したりできません。
415  (ステーションの不正切断時の代理送信等のため、送信権を取得していなくても送信を行う事があります。)
416  @param[in] cloneId 登録解除する AtomicSharingClone の ID です。
417  @return 成功すれば、IsSuccess() が true を返す Result が返されます。
418  @retval ResultNotInitialized 初期化されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
419  @retval ResultNotSet 指定された ID には登録されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
420  */
422  {
423  return UnregisterClone(AtomicSharingClone::ToKey(cloneId));
424  }
425 
426 
427  /*!
428  @brief 指定した ID の AtomicSharingClone を検索して取得します。
429  @param[in] cloneId 検索する AtomicSharingClone の ID です。
430  @return 指定された ID の AtomicSharingClone です。指定した ID のものが無い場合は、NULL を返します。
431  */
433  {
434  return static_cast<AtomicSharingClone*>(m_CloneCollection.Find(AtomicSharingClone::ToKey(cloneId)));
435  }
436 
437 
438  /*!
439  @brief 指定した ID の AtomicSharingClone を検索して取得します。
440  @param[in] cloneId 検索する AtomicSharingClone の ID です。
441  @return 指定された ID の AtomicSharingClone です。指定した ID のものが無い場合は、NULL を返します。
442  */
444  {
445  return static_cast<const AtomicSharingClone*>(m_CloneCollection.Find(AtomicSharingClone::ToKey(cloneId)));
446  }
447 
448 
449  /*!
450  @brief SequentialSharingClone を指定の ID に登録します。
451  @param[in] pClone 登録する SequentialSharingClone です。
452  @param[in] cloneId 登録する ID です。
453  @return 成功すれば、IsSuccess() が true を返す Result が返されます。
454  @retval ResultNotInitialized 初期化されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
455  @retval ResultInvalidArgument 引数が不正です。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
456  @retval ResultAlreadyExists 指定された ID には既に登録されています。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
457  */
459  {
460  return RegisterClone(SequentialSharingClone::ToKey(cloneId), pClone);
461  }
462 
463 
464  /*!
465  @brief SequentialSharingClone を登録解除します。
466  @details 送信途中のものがある場合は送信しきってから登録解除されます。
467  そのため、この関数が成功したとしても pClone->@ref SequentialSharingClone::IsRegisteredWithProtocol() "IsRegisteredWithProtocol()" が
468  false になるまで pClone を使いまわしたり同じ ID に再登録したりできません。
469  @param[in] pClone 登録解除する SequentialSharingClone です。
470  @return 成功すれば、IsSuccess() が true を返す Result が返されます。この関数がエラーを返さないようにアプリケーションを実装する必要があります。
471  @retval ResultNotInitialized 初期化されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
472  @retval ResultInvalidArgument 引数が不正です。この CloneProtocol に登録されていない AtomicSharingClone が指定されています。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
473  */
475  {
476  return UnregisterClone(pClone);
477  }
478 
479 
480  /*!
481  @brief SequentialSharingClone を登録解除します。
482  @details 送信途中のものがある場合は送信しきってから登録解除されます。
483  そのため、この関数が成功したとしても登録解除した SequentialSharingClone::IsRegisteredWithProtocol() が false になるまで
484  その SequentialSharingClone を使いまわしたり同じ ID に再登録したりできません。
485  @param[in] cloneId 登録解除する SequentialSharingClone の ID です。
486  @return 成功すれば、IsSuccess() が true を返す Result が返されます。
487  @retval ResultNotInitialized 初期化されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
488  @retval ResultNotSet 指定された ID には登録されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
489  */
491  {
492  return UnregisterClone(SequentialSharingClone::ToKey(cloneId));
493  }
494 
495 
496  /*!
497  @brief 指定した ID の SequentialSharingClone を検索して取得します。
498  @param[in] cloneId 検索する SequentialSharingClone の ID です。
499  @return 指定された ID の SequentialSharingClone です。指定した ID のものが無い場合は、NULL を返します。
500  */
502  {
503  return static_cast<SequentialSharingClone*>(m_CloneCollection.Find(SequentialSharingClone::ToKey(cloneId)));
504  }
505 
506 
507  /*!
508  @brief 指定した ID の SequentialSharingClone を検索して取得します。
509  @param[in] cloneId 検索する SequentialSharingClone の ID です。
510  @return 指定された ID の SequentialSharingClone です。指定した ID のものが無い場合は、NULL を返します。
511  */
513  {
514  return static_cast<const SequentialSharingClone*>(m_CloneCollection.Find(SequentialSharingClone::ToKey(cloneId)));
515  }
516 
517 
518  /*!
519  @cond PRIVATE
520  @brief 通信を開始します。
521 
522  @param[in] localStationAddress 自分の StationAddress です。
523 
524  @return 成功すれば、IsSuccess() が true を返す Result が返されます。
525 
526  @retval ResultNotInitialized 初期化されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
527  @retval ResultInvalidState 既に通信中です。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
528  @retval ResultInvalidArgument 引数が誤っています。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
529  */
530  virtual Result StartupWithStationAddress(const common::StationAddress& localStationAddress);
531  //! @endcond
532 
533 
534  /*!
535  @cond PRIVATE
536  @brief 通信を終了します。
537  */
538  virtual void CleanupWithStationAddress();
539  //! @endcond
540 
541 
542  /*!
543  @cond PRIVATE
544  @brief メインの処理です。
545 
546  @return ResultSuccess が返されます。
547  */
548  virtual Result Dispatch();
549  //! @endcond
550 
551 
552  /*!
553  @cond PRIVATE
554  @brief 接続状態の切り替え。
555 
556  @param[in] event 操作内容を表すイベントです。
557 
558  @return 成功すれば、IsSuccess() が true を返す Result が返されます。
559 
560  @retval ResultInvalidState 呼び出し状態が不正です。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
561  @retval ResultInvalidArgument 引数が誤っています。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
562  */
563  virtual Result UpdateProtocolEvent(const transport::ProtocolEvent& event);
564  //! @endcond
565 
566 
567  /*!
568  @brief CloneProtocol の動作状態を表します。
569  */
570  enum State
571  {
572  State_Inactive = 0x10, //!< 動作中ではありません。
573  State_Start = 0x20, //!< 開始処理中です。
574  State_Active = 0x30, //!< 動作中です。
575  State_Stop = 0x40 //!< 終了処理中です。
576  };
577 
578 
579  /*!
580  @brief 現在の動作状態を取得します。
581  @return 現在の動作状態です。
582  */
583  State GetState() const
584  {
585  return static_cast<State>(m_InnerState & StateMask);
586  }
587 
588 
589  /*!
590  @brief 指定したステーションの CloneProtocol が動作中かどうかを判定します。
591  @param[in] stationId 動作中かどうかを調べたいステーションの @ref StationId です。
592  @return 指定したステーションが動作中なら true を返します。
593  */
594  bool IsActiveStation(StationId stationId) const;
595 
596 
597  /*!
598  @brief CloneProtocol の動作を開始します。
599  @details 通信開始後、@ref CloneProtocol::State_Inactive の時に呼び出すことができます。
600  成功すると @ref CloneProtocol::State_Start に遷移して開始処理を行った後、 @ref CloneProtocol::State_Active に遷移します。
601  この呼び出し以降、定期的に CloneProtocol::UpdateClock() を呼ぶ必要があります。
602  @return 成功すれば、IsSuccess() が true を返す Result が返されます。この関数がエラーを返さないようにアプリケーションを実装する必要があります。
603  @retval ResultInvalidState 通信中でないか、@ref nn::pia::clone::CloneProtocol::State_Inactive "State_Inactive" ではありません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
604  */
605  Result Start();
606 
607 
608  /*!
609  @brief CloneProtocol の動作を終了します。
610  @details @ref CloneProtocol::State_Start または @ref CloneProtocol::State_Active の時に呼び出すと @ref CloneProtocol::State_Stop に遷移し、終了処理の完了後に @ref CloneProtocol::State_Inactive に遷移します。
611  @ref CloneProtocol::State_Stop の間は、まだ CloneProtocol::UpdateClock() を呼び続ける必要があります。
612  @ref CloneProtocol::State_Inactive, @ref CloneProtocol::State_Stop の時に呼び出しても何も起こりません。
613  @return 成功すれば、IsSuccess() が true を返す Result が返されます。この関数がエラーを返さないようにアプリケーションを実装する必要があります。
614  @retval ResultInvalidState 通信中ではありません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
615  */
616  Result Stop();
617 
618 
619  /*!
620  @brief 時刻を 1 フレーム進めます。
621  @details この関数を呼びだした時だけ CloneProtocol の管理する時刻は進みます。
622  @ref CloneProtocol::State_Start, @ref CloneProtocol::State_Active, @ref CloneProtocol::State_Stop のいずれかの間は定期的に呼び出す必要があります。
623  呼び出しに対してどれだけの時刻が進むかは、CloneProtocol::Initialize() 時に指定する CloneProtocol::Setting で指定する必要があります。
624  時刻の値の精度に対して呼び出し間隔が短い場合は時刻が変わらない場合がありますが、遡ることはありません。
625  @see GetClock
626  */
627  void UpdateClock();
628 
629 
630  /*!
631  @brief 現在の時刻を取得します。
632  @return 現在の時刻です。動作中でない時など有効な時刻が存在しない場合は @ref InvalidClock を返します。
633  @see UpdateClock
634  */
635  ClockValue GetClock() const;
636 
637 
638  /*!
639  @brief 時刻の再調整を開始します。
640  @details このステーションの CloneProtocol の管理する時刻を、他のステーションの平均的な時刻にそろえるように再調整します。
641  他のステーションの時刻を調べた後、通常より高速/低速に時刻を進めることにより誤差を修正します。
642  どの程度高速/低速に進めるかは CloneProtocol::Initialize() 時に指定する CloneProtocol::Setting::clockRegulationRate で指定する必要があります。
643  @ref CloneProtocol::Setting::clockType に @ref CloneProtocol::Setting::ClockType_Rtc を指定した場合は、同期通信を長時間継続していると、端末間の時刻のずれが 10 時間で数秒程度大きくなる可能性があります。長時間の同期通信を行う場合は、この関数を定期的に呼び出すことを検討してください。
644  @return 成功すれば、IsSuccess() が true を返す Result が返されます。この関数がエラーを返さないようにアプリケーションを実装する必要があります。
645  @retval ResultInvalidState @ref nn::pia::clone::CloneProtocol::State_Active "State_Active" でないか、既に調整を実行中です。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
646  @see IsRegulatingClock
647  */
649 
650 
651  /*!
652  @brief 時刻の調整を実行中かどうかを取得します。
653  @return 時刻の調整を実行中なら true を返します。
654  @see RegulateClock
655  */
656  bool IsRegulatingClock() const;
657 
658 
659  /*!
660  @brief (デバッグ用)時刻の値がオーバーフローするまでの期間を設定します。
661 
662  @details 同期通信を開始してから、時刻の値がオーバーフローするまでの期間を設定します。
663  @details 本関数はデバッグ用です。製品には組み込まないよう、注意してください。
664 
665  @param[in] span @ref CloneProtocol::Setting::ClockType が @ref CloneProtocol::Setting::ClockType_Rtc の場合は、時間(単位は秒)、@ref CloneProtocol::Setting::ClockType_Frame の場合は、フレーム数です。
666  @return 成功すれば、IsSuccess() が true を返す Result が返されます。この関数がエラーを返さないようにアプリケーションを実装する必要があります。
667  @retval ResultNotInitialized 初期化されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
668  */
669  Result SetClockOverFlowSpanForDebug(uint32_t span);
670 
671 
672  /*!
673  @brief @ref CloneProtocol::SetSendPeriod() で指定した送信間隔の設定値を取得します。
674 
675  @return 送信間隔の設定値です。
676  */
677  uint32_t GetSendPeriod() const
678  {
679  return m_SendPeriod;
680  }
681 
682 
683  /*!
684  @brief 送信間隔を設定します。
685  @details ここで指定した回数 @ref CloneProtocol::UpdateClock() が呼び出されるたびに、@ref common::Scheduler::Dispatch() 呼び出し時に送信処理が行われます。1 以上の値を指定する必要があります。
686 
687  @param[in] sendPeriod 設定する送信間隔です。
688  @return 成功すれば、IsSuccess() が true を返す Result が返されます。
689  @retval ResultInvalidArgument 引数が不正です。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
690  */
691  Result SetSendPeriod(uint32_t sendPeriod);
692 
693 
694  /*!
695  @brief エラーの発生状態を表します。
696  */
698  {
699  ErrorType_Nothing = 0, //!< エラーはありません。
700  ErrorType_EventDropped, //!< イベントの管理に不整合が生じました。一部のイベントが通知されなかった可能性があります。
701  //!< EventCloneElement を使用していた場合に発生する可能性があります。
702  ErrorType_ClockOverflow //!< 時刻の値がオーバーフローしました。全体的に値の不整合が起こっている可能性があります。
703  };
704 
705 
706  /*!
707  @brief エラーの発生状態を取得します。
708  @details エラーが発生した場合は、送受信している値に不整合が起こっている可能性がありますので、
709  ゲームを無効として CloneProtocol::Stop() で終了させることを推奨します。
710  再び CloneProtocol::Start() を呼び出した際にこの値はリセットされます。
711  複数の種類のエラーが発生した場合は、@ref CloneProtocol::ErrorType の値の大きい方が優先されます。
712  @return エラーの発生状態です。
713  */
715  {
716  return m_Error;
717  }
718 
719 
720  /*!
721  @brief 計測して求めた基準となる RTT(ミリ秒) に対する再送間隔の比率を指定します。
722  @details RTT に対する再送間隔の比率のデフォルト値は 1.25 です。再送間隔は、(RTT * rttRatio + (送信間隔 + 1) * 1 フレームに相当する時間) となります。1 フレームに相当する時間は、@ref CloneProtocol::UpdateClock() の呼び出し間隔に基づいて内部で計測されます。再送間隔の最大値は、2500 ms です。
723  @param[in] rttRatio 計測して求めた基準となる RTT(ミリ秒) に対する、再送間隔の比率です。0 より大きい値を指定する必要があります。
724  @return 成功すれば、IsSuccess() が true を返す Result が返されます。この関数がエラーを返さないようにアプリケーションを実装する必要があります。
725  @retval ResultNotInitialized 初期化されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
726  @retval ResultInvalidArgument 引数が誤っています。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
727  */
728  Result SetResendSpanRatio(float rttRatio);
729 
730 
731  //! @name プロファイリング
732  //! @{
733 
734  /*!
735  @brief 送受信のプロファイリング管理オブジェクトを設定します。
736  @details CloneProfiler を設定すると、 CloneProtocol が行った送受信をプロファイリングできます。
737  ここでの計測は、この CloneProtocol が実際に通信路に送信し、通信路から受信したものが計上されます。
738  クローンのプロファイリングでは自ステーション内での送受信も計上されますが、
739  それらは CloneProtocol 内で解決されるため、 CloneProtocol でのプロファイリングには計上されません。
740  @details 圧縮を有効にしていた場合、計測されるサイズは圧縮された状態でのサイズです。
741  @details 引数に NULL を指定すると、既に設定してある CloneProfiler を解除する事ができます。
742  @param[in] pSendProfiler 送信のプロファイリングを管理する CloneProfiler を指定します。
743  必要ない場合は NULL を指定する必要があります。
744  @param[in] pReceiveProfiler 受信のプロファイリングを管理する CloneProfiler を指定します。
745  必要ない場合は NULL を指定する必要があります。
746  @return 成功すれば、IsSuccess() が true を返す Result が返されます。この関数がエラーを返さないようにアプリケーションを実装する必要があります。
747  @retval ResultNotInitialized 初期化されていません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
748  @retval ResultInvalidArgument 引数が不正です。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
749  */
750  Result SetProfiler(CloneProfilerBase* pSendProfiler, CloneProfilerBase* pReceiveProfiler);
751 
752 
753  /*!
754  @brief 設定されている送信プロファイリング管理オブジェクトを取得します。
755  @return 設定されている送信プロファイリング管理オブジェクトです。設定されていない場合は NULL を返します。
756  @see SetProfiler
757  */
759  {
760  return m_pSendProfiler;
761  }
762 
763 
764  /*!
765  @brief 設定されている受信プロファイリング管理オブジェクトを取得します。
766  @return 設定されている受信プロファイリング管理オブジェクトです。設定されていない場合は NULL を返します。
767  @see SetProfiler
768  */
770  {
771  return m_pReceiveProfiler;
772  }
773 
774 
775  /*!
776  @brief 送受信のプロファイリングされた結果をリセットします。
777  @see SetProfiler
778  */
779  void ResetProfiler();
780 
781 
782  /*!
783  @brief 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に送信した CloneProtocol メッセージの個数を取得します。
784  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
785  @return 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に送信した CloneProtocol メッセージの個数です。
786  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
787  @see SetProfiler
788  */
789  uint32_t GetProfiledLatestSendCount(StationIndex stationIndex) const;
790 
791 
792  /*!
793  @brief 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に送信した CloneProtocol メッセージのサイズ(バイト)を取得します。
794  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
795  @return 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に送信した CloneProtocol メッセージのサイズ(バイト)です。
796  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
797  @see SetProfiler
798  */
799  uint32_t GetProfiledLatestSendSize(StationIndex stationIndex) const;
800 
801 
802  /*!
803  @brief 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に送信した CloneProtocol メッセージの圧縮前のサイズ(バイト)を取得します。
804  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
805  @return 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に送信した CloneProtocol メッセージの圧縮前のサイズ(バイト)です。
806  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
807  @see SetProfiler
808  */
809  uint32_t GetProfiledLatestSendNoCompressedSize(StationIndex stationIndex) const;
810 
811 
812  /*!
813  @brief 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間にユニキャストで送信した CloneProtocol メッセージの個数を取得します。
814  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
815  @return 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間にユニキャストで送信した CloneProtocol メッセージの個数です。
816  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
817  @see SetProfiler
818  */
819  uint32_t GetProfiledLatestSendUnicastCount(StationIndex stationIndex) const;
820 
821 
822  /*!
823  @brief 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間にユニキャストで送信した CloneProtocol メッセージのサイズ(バイト)を取得します。
824  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
825  @return 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間にユニキャストで送信した CloneProtocol メッセージのサイズ(バイト)です。
826  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
827  @see SetProfiler
828  */
829  uint32_t GetProfiledLatestSendUnicastSize(StationIndex stationIndex) const;
830 
831 
832  /*!
833  @brief 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に送信したシステム用 CloneProtocol メッセージの個数を取得します。
834  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
835  @return 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に送信したシステム用 CloneProtocol メッセージの個数です。
836  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
837  @see SetProfiler
838  */
839  uint32_t GetProfiledLatestSendSystemCount(StationIndex stationIndex) const;
840 
841 
842  /*!
843  @brief 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に送信したシステム用 CloneProtocol メッセージのサイズ(バイト)を取得します。
844  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
845  @return 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に送信したシステム用 CloneProtocol メッセージのサイズ(バイト)です。
846  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
847  @see SetProfiler
848  */
849  uint32_t GetProfiledLatestSendSystemSize(StationIndex stationIndex) const;
850 
851 
852  /*!
853  @brief ResetProfiler 以降に送信した CloneProtocol メッセージの個数を取得します。
854  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
855  @return ResetProfiler() 以降に送信した CloneProtocol メッセージの個数です。
856  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
857  @see SetProfiler, ResetProfiler
858  */
859  uint32_t GetProfiledTotalSendCount(StationIndex stationIndex) const;
860 
861 
862  /*!
863  @brief ResetProfiler 以降に送信した CloneProtocol メッセージのサイズ(バイト)を取得します。
864  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
865  @return ResetProfiler() 以降に送信した CloneProtocol メッセージのサイズ(バイト)です。
866  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
867  @see SetProfiler, ResetProfiler
868  */
869  uint32_t GetProfiledTotalSendSize(StationIndex stationIndex) const;
870 
871 
872  /*!
873  @brief ResetProfiler 以降に送信した CloneProtocol メッセージの圧縮前のサイズ(バイト)を取得します。
874  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
875  @return ResetProfiler() 以降に送信した CloneProtocol メッセージの圧縮前のサイズ(バイト)です。
876  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
877  @see SetProfiler, ResetProfiler
878  */
879  uint32_t GetProfiledTotalSendNoCompressedSize(StationIndex stationIndex) const;
880 
881 
882  /*!
883  @brief ResetProfiler 以降にユニキャストで送信した CloneProtocol メッセージの個数を取得します。
884  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
885  @return ResetProfiler() 以降にユニキャストで送信した CloneProtocol メッセージの個数です。
886  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
887  @see SetProfiler, ResetProfiler
888  */
889  uint32_t GetProfiledTotalSendUnicastCount(StationIndex stationIndex) const;
890 
891 
892  /*!
893  @brief ResetProfiler 以降にユニキャストで送信した CloneProtocol メッセージのサイズ(バイト)を取得します。
894  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
895  @return ResetProfiler() 以降にユニキャストで送信した CloneProtocol メッセージのサイズ(バイト)です。
896  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
897  @see SetProfiler, ResetProfiler
898  */
899  uint32_t GetProfiledTotalSendUnicastSize(StationIndex stationIndex) const;
900 
901 
902  /*!
903  @brief ResetProfiler 以降に送信したシステム用 CloneProtocol メッセージの個数を取得します。
904  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
905  @return ResetProfiler() 以降に送信したシステム用 CloneProtocol メッセージの個数です。
906  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
907  @see SetProfiler, ResetProfiler
908  */
909  uint32_t GetProfiledTotalSendSystemCount(StationIndex stationIndex) const;
910 
911 
912  /*!
913  @brief ResetProfiler 以降に送信したシステム用 CloneProtocol メッセージのサイズ(バイト)を取得します。
914  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
915  @return ResetProfiler() 以降に送信したシステム用 CloneProtocol メッセージのサイズ(バイト)です。
916  送信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
917  @see SetProfiler, ResetProfiler
918  */
919  uint32_t GetProfiledTotalSendSystemSize(StationIndex stationIndex) const;
920 
921 
922  /*!
923  @brief 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に受信した CloneProtocol メッセージの個数を取得します。
924  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
925  @return 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に受信した CloneProtocol メッセージの個数です。
926  受信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
927  @see SetProfiler
928  */
929  uint32_t GetProfiledLatestReceiveCount(StationIndex stationIndex) const;
930 
931 
932  /*!
933  @brief 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に受信した CloneProtocol メッセージのサイズ(バイト)を取得します。
934  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
935  @return 直近の @ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE" 回の common::Scheduler::Dispatch の間に受信した CloneProtocol メッセージのサイズ(バイト)です。
936  受信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
937  @see SetProfiler
938  */
939  uint32_t GetProfiledLatestReceiveSize(StationIndex stationIndex) const;
940 
941 
942  /*!
943  @brief ResetProfiler 以降に受信した CloneProtocol メッセージの個数を取得します。
944  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
945  @return ResetProfiler() 以降に受信した CloneProtocol メッセージの個数です。
946  受信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
947  @see SetProfiler, ResetProfiler
948  */
949  uint32_t GetProfiledTotalReceiveCount(StationIndex stationIndex) const;
950 
951 
952  /*!
953  @brief ResetProfiler 以降に受信した CloneProtocol メッセージのサイズ(バイト)を取得します。
954  @param[in] stationIndex プロファイリング対象の @ref StationIndex です。
955  @return ResetProfiler() 以降に受信した CloneProtocol メッセージのサイズ(バイト)です。
956  受信プロファイリング管理オブジェクトが設定されていない場合は 0xFFFFFFFF を返します。
957  @see SetProfiler, ResetProfiler
958  */
959  uint32_t GetProfiledTotalReceiveSize(StationIndex stationIndex) const;
960 
961  //! @}
962 
963  /*!
964  @brief 通信中に実際に使用された Ack 用バッファ数の最大値を取得します。
965  @details この値は再初期化時に 0 にリセットされます。
966  @return 通信中に実際に使用された Ack 用バッファ数の最大値です。
967  */
969  {
970  return m_AckMessageBufferUsedNumMax;
971  }
972 
973  /*!
974  @brief デバッグに有用な情報をプリントします。
975 
976  @param[in] flag トレースフラグの論理和。詳細は @ref TraceFlag 型を参照してください。
977  */
978  virtual void Trace(uint64_t flag) const;
979 
980 
981 public:
982  /*!
983  @cond PRIVATE
984  @brief 再送間隔を取得します。(デバッグ用)
985  */
986  SystemTime GetResendSpan() const
987  {
988  return m_ResendSpan;
989  }
990  //! @endcond
991 
992  /*!
993  @cond PRIVATE
994  @brief ユニキャスト用の再送間隔を取得します。(デバッグ用)
995  */
996  SystemTime GetResendSpanForUnicast(StationIndex stationIndex) const
997  {
998  return m_ResendSpanForUnicast[stationIndex];
999  }
1000  //! @endcond
1001 
1002  uint32_t GetStationNum() const
1003  {
1004  return m_StationNum;
1005  }
1006 
1007  //! @cond PRIVATE
1008 
1009 private:
1010  static int SimpleClockPriorityJudgeFunction(ClockValue clock, StationIndex stationA, StationIndex stationB);
1011  static int ImpartialClockPriorityJudgeFunction(ClockValue clock, StationIndex stationA, StationIndex stationB);
1012 
1013 public:
1014  StationIndex GetLocalStationIndex() const
1015  {
1016  return m_LocalStationIndex;
1017  }
1018  uint32_t GetParticipantBitmap() const
1019  {
1020  return m_ParticipantBitmap;
1021  }
1022  SystemTime GetSystemTime() const
1023  {
1024  return m_SystemTime;
1025  }
1026  uint32_t GetDispatchCount() const
1027  {
1028  return m_DispatchCount;
1029  }
1030 
1031  void ErrorEventDropped()
1032  {
1033  SetError(ErrorType_EventDropped);
1034  }
1035 
1036  // n2920 : CloneBaseで参照するために追加
1037  uint32_t GetValidStationBitmap() const
1038  {
1039  return m_ValidStationBitmap;
1040  }
1041 
1042  uint32_t GetNoticeParticipationBitmap() const
1043  {
1044  return m_NoticeParticipationBitmap;
1045  }
1046 
1047  bool IsBroadcastSupported() const
1048  {
1049  return m_IsBroadcastSupported;
1050  }
1051 
1052 private:
1053  bool IsInitialized() const
1054  {
1055  return (m_StationNum > 0);
1056  }
1057  bool IsInCommunication() const
1058  {
1059  return m_LocalStationIndex != StationIndex_Invalid;
1060  }
1061 
1062  enum InnerState
1063  {
1064  InnerState_Inactive = State_Inactive | 0x1,
1065  InnerState_SyncClock = State_Start | 0x1,
1066  InnerState_NoticeStart = State_Start | 0x2,
1067  InnerState_Active = State_Active | 0x1,
1068  InnerState_CloneEnding = State_Stop | 0x1,
1069  InnerState_NoticeStop = State_Stop | 0x2
1070  };
1071  InnerState GetInnerState() const
1072  {
1073  return m_InnerState;
1074  }
1075 
1076  void UpdateCloneState();
1077  void UpdateState();
1078  void UpdateResendSpan();
1079  SystemTime CalcResendSpan(int rtt) const;
1080 
1081  void ReceiveMessages();
1082  void ReceiveMessage(StationIndex src, const void* cpMessage, uint32_t size);
1083  bool CheckReceivedMessageDestStationBitmap(const void* cpMessage);
1084  bool UpdateReceivedMessageSequentialId(StationIndex src, const void* cpMessage);
1085 
1086  void SerializeMessage(void* pMessage, uint32_t messageSize, uint32_t noCompressedMessageSize, uint8_t* serializedMessageBuf, uint32_t* serializedMessageSize, uint32_t* noCompressedSerializedMessageSize);
1087  template <typename MessageStruct>
1088  void SerializeMessageCore(void* pMessage, uint8_t* serializedMessageBuf, uint32_t* headerSize, uint32_t* serializedHeaderSize);
1089  void CalcSerializedMessageSize(void* pMessage, uint32_t messageSize, uint32_t noCompressedMessageSize, uint32_t* serializedMessageSize, uint32_t* noCompressedSerializedMessageSize);
1090  bool SendUnicastMessage(StationIndex dest, void* pMessage, uint32_t messageSize, uint32_t noCompressedMessageSize, bool isSystem);
1091  bool SendBroadcastMessage(uint32_t destBitmap, void* pMessage, uint32_t messageSize, uint32_t noCompressedMessageSize, bool isSystem);
1092  void SetSequentialIdToMessage(void* pMessage);
1093  void SetDestStationBitmapToMessage(void* pMessage, uint16_t destStationBitmap);
1094 
1095  bool SendBroadcastCloneCommand(StationIndex dest, CloneBase::Type cloneType, StationIndex cloneStationIndex, CloneBase::Id cloneId, uint8_t command);
1096  bool SendBroadcastClockCloneCommand(StationIndex dest, CloneBase::Type cloneType, StationIndex cloneStationIndex, CloneBase::Id cloneId, uint8_t command, ClockValue clock);
1097  bool SendBroadcastClockAndCountCloneCommand(StationIndex dest, CloneBase::Type cloneType, StationIndex cloneStationIndex, CloneBase::Id cloneId, uint8_t command, ClockValue clock, uint8_t count);
1098  bool SendBroadcastClockAndCountAndParticipantCloneCommand(StationIndex dest, CloneBase::Type cloneType, StationIndex cloneStationIndex, CloneBase::Id cloneId, uint8_t command, ClockValue clock, uint8_t count, uint32_t participantBitmap);
1099 
1100  void UpdateSystemTime();
1101 
1102  void SendClockRequest();
1103  void ReceiveClockRequest(StationIndex src, const void* cpMessage, uint32_t size);
1104  void ReceiveClockReplyMessage(StationIndex src, const void* cpMessage, uint32_t size);
1105 
1106  void NoticeParticipation();
1107  void ReceiveEnterMessage(StationIndex src, const void* cpMessage, uint32_t size);
1108  void ReceiveExitMessage(StationIndex src, const void* cpMessage, uint32_t size);
1109  void ReceiveEnterAckMessage(StationIndex src, const void* cpMessage, uint32_t size);
1110  void ReceiveExitAckMessage(StationIndex src, const void* cpMessage, uint32_t size);
1111 
1112  struct DispatchCountData
1113  {
1114  public:
1115  void Clear()
1116  {
1117  m_MyCount = InvalidDispatchCount;
1118  m_ReceivedCount = 0;
1119  }
1120  uint32_t m_MyCount;
1121  uint16_t m_ReceivedCount;
1122  };
1123 
1124 private:
1125  uint32_t m_ElementSizeMax;
1126 
1127  uint32_t m_StationNum;
1128  StationIndex m_LocalStationIndex;
1129  uint32_t m_ValidStationBitmap; // CONNECT,DISCONNECTと直接連動するBitmap
1130  uint32_t m_ParticipantBitmap; // CloneProtoclがeMTEnterを受けて参加、eMTExitを受けて不参加とみなすBitmap
1131  InnerState m_InnerState;
1132 
1133  Clock* m_pClock;
1134 
1135  SystemTime m_SystemTime;
1136  SystemTime m_ResendSpan;
1137  SystemTime m_ResendSpanForUnicast[MaxStationNum];
1138  float m_ResendSpanRatio;
1139  float m_MillisecondsPerFrame;
1140  int m_MillisecondsPerFrameSamplingNum;
1141  static const int MillisecondsPerFrameSamplingNumMax = 10;
1142  common::Time m_MillisecondsPerFramePreTime;
1143 
1144  SystemTime m_LastUpdateResendSpanTime;
1145  SystemTime m_LastParticipationCommandTime;
1146  SystemTime m_LastClockCommandTime;
1147 
1148  uint32_t m_SendPeriod;
1149 
1150  static const SystemTime DefaultResendSpan = 500;
1151 
1152  uint32_t m_DispatchCount;
1153  DispatchCountData* m_paReceivedDispatchCount;
1154  static const uint32_t CheckDispatchCount = 0x00003fff;
1155 
1156 public:
1157  static const uint32_t InvalidDispatchCount = 0xffffffff;
1158 
1159 private:
1160  enum
1161  {
1162  StateMask = 0xf0
1163  };
1164 
1165  uint32_t m_NoticeParticipationBitmap; // 自分がCloneProtocolをStart(),Stop()したときに、相手のAckをチェックするBitmap
1166 
1167 private:
1168  Result RegisterClone(CloneBase::Key key, CloneBase* pClone);
1169  Result UnregisterClone(CloneBase::Key key);
1170  Result UnregisterClone(CloneBase* pClone);
1171 
1172  typedef common::OffsetTreeMap<CloneBase::Key, CloneBase> CloneCollection;
1173  CloneCollection m_CloneCollection;
1174 
1175 
1176 public:
1177  void AddSendCommand(CloneBase::CommandToken* pToken);
1178  void CancelSendCommand(CloneBase::CommandToken* pToken);
1179 
1180 private:
1181  void SendCommand();
1182  uint32_t SendCommandCore(CloneBase::CommandToken* pToken, bool isUnicast, uint32_t destBitmap, void* pMessage, uint32_t messageSize);
1183 
1184  typedef common::OffsetList<CloneBase::CommandToken> CommandTokenList;
1185  CommandTokenList m_SendCommandTokenList;
1186  CommandTokenList m_ResendCommandTokenList;
1187 
1188 public:
1189  void AddSendData(CloneBase::DataToken* pToken);
1190  void CancelSendData(CloneBase::DataToken* pToken);
1191 
1192 private:
1193  void SendAck();
1194  void SendData();
1195  bool SendCloneData(CloneBase::DataToken* pToken);
1196  void ReceiveData(StationIndex src, CloneBase* pClone, const void* cpMessage, uint32_t messageSize);
1197 
1198  typedef common::OffsetList<CloneBase::DataToken> DataTokenList;
1199  DataTokenList m_DataTokenList;
1200 
1201  struct DataMessageBuffer
1202  {
1203  public:
1204  void Clear()
1205  {
1206  m_DestBitmap = 0;
1207  m_Size = 0;
1208  }
1209 
1210  uint32_t m_DestBitmap;
1211  uint16_t m_Size;
1212  uint16_t m_NoCompressedSize;
1213  uint16_t m_Dummy;
1214  uint8_t m_Message[common::ProtocolMessgaePayloadSizeMax + MessageHeaderSerializeDiffSizeMax];
1215  };
1216 
1217  DataMessageBuffer m_DataMessageBuffer;
1218  IDataPacker* m_pDataPacker;
1219  IDataUnpacker* m_pDataUnpacker;
1220  CompressDataUnpacker* m_pCompressedDataUnpacker;
1221 
1222  StationIndex m_TryNextUnicastDestStationIndex;
1223 
1224 public:
1225  ClockPriorityJudgeFunction GetClockPriorityJudgeFunction() const
1226  {
1227  return m_ClockPriorityJudgeFunction;
1228  }
1229 
1230 private:
1231  ClockPriorityJudgeFunction m_ClockPriorityJudgeFunction;
1232 
1233 private:
1234  void SetError(ErrorType errorType);
1235 
1236  ErrorType m_Error;
1237 
1238 private:
1239  CloneProfilerBase* m_pSendProfiler;
1240  CloneProfilerBase* m_pReceiveProfiler;
1241 
1242  uint32_t m_SendMessageSequentialId;
1243  uint32_t m_ReceivedMessageSequentialId[MaxStationNum];
1244 #if NN_PIA_ENABLE_TRACE
1245  // 同じ SequentialId を 2 連続で受信した場合の、1 つ目のメッセージ情報トレース用
1246  struct MessageHeaderForDebug
1247  {
1248  uint8_t m_FormatVersion;
1249  uint8_t m_MessageType;
1250  uint16_t m_DispatchCount;
1251  };
1252  MessageHeaderForDebug m_ReceivedMessageHeaderForDebug[MaxStationNum];
1253 #endif
1254 
1255 public:
1256  typedef bool (*ReceiveElementFunction)(CloneElementBase* pElement, IDataPacker* pAckPacker, const void* cpChunk, uint16_t chunkSize, CloneElementBase::Id elementId, StationIndex src, StationIndex localStationIndex, uint32_t dispatchCount);
1257 
1258  class ElementDefinition
1259  {
1260  public:
1261  ElementDefinition();
1262  void Register(uint16_t type, ReceiveElementFunction receiveFunction, uint32_t dataChunkHeaderSize);
1263  ReceiveElementFunction GetReceiveFunction(uint16_t type) const;
1264  uint32_t GetDataChunkHeaderSizeMax() const
1265  {
1266  return m_DataChunkHeaderSizeMax;
1267  }
1268  static const uint32_t TypeNum = 16;
1269 
1270  private:
1271  ReceiveElementFunction m_aReceiveFunction[TypeNum];
1272  uint32_t m_DataChunkHeaderSizeMax;
1273  };
1274 
1275  static ElementDefinition* GetElementDefinition();
1276 
1277 
1278 protected:
1279  virtual Clock* CreateRtcClock(float clockPerSec, float regulationRate);
1280  virtual uint16_t TransportGetMaxStationNum();
1281  virtual uint32_t PayloadSizeManagerGetMtuSize();
1282  virtual uint32_t SignatureManagerGetSignatureSizeMax();
1283  virtual const common::Time& TransportGetDispatchedTime();
1284  virtual int32_t StationGetRtt(StationIndex stationIndex);
1285  virtual int32_t StationGetRttPulseInterval();
1286  virtual uint32_t PacketHandlerGetPayloadSizeLimit();
1287  virtual bool PacketHandlerSendMessageById(StationIndex dest, const void* cpData, uint32_t size);
1288  virtual bool PacketHandlerSendMessageByBitmap(uint32_t destBitmap, const void* cpData, uint32_t size);
1289  virtual void PacketHandlerReadIterationBegin(void** ppIterator);
1290  virtual bool PacketHandlerReadIterationIsEnd(const void* cpIterator);
1291  virtual void PacketHandlerReadIterationNext(void* pIterator);
1292  virtual void PacketHandlerReadIteratorGet(StationIndex* pSrc, const void** cppPayloadPtr, uint32_t* pPayloadSize, const void* cpIterator);
1293 
1294 public:
1295  template <int TestId, typename Arg>
1296  static void Test(const CloneProtocol& obj, Arg* pArg = NULL);
1297 
1298 private:
1299  // n2920: クライアント監視機能用
1300  uint32_t m_UpdateCount; // 送信間隔関連処理でも使用
1301  uint32_t m_ResendCount;
1302  nn::pia::common::Time m_ActivationStartTime;
1303  uint32_t m_CompCount;
1304  float m_CompRateTotal;
1305  float m_CompAverage;
1306  uint32_t m_SendCount;
1307  uint32_t m_SendDataTotal;
1308 
1309  uint32_t m_UpdateCountOffset;
1310  bool m_IsSendProcessNeeded;
1311 
1312  bool m_IsBroadcastSupported;
1313 
1314  // Ack 用
1315  static const uint32_t AckMessageBufferSize = common::ProtocolMessgaePayloadSizeMax + MessageHeaderSerializeDiffSizeMax;
1316  struct AckMessageInfo
1317  {
1318  uint8_t messageBuffer[AckMessageBufferSize];
1319  uint32_t messageSize;
1320  uint32_t noCompressedMessageSize;
1321  StationIndex destStationIndex;
1322  };
1323  AckMessageInfo* m_pAckMessageInfoArray;
1324  int m_AckMessageBufferNum;
1325  int m_AckMessageBufferHeadIndex;
1326  int m_AckMessageBufferUsedNum;
1327  int m_AckMessageBufferUsedNumMax;
1328 
1329  NN_PIA_DISALLOW_COPY(CloneProtocol);
1330  //! @endcond
1331 };
1332 }
1333 }
1334 } // end of namespace nn::pia::clone