1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: os_Timer.h
4
5 Copyright (C)2009 Nintendo Co., Ltd. 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 $Rev: 29304 $
14 *---------------------------------------------------------------------------*/
15
16 /*! @file
17 @brief Timer に関するAPI の宣言
18
19 */
20
21 #ifndef NN_OS_OS_TIMER_H_
22 #define NN_OS_OS_TIMER_H_
23
24 #include <nn/types.h>
25 #include <nn/Handle.h>
26 #include <nn/Result.h>
27 #include <nn/os/os_Synchronization.h>
28 #include <nn/fnd/fnd_TimeSpan.h>
29
30 #include <nn/util/util_Result.h>
31
32 #ifdef __cplusplus
33
34 namespace nn{ namespace os {
35
36 /*!
37 @brief タイマを表すクラスです。
38
39 タイマには @ref Event と同様に、シグナル状態と非シグナル状態の二つの状態持ちます。
40 Timer の Wait 動作では、イベントがシグナル状態になるのを待ちます。
41
42 また同様に、タイマには、「手動リセットタイマ」と「自動リセットタイマ」の二つがあり、
43 初期化時のパラメータによって設定することができます。
44 二つの違いの詳細は @ref Event を参照してください。
45
46 タイマでは、即時にシグナル状態にはなるわけではなく、
47 @ref StartOneShot 関数を呼んだ後に指定した時間だけ遅れてシグナル状態になります。
48
49 また、@ref StartPeriodic を呼ぶことによって、周期的にシグナル状態にすることができます。
50 */
51 class Timer : public WaitObject
52 {
53 public:
54
55 /*! @brief タイマ初期化
56
57 初期化しないコンストラクタと、初期化するコンストラクタが用意されています。
58
59 初期化しない場合、使用する前に、@ref Initialize を呼んで明示的に初期化する必要があります。
60
61 @param[in] isManualReset @ref Initialize を参照してください。
62 */
63 explicit Timer(bool isManualReset);
64
Timer()65 Timer() {}
66
67 /*!
68 @brief タイマの初期化
69
70 @param[in] isManualReset 手動リセットタイマとするか設定します。
71 手動リセットタイマの場合、タイマの時間が来た後、
72 @ref Wait によりタイマ待ちしようとするスレッドは、
73 即時に起きます。
74
75 @return 無し。
76 */
77 void Initialize(bool isManualReset);
78
79 /*!
80 @brief タイマの初期化を試みます。
81
82 @param[in] isManualReset 手動リセットタイマとするか設定します。
83 手動リセットタイマの場合、タイマの時間が来た後、
84 @ref Wait によりタイマ待ちしようとするスレッドは、
85 即時に起きます。
86
87 @return 関数の実行結果を返します。
88 */
89 nn::Result TryInitialize(bool isManualReset);
90
91 /*!
92 @brief タイマーを破棄します。
93
94 デストラクタからも自動で呼ばれます。
95 @return 無し。
96 */
Finalize()97 void Finalize() { WaitObject::Finalize(); }
98
99 /*!
100 @brief デストラクタです。
101 */
~Timer()102 ~Timer() {}
103
104 /*!
105 @brief タイマーの開始
106
107 @param[in] timeSpan 最初のタイマの通知までの時間を指定します。
108
109 @return 無し。
110 */
111 void StartOneShot(nn::fnd::TimeSpan timeSpan);
112
113 /*!
114 @brief タイマを開始します。
115
116 @param[in] first 最初のタイマの通知までの時間を指定します。
117
118 @param[in] interval 2 度目以降のタイマの通知の間隔を指定します。
119
120 @return 無し。
121 */
122 void StartPeriodic(nn::fnd::TimeSpan first, nn::fnd::TimeSpan interval);
123
124 /*!
125 @brief タイマを即時にシグナル状態にします。
126
127 @return 無し。
128 */
129 void Signal();
130
131 /*!
132 @brief タイマの通知まで待ちます。
133
134 複数のスレッドが同一のTimerインスタンスの @ref Wait を呼び
135 タイマ待ちした場合、先に タイマ待ちしたスレッドが起きます。
136
137 @return 無し。
138 */
Wait()139 void Wait() { this->WaitOne(); }
140
141 /*!
142 @brief 開始されたタイマを停止します。
143
144 @return 無し。
145 */
146 void Stop();
147
148 /*!
149 @brief タイマをクリアします。
150
151 手動リセットタイマを非シグナル状態にします。
152
153 @return 無し。
154 */
155 void ClearSignal();
156
157 private:
158
159 Result TryInitializeImpl(bool isManualReset);
160 void StartImpl(nn::fnd::TimeSpan first, nn::fnd::TimeSpan interval);
161
162 };
163
164 // インライン実装
165
TryInitializeImpl(bool isManualReset)166 inline Result Timer::TryInitializeImpl(bool isManualReset)
167 {
168 Handle handle;
169 NN_UTIL_RETURN_IF_FAILED(nn::svc::CreateTimer(&handle, isManualReset));
170 this->SetHandle(handle);
171 return ResultSuccess();
172 }
173
Initialize(bool isManualReset)174 inline void Timer::Initialize(bool isManualReset)
175 {
176 NN_ERR_THROW_FATAL(TryInitializeImpl(isManualReset));
177 }
178
TryInitialize(bool isManualReset)179 inline nn::Result Timer::TryInitialize(bool isManualReset)
180 {
181 Result result = TryInitializeImpl(isManualReset);
182 if (result.GetSummary() == Result::SUMMARY_OUT_OF_RESOURCE)
183 {
184 return result;
185 }
186 NN_ERR_THROW_FATAL(result);
187 return result;
188 }
189
Timer(bool isManualReset)190 inline Timer::Timer(bool isManualReset)
191 {
192 Initialize(isManualReset);
193 }
194
StartImpl(nn::fnd::TimeSpan initial,nn::fnd::TimeSpan interval)195 inline void Timer::StartImpl(nn::fnd::TimeSpan initial, nn::fnd::TimeSpan interval)
196 {
197 NN_ERR_THROW_FATAL(nn::svc::SetTimer(GetHandle(), initial.GetNanoSeconds(), interval.GetNanoSeconds()));
198 }
199
StartPeriodic(nn::fnd::TimeSpan initial,nn::fnd::TimeSpan interval)200 inline void Timer::StartPeriodic(nn::fnd::TimeSpan initial, nn::fnd::TimeSpan interval)
201 {
202 NN_TASSERT_(interval > 0);
203 this->StartImpl(initial, interval);
204 }
205
StartOneShot(nn::fnd::TimeSpan initial)206 inline void Timer::StartOneShot(nn::fnd::TimeSpan initial)
207 {
208 this->StartImpl(initial, 0);
209 }
210
Signal()211 inline void Timer::Signal()
212 {
213 this->StartOneShot(0);
214 }
215
Stop()216 inline void Timer::Stop()
217 {
218 NN_ERR_THROW_FATAL(nn::svc::CancelTimer(GetHandle()));
219 }
220
ClearSignal()221 inline void Timer::ClearSignal()
222 {
223 NN_ERR_THROW_FATAL(nn::svc::ClearTimer(GetHandle()));
224 }
225
226 }} // namesapce nn::os
227
228 #endif // __cplusplus
229
230 // 以下、C 用宣言
231
232 #include <nn/util/detail/util_CLibImpl.h>
233
234 /*!
235 @addtogroup nn_os
236 @{
237
238 @defgroup nn_os_Timer_c Timer (C)
239
240 @brief @ref nn::os::Timer の C インタフェースモジュールです。
241
242 @{
243 */
244
245 /*!
246 @struct nnosTimer
247 @brief タイマを表す C の構造体です。
248 @brief 対応するクラス @ref nn::os::Timer を参照してください。
249 */
250
251 NN_UTIL_DETAIL_CLIBIMPL_DEFINE_BUFFER_CLASS(nnosTimer, nn::os::Timer, 4, u32);
252 NN_UTIL_DETAIL_CLIBIMPL_DECLARE_CONVERSION(nnosTimerToWaitObject, nnosTimer, nnosWaitObject);
253 NN_UTIL_DETAIL_CLIBIMPL_DECLARE_CONVERSION(nnosWaitObjectToTimer, nnosWaitObject, nnosTimer);
254
255
256 /*!
257 @brief 対応する C++ 関数 @ref nn::os::Timer::Initialize を参照してください。
258 */
259 NN_EXTERN_C void nnosTimerInitialize(nnosTimer* this_, bool isManualReset);
260
261 /*!
262 @brief 対応する C++ 関数 @ref nn::os::Timer::TryInitialize を参照してください。
263 */
264 NN_EXTERN_C bool nnosTimerTryInitialize(nnosTimer* this_, bool isManualReset);
265
266 /*!
267 @brief 対応する C++ 関数 @ref nn::os::Timer::StartPeriodic を参照してください。
268 */
269 NN_EXTERN_C void nnosTimerStartPeriodic(nnosTimer* this_, s64 first, s64 interval);
270
271 /*!
272 @brief 対応する C++ 関数 @ref nn::os::Timer::StartOneShot を参照してください。
273 */
274 NN_EXTERN_C void nnosTimerStartOneShot(nnosTimer* this_, s64 time);
275
276 /*!
277 @brief 対応する C++ 関数 @ref nn::os::Timer::Wait を参照してください。
278 */
279 NN_EXTERN_C void nnosTimerWait(nnosTimer* this_);
280
281 /*!
282 @brief 対応する C++ 関数 @ref nn::os::Timer::Stop を参照してください。
283 */
284 NN_EXTERN_C void nnosTimerStop(nnosTimer* this_);
285
286 /*!
287 @brief 対応する C++ 関数 @ref nn::os::Timer::ClearSignal を参照してください。
288 */
289 NN_EXTERN_C void nnosTimerClearSignal(nnosTimer* this_);
290
291 /*!
292 @brief 対応する C++ 関数 @ref nn::os::Timer::Finalize を参照してください。
293 */
294 NN_EXTERN_C void nnosTimerFinalize(nnosTimer* this_);
295
296 /*!
297 @brief 対応する C++ 関数 @ref nn::os::Timer::Signal を参照してください。
298 */
299 NN_EXTERN_C void nnosTimerSignal(nnosTimer* this_);
300
301 /*!
302 @}
303
304 @}
305 */
306
307 #endif
308
309