CTR Pia  4.11.3
Game Communication Engine
clone_CloneProtocol.h
1 /*---------------------------------------------------------------------------*
2  Project: Pia
3  File: clone_CloneProtocol.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/common/common_PacketDefine.h>
18 #include <pia/common/common_OffsetTreeMap.h>
19 #include <pia/common/common_OffsetList.h>
20 #include <pia/transport/transport_Protocol.h>
21 #include <pia/clone/clone_definitions.h>
22 #include <pia/clone/clone_SendClone.h>
23 #include <pia/clone/clone_ReceiveClone.h>
24 #include <pia/clone/clone_AtomicSharingClone.h>
25 #include <pia/clone/clone_SequentialSharingClone.h>
26 
27 namespace nn
28 {
29 namespace pia
30 {
31 namespace clone
32 {
33 
34 class Clock;
35 class IDataPacker;
36 class IDataUnpacker;
37 class CompressDataUnpacker;
38 
39 
40 /*!
41 @brief Represents a protocol for sharing values between stations. <br />
42 
43 @date 2014-08-01 Changed specifications specific to the arguments and success conditions for the <tt>RegisterReceiveClone</tt>, <tt>UnregisterReceiveClone</tt>, and <tt>SearchReceiveClone</tt> functions.
44 @date 2014-07-17 Changed specifications specific to success conditions for the <tt>RegisterReceiveClone</tt>, <tt>UnregisterReceiveClone</tt>, and <tt>SearchReceiveClone</tt> functions.
45 @date 2014-07-17 Changed the names of the <tt>SetDefermentPeriod</tt> and <tt>GetDefermentPeriod</tt> functions to the <tt>SetMaxSendDelay</tt> and <tt>GetMaxSendDelay</tt> functions, respectively.
46 @date 2014-01-30 Added constants to specify the compression level of synchronization data, and made any other compression levels unsupported.
47 @date 2013-11-25 Added a profiling feature.
48 @date 2013-11-19 Corrected the spelling of <tt>Setting::m_RegulationRate</tt>.
49 @date 2013-07-18 Initial version.
50 */
52 {
53 public:
54  PIA_PROTOCOL_TYPE_INFO(nn::pia::transport::PROTOCOL_TYPE_CLONE);
55 
56 /*!
57 @cond PRIVATE
58 @brief Instantiates the object with default parameters (default constructor).
59 */
60  CloneProtocol();
61  //! @endcond
62 
63 
64 /*!
65 @cond PRIVATE
66 @brief Destructor.
67 */
68  virtual ~CloneProtocol();
69  //! @endcond
70 
71 
72 /*!
73 @brief Compares the order.
74 @param[in] clock Specifies the time of the comparison.
75 @param[in] stationA Specifies the <tt>StationIndex</tt> of a station to compare.
76 @param[in] stationB Specifies the <tt>StationIndex</tt> of a station to compare.
77 @return When the time is <tt>clock</tt>, returns a negative value when <tt><var>stationB</var></tt> is treated as if it occurred before <tt><var>stationA</var></tt>. Returns a positive value when <tt><var>stationB</var></tt> is treated as if it occurred after <tt><var>stationA</var></tt>.
78 @details This function is never called when <tt><var>stationA</var></tt> and <tt><var>stationB</var></tt> are the same value.
79 @details This function must never give contradictory order relationships at any particular time.
80 For example, if <tt>ClockPriorityJudgeFunction(clock, stationA, stationB) < 0</tt> is true, <tt>ClockPriorityJudgeFunction(clock, stationB, stationA) > 0</tt> must also be true.
81 When <tt>ClockPriorityJudgeFunction(clock, stationA, stationB) < 0</tt> and <tt>ClockPriorityJudgeFunction(clock, stationB, stationC) < 0</tt> are both true, <tt>ClockPriorityJudgeFunction(clock, stationA, stationC) < 0</tt> must also be true.
82 @details At different times, however, the order relationship does not need to match.
83 Just because <tt>ClockPriorityJudgeFunction(clock1, stationA, stationB) < 0</tt> is true does not mean it is a problem for <tt>ClockPriorityJudgeFunction(clock2, stationA, stationB) > 0</tt> to also be true.
84 
85 
86 
87 
88 */
89  typedef int (*ClockPriorityJudgeFunction)(ClockValue clock, StationIndex stationA, StationIndex stationB);
90 
91 
92  static const u32 COMPRESSION_LEVEL_NONE = 0; //!< Specifies the compression level (no compression) for the data to send specified in <tt>@ref Setting::dataCompressionLevel</tt>.
93  static const u32 COMPRESSION_LEVEL_LOW = 1; //!< Specifies the compression level (speed emphasized) for the data to send specified in <tt>@ref Setting::dataCompressionLevel</tt>.
94  static const u32 COMPRESSION_LEVEL_MIDDLE = 5; //!< Specifies the compression level for the data to send specified in <tt>@ref Setting::dataCompressionLevel</tt>.
95  static const u32 COMPRESSION_LEVEL_HIGH = 9; //!< Specifies the compression level (compression rate emphasized) for the data to send specified in <tt>@ref Setting::dataCompressionLevel</tt>.
96 
97 /*!
98 @brief Stores settings specified during initialization.
99 @details Specify the same values on stations being communicated with.
100 */
101  struct Setting
102  {
103  public:
104 /*!
105 @brief Instantiates the object with default parameters (default constructor).
106 @details This function initializes the object using default values.
107 */
110  clockPerSec(1000.0f),
111  clockPerFrame(1),
112  clockRegulationRate(0.1f),
115  dataCompressionLevel(COMPRESSION_LEVEL_NONE)
116  {
117  }
118 
119 
120 /*!
121 @brief Enumerates the standard used for advancing the clock.
122 */
124  {
125  CLOCK_TYPE_RTC = 0, //!< Specifies that the clock advances based on RTC.
126  CLOCK_TYPE_FRAME //!< Specifies that the clock advances based on the number of times <tt>CloneProtocol::UpdateClock</tt> is called.
127  };
128 
129 
130 /*!
131 @brief Specifies the standard to use for advancing the clock.
132 @details If <tt>CLOCK_TYPE_RTC</tt> is specified, the clock advances based on RTC.
133 After a session begins and the clock has been regulated, time differences between systems do not need to be considered. However, the clock may not advance the same amount for each frame depending on when <tt>CloneProtocol::UpdateClock</tt> is called.
134 Specify the speed at which to advance the clock in <tt>clockPerSec</tt>.
135 @details If <tt>CLOCK_TYPE_FRAME</tt> is specified, usually the clock advances a set value each time <tt>CloneProtocol::UpdateClock</tt> is called.
136 However, if the number of calls to <tt>CloneProtocol::UpdateClock</tt> differs between stations due to lag or other factors, the clock may no longer match between stations.
137 Specify the speed at which to advance the clock in <tt>clockPerFrame</tt>.
138 @details For more information about managing the clock, see the programming manual.
139 @see clockPerSec
140 @see clockPerFrame
141 
142 
143 */
145 
146 
147 /*!
148 @brief Specifies the value to advance the clock per second.
149 @details This setting is ignored if <tt>clockType</tt> is set to something other than <tt>CLOCK_TYPE_RTC</tt>.
150 @see clockType
151 */
153 
154 
155 /*!
156 @brief Specifies the value to advance the clock per frame.
157 @details This setting is ignored if <tt>clockType</tt> is set to something other than <tt>CLOCK_TYPE_FRAME</tt>.
158 @see clockType
159 */
161 
162 
163 /*!
164 @brief Specifies the rate at which to speed up or slow down the clock when re-regulating the clock.
165 @details When the clock is re-regulated using <tt>CloneProtocol::RegulateClock</tt>, it advances faster or slower than usual at the rate specified here.
166 For example, if <tt>0.1</tt> is specified and the station clock is behind the clocks of other stations, the clock advances at a speed of 110%.
167 On the other hand, if the clock is ahead of the other stations, it advances at a speed of 90%.
168 */
170 
171 
172 /*!
173 @brief Enumerates the method for determining which station was first when an event occurs at the time clock value.
174 */
176  {
177  CLOCK_PRIORITY_JUDGE_METHOD_SIMPLE = 0, //!< Specifies that the station with a smaller station ID value was first.
178  CLOCK_PRIORITY_JUDGE_METHOD_IMPARTIAL, //!< Specifies that the priority is changed based on the clock value so that no single station has an advantage over the long term.
179  CLOCK_PRIORITY_JUDGE_METHOD_USER_DEFINE //!< Specifies that the application defines the method to use.
180  };
181 
182 
183 /*!
184 @brief Specifies the method for determining which station was first when an event occurs at the time clock value.
185 @details If <tt>CLOCK_PRIORITY_JUDGE_METHOD_USER_DEFINE</tt> is specified, specify the function to use for determining the order in <tt>clockPriorityJudgeFunction</tt>.
186 @see clockPriorityJudgeFunction
187 */
189 
190 
191 /*!
192 @brief Specifies the function for determining which station was first when an event occurs at the time clock value.
193 @details This setting is ignored if <tt>clockPriorityJudgeMethod</tt> is set to something other than <tt>CLOCK_PRIORITY_JUDGE_METHOD_USER_DEFINE</tt>.
194 @see clockPriorityJudgeMethod;
195 */
197 
198 
199 /*!
200 @brief Specifies the compression level for data to send.
201 @details Not compressed when <tt>@ref CloneProtocol::COMPRESSION_LEVEL_NONE</tt> is specified.
202 Specifying <tt>@ref CloneProtocol::COMPRESSION_LEVEL_LOW</tt> emphasizes speed; <tt>@ref CloneProtocol::COMPRESSION_LEVEL_HIGH</tt> emphasizes the compression rate.
203 Specifying <tt>@ref CloneProtocol::COMPRESSION_LEVEL_MIDDLE</tt> results in a level of compression in between the other two.
204 The default value is <tt>@ref CloneProtocol::COMPRESSION_LEVEL_NONE</tt>.
205 Other values are not supported.
206 Execution time varies significantly based on the CPU performance of the platform.
207 */
209  };
210 
211 
212 /*!
213 @brief Initialization. Make this call between the <tt>BeginSetup</tt> and <tt>EndSetup</tt> functions.
214 @param[in] setting Specifies various settings.
215 Specify the same values on all stations. Operations are undefined when different values are specified.
216 @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.
217 @retval ResultAlreadyInitialized Indicates that the instance is already initialized. Programming error. Fix your program so that this error is not returned.
218 @retval ResultInvalidArgument Indicates that an argument is invalid. Programming error. Fix your program so that this error is not returned.
219 @see Finalize
220 */
221  nn::Result Initialize(const Setting& setting);
222 
223 
224 /*!
225 @brief Finalizes the class instance.
226 @see Initialize
227 */
228  void Finalize();
229 
230 
231 /*!
232 @brief Gets the maximum value that can be retrieved from the <tt>SerializePolicy::GetSize</tt> function of the clone element to be used.
233 @details If a clone with a registered clone element larger than this value is passed to the <tt>RegisterXXXClone</tt> function, <tt>@ref ResultInvalidArgument</tt> is returned.
234 @details This value is the maximum size that can fit in a single packet.
235 The value differs depending on the communication module being used and the MTU setting.
236 This value can be retrieved after the <tt>Initialize</tt> function has been called.
237 @return Returns the maximum value that can be retrieved from the <tt>SerializePolicy::GetSize</tt> function of the clone element to be used.
238 */
239  size_t GetElementSizeMax() const
240  {
241  return m_ElementSizeMax;
242  }
243 
244 
245 /*!
246 @brief Registers a <tt>SendClone</tt> to the specified ID.
247 @param[in] pClone Specifies the <tt>SendClone</tt> to register.
248 @param[in] cloneId Specifies the ID to register to.
249 @return Returns a <tt>Result</tt> value for which the <tt>IsSuccess</tt> function returns <tt>true</tt> if execution succeeds.
250 @retval ResultNotInitialized Indicates that the instance is not initialized. Programming error. Fix your program so that this error is not returned.
251 @retval ResultInvalidArgument Indicates that an argument is invalid. Programming error. Fix your program so that this error is not returned.
252 @retval ResultAlreadyExists Indicates that the object is already registered to the specified ID. Programming error. Fix your program so that this error is not returned.
253 */
254  nn::Result RegisterSendClone(SendClone* pClone, CloneBase::Id cloneId)
255  {
256  return RegisterClone(SendClone::ToKey(cloneId), pClone);
257  }
258 
259 
260 /*!
261 @brief Unregisters a <tt>SendClone</tt>.
262 @details If a send is in progress, this function waits until the send is complete before unregistering.
263 Therefore, even if this function succeeds, <tt><var>pClone</var></tt> cannot be reused or re-registered to the same ID until <tt>pClone->@ref SendClone::IsRegisteredWithProtocol "IsRegisteredWithProtocol"</tt> returns <tt>false</tt>.
264 @param[in] pClone Specifies the <tt>SendClone</tt> to unregister.
265 @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.
266 @retval ResultNotInitialized Indicates that the instance is not initialized. Programming error. Fix your program so that this error is not returned.
267 @retval ResultInvalidArgument Indicates that an argument is invalid. The specified <tt>SendClone</tt> is not registered to this <tt>CloneProtocol</tt>. Programming error. Fix your program so that this error is not returned.
268 
269 */
270  nn::Result UnregisterSendClone(SendClone* pClone)
271  {
272  return UnregisterClone(pClone);
273  }
274 
275 
276 /*!
277 @brief Unregisters a <tt>SendClone</tt>.
278 @details If a send is in progress, this function waits until the send is complete before unregistering.
279 Even if this function succeeds, <tt><var>SendClone</var></tt> cannot be reused or reregistered to the same ID until <tt>SendClone::IsRegisteredWithProtocol</tt> returns <tt>false</tt>.
280 @param[in] cloneId Specifies the ID of the <tt>SendClone</tt> to unregister.
281 @return Returns a <tt>Result</tt> value for which the <tt>IsSuccess</tt> function returns <tt>true</tt> if execution succeeds.
282 @retval ResultNotInitialized Indicates that the instance is not initialized. Programming error. Fix your program so that this error is not returned.
283 @retval ResultNotSet Indicates that the object is not registered to the specified ID. Programming error. Fix your program so that this error is not returned.
284 
285 */
286  nn::Result UnregisterSendClone(CloneBase::Id cloneId)
287  {
288  return UnregisterClone(SendClone::ToKey(cloneId));
289  }
290 
291 
292 /*!
293 @brief Searches for and gets the <tt>SendClone</tt> object with the specified ID.
294 @param[in] cloneId Specifies the ID of the <tt>SendClone</tt> to search for.
295 @return Returns the <tt>SendClone</tt> with the specified ID. Returns <tt>NULL</tt> when an object with the specified ID cannot be found.
296 */
298  {
299  return static_cast<SendClone*>(m_CloneCollection.Find(SendClone::ToKey(cloneId)));
300  }
301 
302 
303 /*!
304 @brief Searches for and gets the <tt>SendClone</tt> object with the specified ID.
305 @param[in] cloneId Specifies the ID of the <tt>SendClone</tt> to search for.
306 @return Returns the <tt>SendClone</tt> with the specified ID. Returns <tt>NULL</tt> when an object with the specified ID cannot be found.
307 */
309  {
310  return static_cast<const SendClone*>(m_CloneCollection.Find(SendClone::ToKey(cloneId)));
311  }
312 
313 
314 /*!
315 @brief Registers a <tt>ReceiveClone</tt> to the specified ID.
316 @param[in] pClone Specifies the <tt>ReceiveClone</tt> to register.
317 @param[in] sendStationIndex Specifies the <tt>@ref StationIndex</tt> of the sender with the <tt>SendClone</tt>.
318 @param[in] cloneId Specifies the ID to register to.
319 @return Returns a <tt>Result</tt> value for which the <tt>IsSuccess</tt> function returns <tt>true</tt> if execution succeeds.
320 @retval ResultNotInitialized Indicates that the instance is not initialized. Programming error. Fix your program so that this error is not returned.
321 @retval ResultInvalidArgument Indicates that an argument is invalid. Programming error. Fix your program so that this error is not returned.
322 @retval ResultAlreadyExists Indicates that the object is already registered to the specified ID. Programming error. Fix your program so that this error is not returned.
323 */
324  nn::Result RegisterReceiveClone(ReceiveClone* pClone, StationIndex sendStationIndex, CloneBase::Id cloneId);
325 
326 
327 /*!
328 @brief Unregisters a <tt>ReceiveClone</tt>.
329 @details If a send is in progress, this function waits until the send is complete before unregistering.
330 Even if this function succeeds, <tt><var>pClone</var></tt> cannot be reused or re-registered to the same ID until <tt>pClone->@ref ReceiveClone::IsRegisteredWithProtocol "IsRegisteredWithProtocol"</tt> returns <tt>false</tt>.
331 (<tt>ReceiveClone</tt> may also send for other reasons, for example when serving as a proxy when a station is improperly disconnected.)
332 @param[in] pClone Specifies the <tt>ReceiveClone</tt> to unregister.
333 @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.
334 @retval ResultNotInitialized Indicates that the instance is not initialized. Programming error. Fix your program so that this error is not returned.
335 @retval ResultInvalidArgument Indicates that an argument is invalid. The specified <tt>ReceiveClone</tt> is not registered to this <tt>CloneProtocol</tt>. Programming error. Fix your program so that this error is not returned.
336 
337 */
339  {
340  return UnregisterClone(pClone);
341  }
342 
343 
344 /*!
345 @brief Unregisters a <tt>ReceiveClone</tt>.
346 @details If a send is in progress, this function waits until the send is complete before unregistering.
347 Even if this function succeeds, <tt><var>ReceiveClone</var></tt> cannot be reused or reregistered to the same ID until <tt>ReceiveClone::IsRegisteredWithProtocol</tt> returns <tt>false</tt>.
348 (<tt>ReceiveClone</tt> may also send for other reasons, for example when serving as a proxy when a station is improperly disconnected.)
349 @param[in] sendStationIndex Specifies the <tt>@ref StationIndex</tt> of the sender with the <tt>SendClone</tt>.
350 @param[in] cloneId Specifies the ID of the <tt>ReceiveClone</tt> to unregister.
351 @return Returns a <tt>Result</tt> value for which the <tt>IsSuccess</tt> function returns <tt>true</tt> if execution succeeds.
352 @retval ResultNotInitialized Indicates that the instance is not initialized. Programming error. Fix your program so that this error is not returned.
353 @retval ResultInvalidArgument Indicates that an argument is invalid. Programming error. Fix your program so that this error is not returned.
354 @retval ResultNotSet Indicates that the object is not registered to the specified ID. Programming error. Fix your program so that this error is not returned.
355 
356 */
357  nn::Result UnregisterReceiveClone(StationIndex sendStationIndex, CloneBase::Id cloneId);
358 
359 
360 /*!
361 @brief Searches for and gets the <tt>ReceiveClone</tt> object with the specified ID.
362 @param[in] sendStationIndex Specifies the <tt>@ref StationIndex</tt> of the sender with the <tt>SendClone</tt>.
363 @param[in] cloneId Specifies the ID of the <tt>ReceiveClone</tt> to search for.
364 @return Returns the <tt>ReceiveClone</tt> with the specified ID. Returns <tt>NULL</tt> when an object with the specified ID cannot be found.
365 */
366  ReceiveClone* SearchReceiveClone(StationIndex sendStationIndex, CloneBase::Id cloneId);
367 
368 
369 /*!
370 @brief Searches for and gets the <tt>ReceiveClone</tt> object with the specified ID.
371 @param[in] sendStationIndex Specifies the <tt>@ref StationIndex</tt> of the sender with the <tt>SendClone</tt>.
372 @param[in] cloneId Specifies the ID of the <tt>ReceiveClone</tt> to search for.
373 @return Returns the <tt>ReceiveClone</tt> with the specified ID. Returns <tt>NULL</tt> when an object with the specified ID cannot be found.
374 */
375  const ReceiveClone* SearchReceiveClone(StationIndex sendStationIndex, CloneBase::Id cloneId) const;
376 
377 
378 /*!
379 @brief Registers a <tt>AtomicSharingClone</tt> to the specified ID.
380 @param[in] pClone Specifies the <tt>AtomicSharingClone</tt> to register.
381 @param[in] cloneId Specifies the ID to register to.
382 @return Returns a <tt>Result</tt> value for which the <tt>IsSuccess</tt> function returns <tt>true</tt> if execution succeeds.
383 @retval ResultNotInitialized Indicates that the instance is not initialized. Programming error. Fix your program so that this error is not returned.
384 @retval ResultInvalidArgument Indicates that an argument is invalid. Programming error. Fix your program so that this error is not returned.
385 @retval ResultAlreadyExists Indicates that the object is already registered to the specified ID. Programming error. Fix your program so that this error is not returned.
386 */
388  {
389  return RegisterClone(AtomicSharingClone::ToKey(cloneId), pClone);
390  }
391 
392 
393 /*!
394 @brief Unregisters a <tt>AtomicSharingClone</tt>.
395 @details If a send is in progress, this function waits until the send is complete before unregistering.
396 Even if this function succeeds, <tt><var>pClone</var></tt> cannot be reused or re-registered to the same ID until <tt>pClone->@ref AtomicSharingClone::IsRegisteredWithProtocol "IsRegisteredWithProtocol"</tt> returns <tt>false</tt>.
397 (The object may send without acquiring a lock for other reasons, for example when serving as a proxy when a station is improperly disconnected.)
398 @param[in] pClone Specifies the <tt>AtomicSharingClone</tt> to unregister.
399 @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.
400 @retval ResultNotInitialized Indicates that the instance is not initialized. Programming error. Fix your program so that this error is not returned.
401 @retval ResultInvalidArgument Indicates that an argument is invalid. The specified <tt>AtomicSharingClone</tt> is not registered to this <tt>CloneProtocol</tt>. Programming error. Fix your program so that this error is not returned.
402 
403 */
405  {
406  return UnregisterClone(pClone);
407  }
408 
409 
410 /*!
411 @brief Unregisters a <tt>AtomicSharingClone</tt>.
412 @details If a send is in progress, this function waits until the send is complete before unregistering.
413 Even if this function succeeds, <tt><var>AtomicSharingClone</var></tt> cannot be reused or reregistered to the same ID until <tt>AtomicSharingClone::IsRegisteredWithProtocol</tt> returns <tt>false</tt>.
414 (The object may send without acquiring a lock for other reasons, for example when serving as a proxy when a station is improperly disconnected.)
415 @param[in] cloneId Specifies the ID of the <tt>AtomicSharingClone</tt> to unregister.
416 @return Returns a <tt>Result</tt> value for which the <tt>IsSuccess</tt> function returns <tt>true</tt> if execution succeeds.
417 @retval ResultNotInitialized Indicates that the instance is not initialized. Programming error. Fix your program so that this error is not returned.
418 @retval ResultNotSet Indicates that the object is not registered to the specified ID. Programming error. Fix your program so that this error is not returned.
419 
420 */
422  {
423  return UnregisterClone(AtomicSharingClone::ToKey(cloneId));
424  }
425 
426 
427 /*!
428 @brief Searches for and gets the <tt>AtomicSharingClone</tt> object with the specified ID.
429 @param[in] cloneId Specifies the ID of the <tt>AtomicSharingClone</tt> to search for.
430 @return Returns the <tt>AtomicSharingClone</tt> with the specified ID. Returns <tt>NULL</tt> when an object with the specified ID cannot be found.
431 */
433  {
434  return static_cast<AtomicSharingClone*>(m_CloneCollection.Find(AtomicSharingClone::ToKey(cloneId)));
435  }
436 
437 
438 /*!
439 @brief Searches for and gets the <tt>AtomicSharingClone</tt> object with the specified ID.
440 @param[in] cloneId Specifies the ID of the <tt>AtomicSharingClone</tt> to search for.
441 @return Returns the <tt>AtomicSharingClone</tt> with the specified ID. Returns <tt>NULL</tt> when an object with the specified ID cannot be found.
442 */
444  {
445  return static_cast<const AtomicSharingClone*>(m_CloneCollection.Find(AtomicSharingClone::ToKey(cloneId)));
446  }
447 
448 
449 /*!
450 @brief Registers a <tt>SequentialSharingClone</tt> to the specified ID.
451 @param[in] pClone Specifies the <tt>SequentialSharingClone</tt> to register.
452 @param[in] cloneId Specifies the ID to register to.
453 @return Returns a <tt>Result</tt> value for which the <tt>IsSuccess</tt> function returns <tt>true</tt> if execution succeeds.
454 @retval ResultNotInitialized Indicates that the instance is not initialized. Programming error. Fix your program so that this error is not returned.
455 @retval ResultInvalidArgument Indicates that an argument is invalid. Programming error. Fix your program so that this error is not returned.
456 @retval ResultAlreadyExists Indicates that the object is already registered to the specified ID. Programming error. Fix your program so that this error is not returned.
457 */
459  {
460  return RegisterClone(SequentialSharingClone::ToKey(cloneId), pClone);
461  }
462 
463 
464 /*!
465 @brief Unregisters a <tt>SequentialSharingClone</tt>.
466 @details If a send is in progress, this function waits until the send is complete before unregistering.
467 Even if this function succeeds, <tt><var>pClone</var></tt> cannot be reused or re-registered to the same ID until <tt>pClone->@ref SequentialSharingClone::IsRegisteredWithProtocol "IsRegisteredWithProtocol"</tt> returns <tt>false</tt>.
468 @param[in] pClone Specifies the <tt>SequentialSharingClone</tt> to unregister.
469 @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.
470 @retval ResultNotInitialized Indicates that the instance is not initialized. Programming error. Fix your program so that this error is not returned.
471 @retval ResultInvalidArgument Indicates that an argument is invalid. The specified <tt>AtomicSharingClone</tt> is not registered to this <tt>CloneProtocol</tt>. Programming error. Fix your program so that this error is not returned.
472 
473 */
475  {
476  return UnregisterClone(pClone);
477  }
478 
479 
480 /*!
481 @brief Unregisters a <tt>SequentialSharingClone</tt>.
482 @details If a send is in progress, this function waits until the send is complete before unregistering.
483 Even if this function succeeds, <tt><var>SequentialSharingClone</var></tt> cannot be reused or reregistered to the same ID until <tt>SequentialSharingClone::IsRegisteredWithProtocol</tt> returns <tt>false</tt>.
484 @param[in] cloneId Specifies the ID of the <tt>SequentialSharingClone</tt> to unregister.
485 @return Returns a <tt>Result</tt> value for which the <tt>IsSuccess</tt> function returns <tt>true</tt> if execution succeeds.
486 @retval ResultNotInitialized Indicates that the instance is not initialized. Programming error. Fix your program so that this error is not returned.
487 @retval ResultNotSet Indicates that the object is not registered to the specified ID. Programming error. Fix your program so that this error is not returned.
488 
489 */
491  {
492  return UnregisterClone(SequentialSharingClone::ToKey(cloneId));
493  }
494 
495 
496 /*!
497 @brief Searches for and gets the <tt>SequentialSharingClone</tt> object with the specified ID.
498 @param[in] cloneId Specifies the ID of the <tt>SequentialSharingClone</tt> to search for.
499 @return Returns the <tt>SequentialSharingClone</tt> with the specified ID. Returns <tt>NULL</tt> when an object with the specified ID cannot be found.
500 */
502  {
503  return static_cast<SequentialSharingClone*>(m_CloneCollection.Find(SequentialSharingClone::ToKey(cloneId)));
504  }
505 
506 
507 /*!
508 @brief Searches for and gets the <tt>SequentialSharingClone</tt> object with the specified ID.
509 @param[in] cloneId Specifies the ID of the <tt>SequentialSharingClone</tt> to search for.
510 @return Returns the <tt>SequentialSharingClone</tt> with the specified ID. Returns <tt>NULL</tt> when an object with the specified ID cannot be found.
511 */
513  {
514  return static_cast<const SequentialSharingClone*>(m_CloneCollection.Find(SequentialSharingClone::ToKey(cloneId)));
515  }
516 
517 
518 /*!
519 @cond PRIVATE
520 @brief Starts communication.
521 
522 @param[in] localStationIndex Specifies the <tt>StationIndex</tt> of the local station. Specify a value in the range from <tt>STATION_INDEX_1</tt> to <tt><var>maxConnections</var></tt>.
523 
524 @return Returns a <tt>Result</tt> value for which the <tt>IsSuccess</tt> function returns <tt>true</tt> if execution succeeds.
525 
526 @retval ResultNotInitialized Indicates that the instance is not initialized. Programming error. Fix your program so that this error is not returned.
527 @retval ResultInvalidState Indicates that stations are already communicating. Programming error. Fix your program so that this error is not returned.
528 @retval ResultInvalidArgument Indicates that an argument is invalid. Programming error. Fix your program so that this error is not returned.
529 */
530  virtual nn::Result Startup(StationIndex localStationIndex);
531  //! @endcond
532 
533 
534 /*!
535 @cond PRIVATE
536 @brief Ends communication.
537 */
538  virtual void Cleanup();
539  //! @endcond
540 
541 
542 /*!
543 @cond PRIVATE
544 @brief The main process.
545 
546 @return Returns <tt>nn::ResultSuccess</tt>.
547 */
548  virtual nn::Result Dispatch();
549  //! @endcond
550 
551 
552 /*!
553 @cond PRIVATE
554 @brief Switches the connection status.
555 
556 @param[in] event Specifies the event representing the operation.
557 
558 @return Returns a <tt>Result</tt> value for which the <tt>IsSuccess</tt> function returns <tt>true</tt> if execution succeeds.
559 
560 @retval ResultInvalidState Indicates that the function was called in an invalid state. Programming error. Fix your program so that this error is not returned.
561 @retval ResultInvalidArgument Indicates that an argument is invalid. Programming error. Fix your program so that this error is not returned.
562 */
563  virtual nn::Result UpdateProtocolEvent(const transport::ProtocolEvent& event);
564  //! @endcond
565 
566 
567 /*!
568 @brief Enumerates the operational states of <tt>CloneProtocol</tt>.
569 */
570  enum State
571  {
572  STATE_INACTIVE = 0x10, //!< Specifies inactive.
573  STATE_START = 0x20, //!< Specifies starting up.
574  STATE_ACTIVE = 0x30, //!< Specifies active.
575  STATE_STOP = 0x40 //!< Specifies stopping.
576  };
577 
578 
579 /*!
580 @brief Gets the current operational state.
581 @return Returns the current operational state.
582 */
583  State GetState() const
584  {
585  return static_cast<State>(m_InnerState & cStateMask);
586  }
587 
588 
589 /*!
590 @brief Determines whether the <tt>CloneProtocol</tt> of the specified station is active.
591 @param[in] stationId Specifies the <tt>@ref StationId</tt> of the station to be checked if active.
592 @return Returns <tt>true</tt> if the specified station is active.
593 */
594  bool IsActiveStation(StationId stationId) const;
595 
596 
597 /*!
598 @brief Starts operation of <tt>CloneProtocol</tt>.
599 @details This function can be called when the operational state is <tt>@ref STATE_INACTIVE</tt> after communication starts.
600 When this function succeeds, the object state changes to <tt>@ref STATE_START</tt> and begins the startup process, after which it transitions to <tt>@ref STATE_ACTIVE</tt>.
601 After calling this function, you must periodically call the <tt>UpdateClock</tt> function.
602 @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.
603 @retval ResultInvalidState Indicates that the station is not communicating or the state is not <tt>@ref nn::pia::clone::CloneProtocol::STATE_INACTIVE "STATE_INACTIVE"</tt>. Programming error. Fix your program so that this error is not returned.
604 */
605  nn::Result Start();
606 
607 
608 /*!
609 @brief Stops operation of <tt>CloneProtocol</tt>.
610 @details When this function is called while the operational state is <tt>@ref STATE_START</tt> or <tt>@ref STATE_ACTIVE</tt>, the state changes to <tt>@ref STATE_STOP</tt> and then to <tt>@ref STATE_INACTIVE</tt> after finalization is complete.
611 You must continue to call the <tt>UpdateClock</tt> function while the state is <tt>@ref STATE_STOP</tt>.
612 This function does nothing if called while the state is <tt>@ref STATE_INACTIVE</tt> or <tt>@ref STATE_STOP</tt>.
613 @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.
614 @retval ResultInvalidState Indicates that communication is not active. Programming error. Fix your program so that this error is not returned.
615 */
616  nn::Result Stop();
617 
618 
619 /*!
620 @brief Advances the clock by one frame.
621 @details The clock managed by <tt>CloneProtocol</tt> only advances when this function is called.
622 Be sure to call this function periodically while the operational state is either <tt>@ref STATE_START</tt>, <tt>@ref STATE_ACTIVE</tt>, or <tt>@ref STATE_STOP</tt>.
623 Set the amount each call advances the clock in the <tt>Setting</tt> object that is specified when calling the <tt>Initialize</tt> function.
624 If the interval between calls is shorter than the precision of the clock value, the clock may stay the same but it never goes backward.
625 @see GetClock
626 */
627  void UpdateClock();
628 
629 
630 /*!
631 @brief Gets the current clock.
632 @return Returns the current clock. Returns <tt>@ref INVALID_CLOCK</tt> if a valid clock does not exist because, for example, the object is not active.
633 @see UpdateClock
634 */
635  ClockValue GetClock() const;
636 
637 
638 /*!
639 @brief Starts re-regulating the clock.
640 @details The clock managed by the <tt>CloneProtocol</tt> for this station is re-adjusted to be in line with the average clock of the other stations.
641 Discrepancies are fixed by advancing the clock at a faster or slower rate than usual after examining the clocks of the other stations.
642 The rate itself is set in the <tt>Setting::clockRegulationRate</tt> member of the <tt>Setting</tt> object that is specified when the <tt>Initialize</tt> function is called.
643 @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.
644 @retval ResultInvalidState Indicates that the state is not <tt>@ref nn::pia::clone::CloneProtocol::STATE_ACTIVE "STATE_ACTIVE"</tt> or the clock is already being regulated. Programming error. Fix your program so that this error is not returned.
645 @see IsRegulatingClock
646 */
647  nn::Result RegulateClock();
648 
649 
650 /*!
651 @brief Gets whether the clock is being regulated.
652 @return Returns <tt>true</tt> if the clock is being regulated..
653 @see RegulateClock
654 */
655  bool IsRegulatingClock() const;
656 
657 
658 /*!
659 @brief (For debugging.) Sets the time until the clock value overflows.
660 
661 @details Sets the time from when synchronous communication starts until the clock value overflows.
662 @details This function is for debugging. Do not include it in retail products.
663 
664 @param[in] span If the <tt>@ref Setting::ClockType</tt> is <tt>@ref Setting::CLOCK_TYPE_RTC</tt>, this is the time (in seconds). If it is <tt>@ref Setting::CLOCK_TYPE_FRAME</tt>, this is the number of frames.
665 @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.
666 @retval ResultNotInitialized Indicates that the instance is not initialized. Programming error. Fix your program so that this error is not returned.
667 */
668  nn::Result SetClockOverFlowSpanForDebug(u32 span);
669 
670 
671 /*!
672 @brief Enumerates the error state.
673 */
675  {
676  ERROR_TYPE_NOTHING = 0, //!< Specifies no error.
677  ERROR_TYPE_DROP_EVENT, //!< Specifies an inconsistency in event management. Some event notifications may not have been sent.
678  //!< This error can occur when <tt>EventCloneElement</tt> is used with <tt>AtomicSharingClone</tt>.
679  ERROR_TYPE_CLOCK_OVERFLOW //!< Specifies the clock value overflowed. Widespread inconsistencies may be occurring.
680  };
681 
682 
683 /*!
684 @brief Gets the error state.
685 @details When an error occurs, the values being sent or received may be invalid. We recommend stopping the match and ending the session with the <tt>Stop</tt> function.
686 This value is reset when the <tt>Start</tt> function is called again.
687 When multiple error types occur, the one with the highest <tt>@ref ErrorType</tt> takes precedence.
688 @return Returns the error state.
689 
690 */
692  {
693  return m_Error;
694  }
695 
696 
697 /*!
698 @brief Sets the maximum time to defer the sending of data.
699 @details In some clone elements, you can specify whether to send data immediately after it is set, or to wait until there is other data to send.
700 Even if you defer the sending, the data is sent by itself when the time specified here elapses.
701 Deferring the sending of data can be expected to reduce the number of packets sent, but it takes longer for the data to arrive after it is set.
702 @param[in] maxSendDelay Specifies the maximum time to defer sending. The value is in milliseconds. The maximum value that can be specified is <tt>10000</tt>.
703 @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.
704 @retval ResultNotInitialized Indicates that the instance is not initialized. Programming error. Fix your program so that this error is not returned.
705 @retval ResultInvalidArgument Indicates that an argument is invalid. Programming error. Fix your program so that this error is not returned.
706 @see GetMaxSendDelay
707 */
708  nn::Result SetMaxSendDelay(u16 maxSendDelay);
709 
710 
711 /*!
712 @brief Gets the maximum time to defer the sending of data.
713 @return Returns the maximum time to defer the sending of data. The value is in milliseconds.
714 @see SetMaxSendDelay
715 */
716  u16 GetMaxSendDelay() const
717  {
718  return m_MaxSendDelay;
719  }
720 
721 
722 /*!
723 @brief Specifies the ratio of the resend interval for the base RTT obtained from profiling.
724 @details The default value of the ratio is 1.25. The resend interval is the value of (RTT * <tt><var>ratio</var></tt>). The maximum value of the resend interval is 2500 milliseconds.
725 @param[in] ratio The ratio of the resend interval for the base RTT obtained from profiling Specify a value larger than <tt>0</tt>.
726 @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.
727 @retval ResultNotInitialized Indicates that the instance is not initialized. Programming error. Fix your program so that this error is not returned.
728 @retval ResultInvalidArgument Indicates that an argument is invalid. Programming error. Fix your program so that this error is not returned.
729 */
730  nn::Result SetResendSpanRatio(f32 ratio);
731 
732 
733  //! @name Profiling
734  //! @{
735 
736 /*!
737 @brief Sets an object to manage send/receive profiling.
738 @details <tt>CloneProtocol</tt> send/receive tasks can be profiled by configuring <tt>CloneProfiler</tt>.
739 This calculation includes the data <tt>CloneProtocol</tt> actually sends through and receives from the communication pathway.
740 In clone profiling, the data the local station sends and receives is included in the calculation, but this data is resolved in <tt>CloneProtocol</tt> and is not included in the <tt>CloneProtocol</tt> profiling calculations.
741 @details When compression is enabled, the compressed size is used in the calculation.
742 @details A <tt>CloneProfiler</tt> instance that is already configured can be released by specifying <tt>NULL</tt> in the arguments.
743 @param[in] pSendProfiler Specifies the <tt>CloneProfiler</tt> that manages the send profiling.
744 Specify <tt>NULL</tt> if not necessary.
745 @param[in] pReceiveProfiler Specifies the <tt>CloneProfiler</tt> that manages the receive profiling.
746 Specify <tt>NULL</tt> if not necessary.
747 @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.
748 @retval ResultNotInitialized Indicates that the instance is not initialized. Programming error. Fix your program so that this error is not returned.
749 @retval ResultInvalidArgument Indicates that an argument is invalid. Programming error. Fix your program so that this error is not returned.
750 
751 */
752  nn::Result SetProfiler(CloneProfilerBase* pSendProfiler, CloneProfilerBase* pReceiveProfiler);
753 
754 
755 /*!
756 @brief Gets the object configured to manage send profiling.
757 @return The object configured to manage send profiling. Returns <tt>NULL</tt> if nothing has been set.
758 @see SetProfiler
759 */
761  {
762  return m_pSendProfiler;
763  }
764 
765 
766 /*!
767 @brief Gets the object configured to manage receive profiling.
768 @return The object configured to manage receive profiling. Returns <tt>NULL</tt> if nothing has been set.
769 @see SetProfiler
770 */
772  {
773  return m_pReceiveProfiler;
774  }
775 
776 
777 /*!
778 @brief Resets the results of send/receive profiling.
779 @see SetProfiler
780 */
781  void ResetProfiler();
782 
783 
784 /*!
785 @brief Gets the send count for the last <tt>@ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE"</tt> times <tt>common::Scheduler::Dispatch</tt> was called.
786 @param[in] stationIndex The <tt>StationIndex</tt> that is subject to profiling.
787 @return The send count for the last <tt>@ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE"</tt> times <tt>common::Scheduler::Dispatch</tt> was called.
788 Returns <tt>0</tt> if no object is configured to manage send profiling.
789 @see SetProfiler
790 */
791  u32 GetProfiledLatestSendCount(StationIndex stationIndex) const;
792 
793 
794 /*!
795 @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.
796 @param[in] stationIndex The <tt>StationIndex</tt> that is subject to profiling.
797 @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.
798 Returns <tt>0</tt> if no object is configured to manage send profiling.
799 @see SetProfiler
800 */
801  u32 GetProfiledLatestSendSize(StationIndex stationIndex) const;
802 
803 
804 /*!
805 @brief Gets the number of times sent since <tt>ResetProfiler</tt> was called.
806 @param[in] stationIndex The <tt>StationIndex</tt> that is subject to profiling.
807 @return The number of times sent since <tt>ResetProfiler</tt> was called.
808 Returns <tt>0</tt> if no object is configured to manage send profiling.
809 @see SetProfiler, ResetProfiler
810 */
811  u32 GetProfiledTotalSendCount(StationIndex stationIndex) const;
812 
813 
814 /*!
815 @brief Gets the amount of data, in bytes, sent since <tt>ResetProfiler</tt> was called.
816 @param[in] stationIndex The <tt>StationIndex</tt> that is subject to profiling.
817 @return The amount of data, in bytes, sent since <tt>ResetProfiler</tt> was called.
818 Returns <tt>0</tt> if no object is configured to manage send profiling.
819 @see SetProfiler, ResetProfiler
820 */
821  u32 GetProfiledTotalSendSize(StationIndex stationIndex) const;
822 
823 
824 /*!
825 @brief Gets the receive count for the last <tt>@ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE"</tt> times <tt>common::Scheduler::Dispatch</tt> was called.
826 @param[in] stationIndex The <tt>StationIndex</tt> that is subject to profiling.
827 @return The receive count for the last <tt>@ref CloneProfiler "CloneProfiler::LATEST_BUFFER_SIZE"</tt> times <tt>common::Scheduler::Dispatch</tt> was called.
828 Returns <tt>0</tt> if no object is configured to manage receive profiling.
829 @see SetProfiler
830 */
831  u32 GetProfiledLatestReceiveCount(StationIndex stationIndex) const;
832 
833 
834 /*!
835 @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.
836 @param[in] stationIndex The <tt>StationIndex</tt> that is subject to profiling.
837 @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.
838 Returns <tt>0</tt> if no object is configured to manage receive profiling.
839 @see SetProfiler
840 */
841  u32 GetProfiledLatestReceiveSize(StationIndex stationIndex) const;
842 
843 
844 /*!
845 @brief Gets the number of times received since <tt>ResetProfiler</tt> was called.
846 @param[in] stationIndex The <tt>StationIndex</tt> that is subject to profiling.
847 @return The number of times received since <tt>ResetProfiler</tt> was called.
848 Returns <tt>0</tt> if no object is configured to manage receive profiling.
849 @see SetProfiler, ResetProfiler
850 */
851  u32 GetProfiledTotalReceiveCount(StationIndex stationIndex) const;
852 
853 
854 /*!
855 @brief Gets the amount of data, in bytes, received since <tt>ResetProfiler</tt> was called.
856 @param[in] stationIndex The <tt>StationIndex</tt> that is subject to profiling.
857 @return The amount of data, in bytes, received since <tt>ResetProfiler</tt> was called.
858 Returns <tt>0</tt> if no object is configured to manage receive profiling.
859 @see SetProfiler, ResetProfiler
860 */
861  u32 GetProfiledTotalReceiveSize(StationIndex stationIndex) const;
862 
863  //! @}
864 
865 
866 /*!
867 @brief Prints information that is useful for debugging.
868 
869 @param[in] flag Specifies the bitwise OR of trace flags. For more information, see the <tt>@ref TraceFlag</tt> type.
870 */
871  virtual void Trace(u64 flag) const;
872 
873 
874 public:
875 /*!
876 @cond PRIVATE
877 @brief Gets the resend interval. (For debugging.)
878 */
879  SystemTime GetResendSpan() const
880  {
881  return m_ResendSpan;
882  }
883  //! @endcond
884 
885 /*!
886 @cond PRIVATE
887 @brief Gets the send interval used in unicasts. (For debugging.)
888 */
889  SystemTime GetResendSpanForUnicast(StationIndex stationIndex) const
890  {
891  return m_ResendSpanForUnicast[stationIndex];
892  }
893  //! @endcond
894 
895  u32 GetStationNum() const
896  {
897  return m_StationNum;
898  }
899 
900  //! @cond PRIVATE
901 
902 private:
903  static int SimpleClockPriorityJudgeFunction(ClockValue clock, StationIndex stationA, StationIndex stationB);
904  static int ImpartialClockPriorityJudgeFunction(ClockValue clock, StationIndex stationA, StationIndex stationB);
905 
906 public:
907  StationIndex GetLocalStationIndex() const
908  {
909  return m_LocalStationIndex;
910  }
911  u32 GetParticipantBitmap() const
912  {
913  return m_ParticipantBitmap;
914  }
915  SystemTime GetSystemTime() const
916  {
917  return m_SystemTime;
918  }
919  u32 GetDispatchCount() const
920  {
921  return m_DispatchCount;
922  }
923 
924  void ErrorDropEvent()
925  {
926  SetError(ERROR_TYPE_DROP_EVENT);
927  }
928 
929  // n2920: Added for <tt>CloneBase</tt> to reference.
930  u32 GetValidStationBitmap() const
931  {
932  return m_ValidStationBitmap;
933  }
934 
935  u32 GetNoticeParticipationBitmap() const
936  {
937  return m_NoticeParticipationBitmap;
938  }
939 
940 private:
941  bool IsInitialized() const
942  {
943  return (m_StationNum > 0);
944  }
945  bool IsInCommunication() const
946  {
947  return m_LocalStationIndex != STATION_INDEX_INVALID;
948  }
949 
950  enum InnerState
951  {
952  eISInactive = STATE_INACTIVE | 0x1,
953  eISSyncClock = STATE_START | 0x1,
954  eISNoticeStart = STATE_START | 0x2,
955  eISActive = STATE_ACTIVE | 0x1,
956  eISComplete = STATE_STOP | 0x1,
957  eISStop = STATE_STOP | 0x2
958  };
959  InnerState GetInnerState() const
960  {
961  return m_InnerState;
962  }
963 
964  void UpdateCloneState();
965  void UpdateState();
966  void UpdateResendSpan();
967 
968  void ReceiveMessages();
969  void ReceiveMessage(StationIndex src, const void* cpMessage, size_t size);
970  bool UpdateReceivedMessageSequentialId(StationIndex src, const void* cpMessage);
971 
972  bool SendUnicastMessage(StationIndex dest, void* pMessage, size_t messageSize);
973  bool SendMulticastMessage(u32 destBitmap, void* pMessage, size_t messageSize);
974  void SetSequentialIdToMessage(void* pMessage);
975 
976  bool SendUnicastCloneCommand(StationIndex dest, CloneBase::Type cloneType, StationIndex cloneStationIndex, CloneBase::Id cloneId, u8 command);
977  bool SendUnicastClockCloneCommand(StationIndex dest, CloneBase::Type cloneType, StationIndex cloneStationIndex, CloneBase::Id cloneId, u8 command, ClockValue clock);
978  bool SendUnicastClockAndCountCloneCommand(StationIndex dest, CloneBase::Type cloneType, StationIndex cloneStationIndex, CloneBase::Id cloneId, u8 command, ClockValue clock, u8 count);
979  bool SendUnicastClockAndCountAndParticipantCloneCommand(StationIndex dest, CloneBase::Type cloneType, StationIndex cloneStationIndex, CloneBase::Id cloneId, u8 command, ClockValue clock, u8 count, u32 participantBitmap);
980 
981  void UpdateSystemTime();
982 
983  void SendClockRequest();
984  void ReceiveClockRequest(StationIndex src, const void* cpMessage, size_t size);
985  void ReceiveClockReplyMessage(StationIndex src, const void* cpMessage, size_t size);
986 
987  void NoticeParticipation();
988  void ReceiveEnterMessage(StationIndex src, const void* cpMessage, size_t size);
989  void ReceiveExitMessage(StationIndex src, const void* cpMessage, size_t size);
990  void ReceiveEnterAckMessage(StationIndex src, const void* cpMessage, size_t size);
991  void ReceiveExitAckMessage(StationIndex src, const void* cpMessage, size_t size);
992 
993  struct DispatchCountData
994  {
995  public:
996  void Clear()
997  {
998  m_MyCount = cInvalidDispatchCount;
999  m_ReceivedCount = 0;
1000  }
1001  u32 m_MyCount;
1002  u16 m_ReceivedCount;
1003  };
1004 
1005 private:
1006  size_t m_ElementSizeMax;
1007 
1008  u32 m_StationNum;
1009  StationIndex m_LocalStationIndex;
1010  u32 m_ValidStationBitmap; // Bitmap to directly link to CONNECT and DISCONNECT.
1011  u32 m_ParticipantBitmap; // Consider the bitmap this way: <tt>CloneProtocol</tt> joins when it receives <tt>eMTEnter</tt> and does not join when it receives <tt>eMTExit</tt>.
1012  InnerState m_InnerState;
1013 
1014  Clock* m_pClock;
1015 
1016  SystemTime m_SystemTime;
1017  SystemTime m_ResendSpan;
1018  SystemTime m_ResendSpanForUnicast[MAX_STATION_NUM];
1019  f32 m_ResendSpanRatio;
1020  SystemTime m_LastUpdateResendSpanTime;
1021  SystemTime m_LastParticipationCommandTime;
1022  SystemTime m_LastClockCommandTime;
1023 
1024  SystemTime m_MaxSendDelay;
1025 
1026  static const SystemTime cDefaultResendSpan = 500;
1027 
1028  u32 m_DispatchCount;
1029  DispatchCountData* m_paReceivedDispatchCount;
1030  static const u32 cCheckDispatchCount = 0x00003fff;
1031 
1032 public:
1033  static const u32 cInvalidDispatchCount = 0xffffffff;
1034 
1035 private:
1036  enum
1037  {
1038  cStateMask = 0xf0
1039  };
1040 
1041  u32 m_NoticeParticipationBitmap; // The bitmap that Ack by peers checks when the local station calls <tt>Start()</tt> and <tt>Stop()</tt> on <tt>CloneProtocol</tt>.
1042 
1043 private:
1044  nn::Result RegisterClone(CloneBase::Key key, CloneBase* pClone);
1045  nn::Result UnregisterClone(CloneBase::Key key);
1046  nn::Result UnregisterClone(CloneBase* pClone);
1047 
1048  typedef common::OffsetTreeMap<CloneBase::Key, CloneBase> CloneCollection;
1049  CloneCollection m_CloneCollection;
1050 
1051 
1052 public:
1053  void AddSendCommand(CloneBase::CommandToken* pToken);
1054  void CancelSendCommand(CloneBase::CommandToken* pToken);
1055 
1056 private:
1057  void SendCommand();
1058  u32 SendCommandCore(CloneBase::CommandToken* pToken, bool isUnicast, u32 destBitmap, void* pMessage, size_t messageSize);
1059 
1060  typedef common::OffsetList<CloneBase::CommandToken> CommandTokenList;
1061  CommandTokenList m_SendCommandTokenList;
1062  CommandTokenList m_ResendCommandTokenList;
1063 
1064 public:
1065  void AddSendData(CloneBase::DataToken* pToken);
1066  void CancelSendData(CloneBase::DataToken* pToken);
1067 
1068 private:
1069  void SendData();
1070  bool SendCloneData(CloneBase::DataToken* pToken);
1071  void ReceiveData(StationIndex src, CloneBase* pClone, const void* cpMessage, size_t messageSize);
1072 
1073  typedef common::OffsetList<CloneBase::DataToken> DataTokenList;
1074  DataTokenList m_DataTokenList;
1075 
1076  struct DataMessageBuffer
1077  {
1078  public:
1079  void Clear()
1080  {
1081  m_DestBitmap = 0;
1082  m_Size = 0;
1083  }
1084 
1085  u32 m_DestBitmap;
1086  u16 m_Size;
1087  u16 m_Dummy;
1088  u8 m_Message[common::PROTOCOL_MESSGAE_PAYLOAD_SIZE_MAX];
1089  };
1090 
1091  DataMessageBuffer m_DataMessageBuffer;
1092  IDataPacker* m_pDataPacker;
1093  IDataUnpacker* m_pDataUnpacker;
1094  CompressDataUnpacker* m_pCompressedDataUnpacker;
1095 
1096 public:
1097  ClockPriorityJudgeFunction GetClockPriorityJudgeFunction() const
1098  {
1099  return m_ClockPriorityJudgeFunction;
1100  }
1101 
1102 private:
1103  ClockPriorityJudgeFunction m_ClockPriorityJudgeFunction;
1104 
1105 private:
1106  void SetError(ErrorType errorType);
1107 
1108  ErrorType m_Error;
1109 
1110 private:
1111  CloneProfilerBase* m_pSendProfiler;
1112  CloneProfilerBase* m_pReceiveProfiler;
1113 
1114  u32 m_SendMessageSequentialId;
1115  u32 m_ReceivedMessageSequentialId[MAX_STATION_NUM];
1116 #if NN_PIA_ENABLE_TRACE
1117  // If the same <tt>SequentialId</tt> is received twice in a row, the first is for message information tracing.
1118  struct MessageHeaderForDebug
1119  {
1120  u8 m_FormatVersion;
1121  u8 m_MessageType;
1122  u16 m_DispatchCount;
1123  };
1124  MessageHeaderForDebug m_ReceivedMessageHeaderForDebug[MAX_STATION_NUM];
1125 #endif
1126 
1127 public:
1128  typedef bool (*ReceiveElementFunction)(CloneElementBase* pElement, IDataPacker* pAckPacker, const void* cpChunk, u16 chunkSize, CloneElementBase::Id elementId, StationIndex src, StationIndex localStationIndex, u32 dispatchCount);
1129 
1130  class ElementDefinition
1131  {
1132  public:
1133  ElementDefinition();
1134  void Register(u16 type, ReceiveElementFunction receiveFunction, size_t dataChunkHeaderSize);
1135  ReceiveElementFunction GetReceiveFunction(u16 type) const;
1136  size_t GetDataChunkHeaderSizeMax() const
1137  {
1138  return m_DataChunkHeaderSizeMax;
1139  }
1140  static const u32 cTypeNum = 16;
1141 
1142  private:
1143  ReceiveElementFunction m_aReceiveFunction[cTypeNum];
1144  size_t m_DataChunkHeaderSizeMax;
1145  };
1146 
1147  static ElementDefinition* GetElementDefinition();
1148 
1149 
1150 protected:
1151  virtual Clock* CreateRtcClock(f32 clockPerSec, f32 regulationRate);
1152  virtual size_t TransportGetMaxStationNum();
1153  virtual size_t PayloadSizeManagerGetMtuSize();
1154  virtual size_t SignatureManagerGetSignatureSizeMax();
1155  virtual const common::Time& TransportGetDispatchedTime();
1156  virtual s32 StationGetRtt(StationIndex stationId);
1157  virtual s32 StationGetRttPulseInterval();
1158  virtual size_t PacketHandlerGetPayloadSizeLimit();
1159  virtual bool PacketHandlerSendMessageById(StationIndex dest, const void* cpData, size_t size);
1160  virtual bool PacketHandlerSendMessageByBitmap(u32 destBitmap, const void* cpData, size_t size);
1161  virtual void PacketHandlerReadIterationBegin(void** ppIterator);
1162  virtual bool PacketHandlerReadIterationIsEnd(const void* cpIterator);
1163  virtual void PacketHandlerReadIterationNext(void* pIterator);
1164  virtual void PacketHandlerReadIteratorGet(StationIndex* pSrc, const void** cppPayloadPtr, size_t* pPayloadSize, const void* cpIterator);
1165 
1166 public:
1167  template <int TEST_ID, typename Arg>
1168  static void Test(const CloneProtocol& obj, Arg* pArg = NULL);
1169 
1170 private:
1171  // n2920: For the client-monitoring feature.
1172  u32 m_UpdateCount;
1173  u32 m_ResendCount;
1174  nn::pia::common::Time m_ActivationStartTime;
1175  u32 m_CompCount;
1176  f32 m_CompRateTotal;
1177  f32 m_CompAverage;
1178  u32 m_SendCount;
1179  u32 m_SendDataTotal;
1180 
1181  //! @endcond
1182 };
1183 }
1184 }
1185 } // end of namespace nn::pia::clone
nn::Result Initialize(const Setting &setting)
Initialization. Make this call between the BeginSetup and EndSetup functions.
const SendClone * SearchSendClone(CloneBase::Id cloneId) const
Searches for and gets the SendClone object with the specified ID.
Definition: clone_CloneProtocol.h:308
static const u32 COMPRESSION_LEVEL_HIGH
Specifies the compression level (compression rate emphasized) for the data to send specified in Setti...
Definition: clone_CloneProtocol.h:95
This is the base class for managing data that is sent and received. .
Definition: clone_CloneElementBase.h:40
Specifies stopping.
Definition: clone_CloneProtocol.h:575
u32 GetProfiledTotalSendSize(StationIndex stationIndex) const
Gets the amount of data, in bytes, sent since ResetProfiler was called.
f32 clockPerSec
Specifies the value to advance the clock per second.
Definition: clone_CloneProtocol.h:152
Specifies active.
Definition: clone_CloneProtocol.h:574
u32 ClockValue
Defines a type that holds a clock value.
Definition: clone_definitions.h:44
u32 GetProfiledLatestReceiveCount(StationIndex stationIndex) const
Gets the receive count for the last CloneProfiler::LATEST_BUFFER_SIZE times common::Scheduler::Dispat...
nn::Result UnregisterSendClone(CloneBase::Id cloneId)
Unregisters a SendClone.
Definition: clone_CloneProtocol.h:286
Class that represents time.
Definition: common_Time.h:39
StationIndex
Enumerates StationIndex values.
Definition: platformCtr.h:44
Definition of the StationId identifying the station within the session.
Definition: types.h:33
ErrorType GetError() const
Gets the error state.
Definition: clone_CloneProtocol.h:691
bool IsRegulatingClock() const
Gets whether the clock is being regulated.
Specifies that the station with a smaller station ID value was first.
Definition: clone_CloneProtocol.h:177
size_t GetElementSizeMax() const
Gets the maximum value that can be retrieved from the SerializePolicy::GetSize function of the clone ...
Definition: clone_CloneProtocol.h:239
SequentialSharingClone * SearchSequentialSharingClone(CloneBase::Id cloneId)
Searches for and gets the SequentialSharingClone object with the specified ID.
Definition: clone_CloneProtocol.h:501
Definition: assert.h:115
nn::Result RegisterSendClone(SendClone *pClone, CloneBase::Id cloneId)
Registers a SendClone to the specified ID.
Definition: clone_CloneProtocol.h:254
ID indicating a station that is not present in the session.
Definition: platformCtr.h:59
This class is a derivative of CloneBase and provides functionality for managing unidirectional sendin...
Definition: clone_SendClone.h:33
nn::Result RegisterReceiveClone(ReceiveClone *pClone, StationIndex sendStationIndex, CloneBase::Id cloneId)
Registers a ReceiveClone to the specified ID.
const CloneProfilerBase * GetSendProfiler() const
Gets the object configured to manage send profiling.
Definition: clone_CloneProtocol.h:760
Specifies starting up.
Definition: clone_CloneProtocol.h:573
f32 clockRegulationRate
Specifies the rate at which to speed up or slow down the clock when re-regulating the clock...
Definition: clone_CloneProtocol.h:169
ErrorType
Enumerates the error state.
Definition: clone_CloneProtocol.h:674
u32 clockPerFrame
Specifies the value to advance the clock per frame.
Definition: clone_CloneProtocol.h:160
Specifies that the clock advances based on the number of times CloneProtocol::UpdateClock is called...
Definition: clone_CloneProtocol.h:126
static const u32 COMPRESSION_LEVEL_LOW
Specifies the compression level (speed emphasized) for the data to send specified in Setting::dataCom...
Definition: clone_CloneProtocol.h:93
Specifies inactive.
Definition: clone_CloneProtocol.h:572
nn::Result UnregisterSequentialSharingClone(CloneBase::Id cloneId)
Unregisters a SequentialSharingClone.
Definition: clone_CloneProtocol.h:490
int(* ClockPriorityJudgeFunction)(ClockValue clock, StationIndex stationA, StationIndex stationB)
Compares the order.
Definition: clone_CloneProtocol.h:89
virtual void Trace(u64 flag) const
Prints information that is useful for debugging.
Represents a protocol for sharing values between stations.
Definition: clone_CloneProtocol.h:51
State
Enumerates the operational states of CloneProtocol.
Definition: clone_CloneProtocol.h:570
bool IsInitialized(void)
Gets whether the clone module is initialized.
This base class manages PiaClone profiling.
Definition: clone_CloneProfilerBase.h:33
This is the base class for managing sending and receiving. .
Definition: clone_CloneBase.h:38
nn::Result RegisterSequentialSharingClone(SequentialSharingClone *pClone, CloneBase::Id cloneId)
Registers a SequentialSharingClone to the specified ID.
Definition: clone_CloneProtocol.h:458
void ResetProfiler()
Resets the results of send/receive profiling.
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
ClockPriorityJudgeFunction clockPriorityJudgeFunction
Specifies the function for determining which station was first when an event occurs at the time clock...
Definition: clone_CloneProtocol.h:196
This class is a derivative of CloneBase and provides functionality for managing unidirectional receiv...
Definition: clone_ReceiveClone.h:34
Specifies no error.
Definition: clone_CloneProtocol.h:676
nn::Result UnregisterReceiveClone(ReceiveClone *pClone)
Unregisters a ReceiveClone.
Definition: clone_CloneProtocol.h:338
Specifies the clock value overflowed. Widespread inconsistencies may be occurring.
Definition: clone_CloneProtocol.h:679
ReceiveClone * SearchReceiveClone(StationIndex sendStationIndex, CloneBase::Id cloneId)
Searches for and gets the ReceiveClone object with the specified ID.
u16 GetMaxSendDelay() const
Gets the maximum time to defer the sending of data.
Definition: clone_CloneProtocol.h:716
Specifies an inconsistency in event management.
Definition: clone_CloneProtocol.h:677
u32 dataCompressionLevel
Specifies the compression level for data to send.
Definition: clone_CloneProtocol.h:208
SendClone * SearchSendClone(CloneBase::Id cloneId)
Searches for and gets the SendClone object with the specified ID.
Definition: clone_CloneProtocol.h:297
AtomicSharingClone * SearchAtomicSharingClone(CloneBase::Id cloneId)
Searches for and gets the AtomicSharingClone object with the specified ID.
Definition: clone_CloneProtocol.h:432
Stores settings specified during initialization.
Definition: clone_CloneProtocol.h:101
u32 GetProfiledTotalSendCount(StationIndex stationIndex) const
Gets the number of times sent since ResetProfiler was called.
void Finalize()
Finalizes the class instance.
nn::Result UnregisterSequentialSharingClone(SequentialSharingClone *pClone)
Unregisters a SequentialSharingClone.
Definition: clone_CloneProtocol.h:474
u32 GetProfiledLatestReceiveSize(StationIndex stationIndex) const
Gets the total amount of data, in bytes, received during the last CloneProfiler::LATEST_BUFFER_SIZE t...
nn::Result UnregisterAtomicSharingClone(CloneBase::Id cloneId)
Unregisters a AtomicSharingClone.
Definition: clone_CloneProtocol.h:421
Protocol base class.
Definition: transport_Protocol.h:44
State GetState() const
Gets the current operational state.
Definition: clone_CloneProtocol.h:583
Specifies that the application defines the method to use.
Definition: clone_CloneProtocol.h:179
nn::Result RegulateClock()
Starts re-regulating the clock.
nn::Result Stop()
Stops operation of CloneProtocol.
ClockPriorityJudgeMethod clockPriorityJudgeMethod
Specifies the method for determining which station was first when an event occurs at the time clock v...
Definition: clone_CloneProtocol.h:188
Specifies that the clock advances based on RTC.
Definition: clone_CloneProtocol.h:125
nn::Result SetProfiler(CloneProfilerBase *pSendProfiler, CloneProfilerBase *pReceiveProfiler)
Sets an object to manage send/receive profiling.
u32 GetProfiledTotalReceiveCount(StationIndex stationIndex) const
Gets the number of times received since ResetProfiler was called.
nn::Result SetMaxSendDelay(u16 maxSendDelay)
Sets the maximum time to defer the sending of data.
Setting()
Instantiates the object with default parameters (default constructor).
Definition: clone_CloneProtocol.h:108
const SequentialSharingClone * SearchSequentialSharingClone(CloneBase::Id cloneId) const
Searches for and gets the SequentialSharingClone object with the specified ID.
Definition: clone_CloneProtocol.h:512
nn::Result RegisterAtomicSharingClone(AtomicSharingClone *pClone, CloneBase::Id cloneId)
Registers a AtomicSharingClone to the specified ID.
Definition: clone_CloneProtocol.h:387
static const u32 COMPRESSION_LEVEL_MIDDLE
Specifies the compression level for the data to send specified in Setting::dataCompressionLevel.
Definition: clone_CloneProtocol.h:94
This class is a derivative of CloneBase and provides functionality for bidirectional sending and rece...
Definition: clone_SequentialSharingClone.h:35
u32 GetProfiledLatestSendCount(StationIndex stationIndex) const
Gets the send count for the last CloneProfiler::LATEST_BUFFER_SIZE times common::Scheduler::Dispatch ...
u32 Id
Specifies the type of the ID for identifying clones.
Definition: clone_CloneBase.h:68
nn::Result UnregisterSendClone(SendClone *pClone)
Unregisters a SendClone.
Definition: clone_CloneProtocol.h:270
This class is a derivative of CloneBase and provides functionality for exclusively controlling the lo...
Definition: clone_AtomicSharingClone.h:33
Specifies that the priority is changed based on the clock value so that no single station has an adva...
Definition: clone_CloneProtocol.h:178
nn::Result UnregisterAtomicSharingClone(AtomicSharingClone *pClone)
Unregisters a AtomicSharingClone.
Definition: clone_CloneProtocol.h:404
void UpdateClock()
Advances the clock by one frame.
static const u32 COMPRESSION_LEVEL_NONE
Specifies the compression level (no compression) for the data to send specified in Setting::dataCompr...
Definition: clone_CloneProtocol.h:92
ClockValue GetClock() const
Gets the current clock.
const CloneProfilerBase * GetReceiveProfiler() const
Gets the object configured to manage receive profiling.
Definition: clone_CloneProtocol.h:771
u32 GetProfiledLatestSendSize(StationIndex stationIndex) const
Gets the total amount of data, in bytes, sent during the last CloneProfiler::LATEST_BUFFER_SIZE times...
ClockType clockType
Specifies the standard to use for advancing the clock.
Definition: clone_CloneProtocol.h:144
ClockPriorityJudgeMethod
Enumerates the method for determining which station was first when an event occurs at the time clock ...
Definition: clone_CloneProtocol.h:175
const AtomicSharingClone * SearchAtomicSharingClone(CloneBase::Id cloneId) const
Searches for and gets the AtomicSharingClone object with the specified ID.
Definition: clone_CloneProtocol.h:443
u16 Id
Specifies the type of the ID for identifying clone elements.
Definition: clone_CloneElementBase.h:59
bool IsActiveStation(StationId stationId) const
Determines whether the CloneProtocol of the specified station is active.
nn::Result Start()
Starts operation of CloneProtocol.
nn::Result SetClockOverFlowSpanForDebug(u32 span)
(For debugging.) Sets the time until the clock value overflows.
nn::Result SetResendSpanRatio(f32 ratio)
Specifies the ratio of the resend interval for the base RTT obtained from profiling.
u32 GetProfiledTotalReceiveSize(StationIndex stationIndex) const
Gets the amount of data, in bytes, received since ResetProfiler was called.
ClockType
Enumerates the standard used for advancing the clock.
Definition: clone_CloneProtocol.h:123