CTR-Pia  5.4.3
Game Communication Engine
 全て クラス ネームスペース 関数 変数 型定義 列挙型 列挙型の値 ページ
reckoning_ReckoningCloneElement.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/reckoning/reckoning_Definitions.h>
17 #include <nn/pia/reckoning/reckoning_ReckoningCloneElementBase.h>
18 #include <nn/pia/reckoning/reckoning_VoidMemberConcealer.h>
19 #include <nn/pia/clone/clone_SerializePolicyDefinition.h>
20 #include <nn/pia/clone/clone_CloneProtocol.h>
21 
22 #include <limits.h>
23 
24 namespace nn
25 {
26 namespace pia
27 {
28 namespace reckoning
29 {
30 
31 /*!
32  @brief 推測航法を用いながらの値の送受信を管理します。
33 
34  @tparam ReckoningStrategy_ 推測アルゴリズムを定義するクラスの型です。
35 
36  @details 設定された値の一部を標本値として一定数保持・送信し、その標本値から現在の値を推測することにより、
37  設定された値をすべて送信することなく値を伝えます。
38 
39  ReckoningStrategy に指定するクラスには、以下の定義がされている必要があります。
40 
41 
42 
43  @li @code Value @endcode
44  SetValue(), GetValue() で設定/取得する値の型です。
45  @li @code Sample @endcode
46  標本値の型です。この型で実際に送受信されます。
47  @li @code SetValueArg @endcode
48  SetValue() 時に指定して ReckoningStrategy::CheckSample(), ReckoningStrategy::MakeSample() に渡される値の型です。
49  必要が無ければ void を指定する必要があります。
50  @li @code Work @endcode
51  推測の計算のための事前計算結果を保持しておく型です。必要が無ければ void を指定する必要があります。
52 
53  定数
54 
55  @li @code static const uint32_t BufferSize @endcode
56  標本値を保持しておく個数です。
57 
58  関数
59 
60  @li @code bool Estimate(
61  Value* pValue,
62  const nn::pia::reckoning::ReckoningCloneElementBase::SampleAccessor<Sample>& accessor,
63  nn::pia::clone::ClockValue clock,
64  Work* pWork); @endcode
65  推測値を計算します。
66  推測値が計算できた場合は、その値を *pValue に設定して true を返す必要があります。
67  計算できなかった場合は、 false を返す必要があります。
68  @li @code bool CheckSample(
69  bool* pIsReliable,
70  const Value& value,
71  const SetValueArg* cpSetValueArg,
72  const nn::pia::reckoning::ReckoningCloneElementBase::SampleAccessor<Sample>& accessor,
73  nn::pia::clone::ClockValue clock,
74  Work* pWork); @endcode
75  SetValue() で設定した値 value を標本値として採用するかどうかを判定します。
76  標本値として採用する場合は true を返す必要があります。
77  標本値の送信にあたり到達保証をする必要がある場合は *pIsReliable に true を設する必要があります。
78  @li @code void MakeSample(
79  Sample* pSample,
80  const Value& value,
81  const SetValueArg* cpSetValueArg,
82  const nn::pia::reckoning::ReckoningCloneElementBase::SampleAccessor<Sample>& accessor,
83  nn::pia::clone::ClockValue clock,
84  Work* pWork); @endcode
85  標本値として保存する値を計算します。
86  CheckSample() で標本値として採用するよう判定され、実際にバッファが確保できた場合に呼び出されます。
87  *pSample に標本値を設定する必要があります。
88  @li @code void OnUpdateSample(
89  const nn::pia::reckoning::ReckoningCloneElementBase::SampleAccessor<Sample>& accessor,
90  int index,
91  Work* pWork); @endcode
92  標本値が追加された場合に呼び出されます。
93  必要に応じて pWork の値を更新する必要があります。
94 
95  詳細はプログラミングマニュアルを参照してください。
96  */
97 template <
98  typename ReckoningStrategy_>
100 {
101 public:
102  /*!
103  @brief 推測アルゴリズムの型です。
104  */
105  typedef ReckoningStrategy_ ReckoningStrategy;
106 
107 
108  /*!
109  @brief このオブジェクトが管理する値の型です。
110  */
111  typedef typename ReckoningStrategy::Value Value;
112 
113 
114  /*!
115  @brief 標本値の型です。
116  */
117  typedef typename ReckoningStrategy::Sample Sample;
118 
119 
120  /*!
121  @brief SetValue() から、ReckoningStrategy::CheckSample()、ReckoningStrategy::MakeSample() に伝える値の型です。
122  */
123  typedef typename ReckoningStrategy::SetValueArg SetValueArg;
124 
125 
126  /*!
127  @brief ワークバッファの型です。
128  */
129  typedef typename ReckoningStrategy::Work Work;
130 
131 
132  /*!
133  @brief Sample をシリアライズするためのアルゴリズムです。
134  */
136 
137 
138  /*!
139  @brief 標本値を保持しておくバッファのサイズです。
140  */
141  static const uint32_t BufferSize = ReckoningStrategy::BufferSize;
142 
143 
144  /*!
145  @brief コンストラクタです。
146  @param[in] pReckoningStrategy 推測アルゴリズムのインスタンスを指定します。
147  ここでの指定は省略できますが、 CloneBase::RegisterElement() に渡すまでには
148  SetReckoningStrategy() で有効なインスタンスを設定しておく必要があります。
149  */
150  explicit ReckoningCloneElement(ReckoningStrategy* pReckoningStrategy = NULL);
151 
152 
153  /*!
154  @brief デストラクタです。
155  */
157  {
158  }
159 
160 
161  /*!
162  @brief 推測アルゴリズムのインスタンスを指定します。
163  @details @ref clone::CloneBase "CloneBase" に登録されている状態では設定できません。
164  @param[in] pReckoningStrategy 指定する推測アルゴリズムです。
165  @return 成功すれば、 IsSuccess() が true を返す Result が返されます。
166  @retval ResultInvalidState CloneBase に登録されています。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
167  */
168  Result SetReckoningStrategy(ReckoningStrategy* pReckoningStrategy);
169 
170 
171  /*!
172  @brief 設定されている推測アルゴリズムのインスタンスをリセットします。
173  @details @ref clone::CloneBase "CloneBase" に登録されている状態ではリセットできません。
174  @return 成功すれば、 IsSuccess() が true を返す Result が返されます。
175  @retval ResultInvalidState CloneBase に登録されています。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
176  */
178  {
179  return SetReckoningStrategy(NULL);
180  }
181 
182 
183  /*!
184  @brief 値を設定します。
185  @param[in] value 設定する値です。
186  @param[in] cpSetValueArg ReckoningStrategy::CheckSample()、ReckoningStrategy::MakeSample() に伝える値です。
187  @return 成功すれば、 IsSuccess() が true を返す Result が返されます。
188  @retval ResultInvalidState 登録している CloneBase が送信可能状態ではありません。プログラミングエラーです。このエラーが返らないようにソースコードを修正してください。
189  */
190  Result SetValue(const Value& value, const SetValueArg* cpSetValueArg = NULL);
191 
192 
193  /*!
194  @brief 値を取得します。
195  @return このオブジェクトが管理する値です。 @ref IsValidValue() が false の場合に取得できる値は不定です。
196  */
197  const Value& GetValue()
198  {
199  UpdateValue();
200  return *m_ValueWork.GetT1Ptr();
201  }
202 
203 
204  //! @cond PRIVATE
205 
206 public:
207  virtual bool IsInitialized() const
208  {
209  return PIA_IS_VALID_POINTER(m_pReckoningStrategy);
210  }
211 
212 protected:
213  virtual uint32_t GetSize() const
214  {
216  }
217  virtual void Serialize(void* pBuffer, const ReckoningSendToken* cpToken);
218  virtual void ClearValue()
219  {
220  m_ValueWork = VoidMemberConcealer<Value, Work>();
221  }
222  virtual bool EstimateValue(clone::ClockValue clock);
223 
224  virtual void Deserialize(ReckoningSendToken* pToken, const void* cpData);
225  virtual void OnUpdateSample(int idx);
226 
227 private:
228  ReckoningSendToken* m_apToken[BufferSize];
229  SampleReckoningSendToken<Sample> m_aSampleBuffer[BufferSize];
230 
231  ReckoningStrategy* m_pReckoningStrategy;
232 
233  VoidMemberConcealer<Value, Work> m_ValueWork;
234 
235  NN_PIA_DISALLOW_COPY(ReckoningCloneElement);
236  //! @endcond
237 };
238 
239 
240 //! @cond
241 
242 template <typename ReckoningStrategy>
243 ReckoningCloneElement<ReckoningStrategy>::ReckoningCloneElement(ReckoningStrategy* pReckoningStrategy)
244  : ReckoningCloneElementBase(m_apToken, BufferSize),
245  m_pReckoningStrategy(pReckoningStrategy),
246  m_ValueWork()
247 {
248  PIA_COMPILE_ASSERT(BufferSize > 0 && BufferSize <= ULONG_MAX);
249 
250  for (uint32_t i = 0; i < static_cast<uint32_t>(BufferSize); ++i)
251  {
252  m_aSampleBuffer[i].Init(this);
253  m_apToken[i] = &m_aSampleBuffer[i];
254  }
255 }
256 
257 
258 template <typename ReckoningStrategy>
259 Result ReckoningCloneElement<ReckoningStrategy>::SetReckoningStrategy(ReckoningStrategy* pReckoningStrategy)
260 {
261  if (IsRegisteredWithCloneBase())
262  {
263 
264  PIA_RETURN_RESULT_WITH_REPORT(ResultInvalidState, "State must not be (IsRegisteredWithCloneBase() == true).");
265  }
266  m_pReckoningStrategy = pReckoningStrategy;
267  return ResultSuccess();
268 }
269 
270 
271 template <typename ReckoningStrategy>
272 Result ReckoningCloneElement<ReckoningStrategy>::SetValue(const Value& value, const SetValueArg* cpSetValueArg)
273 {
274  bool isSend;
275  Result r = SetValueCore(&isSend);
276 
277  if (isSend)
278  {
279  const clone::ClockValue clock = GetProtocol()->GetClock();
280  const SampleAccessor<Sample> accessor(GetSampleBuffer());
281 
282  bool isReliable = false;
283  bool isSample = m_pReckoningStrategy->CheckSample(&isReliable, value, cpSetValueArg, accessor, clock, m_ValueWork.GetT2Ptr());
284  if (isSample)
285  {
286  int idx;
287  ReckoningSendToken* pToken = AssignTokenForSend(&idx, isReliable);
288  PIA_ASSERT(pToken != NULL && idx == 0);
289 
290  SampleReckoningSendToken<Sample>* pSampleToken = static_cast<SampleReckoningSendToken<Sample>*>(pToken);
291  m_pReckoningStrategy->MakeSample(pSampleToken->GetSamplePtr(), value, cpSetValueArg, accessor, clock, m_ValueWork.GetT2Ptr());
292  m_pReckoningStrategy->OnUpdateSample(accessor, idx, m_ValueWork.GetT2Ptr());
293  }
294  }
295 
296  return r;
297 }
298 
299 
300 template <typename ReckoningStrategy>
301 void ReckoningCloneElement<ReckoningStrategy>::Serialize(void* pBuffer, const ReckoningSendToken* cpToken)
302 {
303  const SampleReckoningSendToken<Sample>* cpSampleToken = static_cast<const SampleReckoningSendToken<Sample>*>(cpToken);
304  ValueSerializePolicy::Serialize(pBuffer, cpSampleToken->GetSample());
305 }
306 
307 
308 template <typename ReckoningStrategy>
309 bool ReckoningCloneElement<ReckoningStrategy>::EstimateValue(clone::ClockValue clock)
310 {
311  const SampleAccessor<Sample> accessor(GetSampleBuffer());
312  return m_pReckoningStrategy->Estimate(m_ValueWork.GetT1Ptr(), accessor, clock, m_ValueWork.GetT2Ptr());
313 }
314 
315 
316 template <typename ReckoningStrategy>
317 void ReckoningCloneElement<ReckoningStrategy>::Deserialize(ReckoningSendToken* pToken, const void* cpData)
318 {
319  SampleReckoningSendToken<Sample>* pSampleToken = static_cast<SampleReckoningSendToken<Sample>*>(pToken);
320  ValueSerializePolicy::Deserialize(pSampleToken->GetSamplePtr(), cpData);
321 }
322 
323 
324 template <typename ReckoningStrategy>
325 void ReckoningCloneElement<ReckoningStrategy>::OnUpdateSample(int idx)
326 {
327  const SampleAccessor<Sample> accessor(GetSampleBuffer());
328  m_pReckoningStrategy->OnUpdateSample(accessor, idx, m_ValueWork.GetT2Ptr());
329 }
330 
331 
332 //! @endcond
333 }
334 }
335 } // end of namespace nn::pia::reckoning