CTR Pia  4.11.3
Game Communication Engine
reckoning_ReckoningCloneElementBase.h
1 /*---------------------------------------------------------------------------*
2  Project: Pia
3  File: reckoning_ReckoningCloneElementBase.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/reckoning/reckoning_definitions.h>
18 #include <pia/clone/clone_CloneElementBase.h>
19 #include <pia/common/common_OffsetList.h>
20 
21 
22 namespace nn
23 {
24 namespace pia
25 {
26 namespace clone
27 {
28 class CloneProtocol;
29 class IDataPacker;
30 }
31 }
32 }
33 
34 
35 namespace nn
36 {
37 namespace pia
38 {
39 namespace reckoning
40 {
41 
42 /*!
43 @brief This is the base class for managing the sending and receiving of data while using dead reckoning.
44 
45 @date 2013-10-28 Initial version.
46 */
48 {
49 public:
50 /*!
51 @brief Destroys the object (destructor).
52 */
53  virtual ~ReckoningCloneElementBase();
54 
55 
56 /*!
57 @brief Gets whether a valid value can be obtained using <tt>@ref ReckoningCloneElement::GetValue "GetValue"</tt>.
58 @return Returns <tt>true</tt> if a valid value can be obtained using <tt>@ref ReckoningCloneElement::GetValue "GetValue"</tt>.
59 */
60  bool IsValidValue();
61 
62 
63 /*!
64 @brief Prints information that is useful for debugging.
65 
66 @param[in] flag Specifies the bitwise OR of trace flags. For more information, see the <tt>@ref TraceFlag</tt> type.
67 */
68  void Trace(u64 flag) const;
69 
70 
71  //! @cond PRIVATE
72 
73 public:
74  virtual u16 GetType() const
75  {
76  return GetTypeStatic();
77  }
78  virtual bool IsSupportedClone(int cloneType) const;
79 
80  static u16 GetTypeStatic()
81  {
82  return TYPE_RECKONING;
83  }
84  static bool Receive(CloneElementBase* pElement, clone::IDataPacker* pAckPacker, const void* cpChunk, u16 chunkSize, Id elementId, StationIndex src, StationIndex myStationIndex, u32 dispatchCount);
85  static size_t GetDataChunkHeaderSize();
86 
87 private:
88  void ReceiveUnreliable(const void* cpData, size_t size, StationIndex src, StationIndex setter, clone::ClockValue clock);
89  void ReceiveReliable(const void* cpData, size_t size, StationIndex src, StationIndex setter, clone::ClockValue clock, u32 destBmp);
90  void ReceiveAck(StationIndex src, StationIndex setter, clone::ClockValue clock);
91 
92 public:
93  virtual void ClearData();
94 
95  virtual void AddDest(StationIndex stationId);
96  virtual void RemoveDest(StationIndex stationId);
97  virtual void Adjust(StationIndex stationId);
98 
99  virtual void RequestInitialData();
100 
101 public:
102  class ReckoningSendToken : public ConversibleResendableSendToken
103  {
104  public:
105  ReckoningSendToken()
106  : ConversibleResendableSendToken()
107  {
108  }
109  void Init(ReckoningCloneElementBase* pElement)
110  {
111  m_pElement = pElement;
112  }
113 
114  virtual Type GetElementType() const
115  {
116  return TYPE_RECKONING;
117  }
118  virtual u32 GetDestBitmap() const
119  {
120  return m_DestBmp;
121  }
122  virtual size_t GetChunkSize() const;
123  virtual void WriteChunk(void* pChunkBuffer) const;
124  virtual CloneElementBase* GetElement()
125  {
126  return m_pElement;
127  }
128 
129  Id GetId() const
130  {
131  return m_pElement->GetId();
132  }
133  size_t GetSize() const
134  {
135  return m_pElement->GetSize();
136  }
137  clone::ClockValue GetClock() const
138  {
139  return m_Clock;
140  }
141  void Serialize(void* pBuffer) const
142  {
143  m_pElement->Serialize(pBuffer, this);
144  }
145 
146  StationIndex GetSetterStationIndex() const
147  {
148  return m_SetterStationIndex;
149  }
150 
151  void SetDestBitmap(u32 destBmp)
152  {
153  m_DestBmp = destBmp;
154  }
155  void SetClock(clone::ClockValue clock)
156  {
157  m_Clock = clock;
158  }
159  void SetSetterStationIndex(StationIndex stationId)
160  {
161  m_SetterStationIndex = stationId;
162  }
163 
164  void AddSendData()
165  {
166  m_pElement->AddSendData(this);
167  }
168  void CancelSendData()
169  {
170  m_pElement->CancelSendData(this);
171  }
172 
173  private:
174  ReckoningCloneElementBase* m_pElement;
175  u32 m_DestBmp;
176  clone::ClockValue m_Clock;
177  StationIndex m_SetterStationIndex;
178  };
179 
180 protected:
181  template <typename Sample>
182  class SampleReckoningSendToken : public ReckoningSendToken
183  {
184  public:
185  SampleReckoningSendToken()
186  : ReckoningSendToken()
187  {
188  }
189  Sample* GetSamplePtr()
190  {
191  return &m_Sample;
192  }
193  const Sample& GetSample() const
194  {
195  return m_Sample;
196  }
197 
198  private:
199  Sample m_Sample;
200  };
201 
202 protected:
203  ReckoningCloneElementBase(ReckoningSendToken** papBuffer, u32 bufferSize);
204 
205 protected:
206  void UpdateValue();
207  nn::Result SetValueCore(bool* pIsSend);
208  ReckoningSendToken* AssignTokenForSend(int* pIdx, bool isResendable);
209 
210  virtual void Serialize(void* pBuffer, const ReckoningSendToken* cpToken) = 0;
211  virtual void ClearValue() = 0;
212  virtual bool EstimateValue(clone::ClockValue clock) = 0;
213 
214  virtual void Deserialize(ReckoningSendToken* pToken, const void* cpData) = 0;
215  virtual void OnUpdateSample(int idx) = 0;
216 
217 protected:
218  class SampleBuffer
219  {
220  public:
221  SampleBuffer(ReckoningSendToken** apBuffer, int size);
222 
223  void Clear();
224  ReckoningSendToken* Get(int idx);
225  const ReckoningSendToken* Get(int idx) const;
226  bool IsHead(ReckoningSendToken* pToken) const
227  {
228  return (pToken == m_apBuffer[m_HeadIdx]);
229  }
230  ReckoningSendToken* Search(clone::ClockValue clock);
231  ReckoningSendToken* Assign(int* pIdx, clone::ClockValue clock);
232  int GetNum() const
233  {
234  return m_Num;
235  }
236 
237  void AddDest(StationIndex stationId, bool IsResponsible);
238  void RemoveDest(StationIndex stationId);
239  void Adjust();
240 
241  private:
242  ReckoningSendToken** m_apBuffer;
243  int m_Size;
244  int m_HeadIdx;
245  int m_Num;
246  };
247 
248  const SampleBuffer& GetSampleBuffer() const
249  {
250  return m_SampleBuffer;
251  }
252 
253  //! @endcond
254 
255 public:
256 /*!
257 @brief Contains member functions used to access values in the sample buffer.
258 @tparam Sample Specifies the sample type.
259 */
260  template <typename Sample>
262  {
263  public:
264  //! @cond PRIVATE
265  explicit SampleAccessor(const SampleBuffer& cBuffer)
266  : m_cBuffer(cBuffer)
267  {
268  }
269  //! @endcond
270 
271 
272 /*!
273 @brief Gets the number of saved samples.
274 */
275  int GetNum() const
276  {
277  return m_cBuffer.GetNum();
278  }
279 
280 
281 /*!
282 @brief Gets the clock for when the sample was set.
283 @param[in] index Specifies the index of the sample. A smaller value indicates a later sample.
284 @return Returns the clock for when the sample was set.
285 */
286  clone::ClockValue GetClock(int index) const
287  {
288  PIA_ASSERT(index >= 0 && index < GetNum());
289  return m_cBuffer.Get(index)->GetClock();
290  }
291 
292 
293 /*!
294 @brief Gets a sample.
295 @param[in] index Specifies the index of the sample. A smaller value indicates a later sample.
296 @return Returns the sample.
297 */
298  const Sample& GetSample(int index) const
299  {
300  PIA_ASSERT(index >= 0 && index < GetNum());
301  return static_cast<const SampleReckoningSendToken<Sample>*>(m_cBuffer.Get(index))->GetSample();
302  }
303 
304  private:
305  const SampleBuffer& m_cBuffer;
306  };
307 
308 
309  //! @cond PRIVATE
310 
311 private:
312  SampleBuffer m_SampleBuffer;
313  clone::ClockValue m_Clock;
314  bool m_IsValidValue;
315  StationIndex m_ResponsibleStationIndex;
316 
317  static Definition<ReckoningCloneElementBase> s_Definition;
318 
319 public:
320 #if 0
321  void Test(const CloneProtocol* cpProtocol);
322 #endif
323 
324 public:
325  template <int TEST_ID, typename Arg>
326  static void Test(const ReckoningCloneElementBase& obj, Arg* pArg = NULL);
327 
328  //! @endcond
329 };
330 }
331 }
332 } // end of namespace nn::pia::reckoning
This is the base class for managing data that is sent and received. .
Definition: clone_CloneElementBase.h:40
u32 ClockValue
Defines a type that holds a clock value.
Definition: clone_definitions.h:44
StationIndex
Enumerates StationIndex values.
Definition: platformCtr.h:44
Definition: assert.h:115
Contains member functions used to access values in the sample buffer.
Definition: reckoning_ReckoningCloneElementBase.h:261
const Sample & GetSample(int index) const
Gets a sample.
Definition: reckoning_ReckoningCloneElementBase.h:298
This is the base class for managing the sending and receiving of data while using dead reckoning...
Definition: reckoning_ReckoningCloneElementBase.h:47
int GetNum() const
Gets the number of saved samples.
Definition: reckoning_ReckoningCloneElementBase.h:275
u16 Id
Specifies the type of the ID for identifying clone elements.
Definition: clone_CloneElementBase.h:59
clone::ClockValue GetClock(int index) const
Gets the clock for when the sample was set.
Definition: reckoning_ReckoningCloneElementBase.h:286