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