/*---------------------------------------------------------------------------* Project: Horizon File: os_Timer.h Copyright (C)2009 Nintendo Co., Ltd. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Rev: 16832 $ *---------------------------------------------------------------------------*/ /*! @file @brief Timer に関するAPI の宣言 */ #ifndef NN_OS_OS_TIMER_H_ #define NN_OS_OS_TIMER_H_ #include #include #include #include #include #include #ifdef __cplusplus namespace nn{ namespace os { /*! @brief タイマを表すクラスです。 タイマには @ref Event と同様に、シグナル状態と非シグナル状態の二つの状態持ちます。 Timer の Wait 動作では、イベントがシグナル状態になるのを待ちます。 また同様に、タイマには、「手動リセットタイマ」と「自動リセットタイマ」の二つがあり、 初期化時のパラメータによって設定することができます。 二つの違いの詳細は @ref Event を参照してください。 タイマでは、即時にシグナル状態にはなるわけではなく、 @ref StartOneShot 関数を呼んだ後に指定した時間だけ遅れてシグナル状態になります。 また、@ref StartPeriodic を呼ぶことによって、周期的にシグナル状態にすることができます。 */ class Timer : public WaitObject { public: /*! @brief タイマ初期化 初期化しないコンストラクタと、初期化するコンストラクタが用意されています。 初期化しない場合、使用する前に、@ref Initialize を呼んで明示的に初期化する必要があります。 @param[in] isManualReset @ref Initialize を参照してください。 */ explicit Timer(bool isManualReset); Timer() {} /*! @brief タイマの初期化 @param[in] isManualReset 手動リセットタイマとするか設定します。 手動リセットタイマの場合、タイマの時間が来た後、 @ref Wait によりタイマ待ちしようとするスレッドは、 即時に起きます。 @return 無し。 */ void Initialize(bool isManualReset); /*! @brief タイマの初期化を試みます。 @param[in] isManualReset 手動リセットタイマとするか設定します。 手動リセットタイマの場合、タイマの時間が来た後、 @ref Wait によりタイマ待ちしようとするスレッドは、 即時に起きます。 @return 関数の実行結果を返します。 */ nn::Result TryInitialize(bool isManualReset); /*! @brief タイマーを破棄します。 デストラクタからも自動で呼ばれます。 @return 無し。 */ void Finalize() { WaitObject::Finalize(); } /*! @brief デストラクタです。 */ ~Timer() {} /*! @brief タイマーの開始 @param[in] timeSpan 最初のタイマの通知までの時間を指定します。 @return 無し。 */ void StartOneShot(nn::fnd::TimeSpan timeSpan); /*! @brief タイマを開始します。 @param[in] first 最初のタイマの通知までの時間を指定します。 @param[in] interval 2 度目以降のタイマの通知の間隔を指定します。 @return 無し。 */ void StartPeriodic(nn::fnd::TimeSpan first, nn::fnd::TimeSpan interval); /*! @brief タイマを即時にシグナル状態にします。 @return 無し。 */ void Signal(); /*! @brief タイマの通知まで待ちます。 複数のスレッドが同一のTimerインスタンスの @ref Wait を呼び タイマ待ちした場合、先に タイマ待ちしたスレッドが起きます。 @return 無し。 */ void Wait() { this->WaitOne(); } /*! @brief 開始されたタイマを停止します。 @return 無し。 */ void Stop(); /*! @brief タイマをクリアします。 手動リセットタイマを非シグナル状態にします。 @return 無し。 */ void ClearSignal(); private: Result TryInitializeImpl(bool isManualReset); void StartImpl(nn::fnd::TimeSpan first, nn::fnd::TimeSpan interval); }; // インライン実装 inline Result Timer::TryInitializeImpl(bool isManualReset) { Handle handle; NN_UTIL_RETURN_IF_FAILED(nn::svc::CreateTimer(&handle, isManualReset)); this->SetHandle(handle); return ResultSuccess(); } inline void Timer::Initialize(bool isManualReset) { NN_UTIL_PANIC_IF_FAILED(TryInitializeImpl(isManualReset)); } inline nn::Result Timer::TryInitialize(bool isManualReset) { Result result = TryInitializeImpl(isManualReset); if (result.GetSummary() == Result::SUMMARY_OUT_OF_RESOURCE) { return result; } NN_UTIL_PANIC_IF_FAILED(result); return result; } inline Timer::Timer(bool isManualReset) { Initialize(isManualReset); } inline void Timer::StartImpl(nn::fnd::TimeSpan initial, nn::fnd::TimeSpan interval) { NN_UTIL_PANIC_IF_FAILED(nn::svc::SetTimer(GetHandle(), initial.GetNanoSeconds(), interval.GetNanoSeconds())); } inline void Timer::StartPeriodic(nn::fnd::TimeSpan initial, nn::fnd::TimeSpan interval) { NN_TASSERT_(interval > 0); this->StartImpl(initial, interval); } inline void Timer::StartOneShot(nn::fnd::TimeSpan initial) { this->StartImpl(initial, 0); } inline void Timer::Signal() { this->StartOneShot(0); } inline void Timer::Stop() { NN_UTIL_PANIC_IF_FAILED(nn::svc::CancelTimer(GetHandle())); } inline void Timer::ClearSignal() { NN_UTIL_PANIC_IF_FAILED(nn::svc::ClearTimer(GetHandle())); } }} // namesapce nn::os #endif // __cplusplus // 以下、C 用宣言 #include /*! @addtogroup nn_os @{ @defgroup nn_os_Timer_c Timer (C) @brief @ref nn::os::Timer の C インタフェースモジュールです。 @{ */ /*! @struct nnosTimer @brief タイマを表す C の構造体です。 @brief 対応するクラス @ref nn::os::Timer を参照してください。 */ NN_UTIL_DETAIL_CLIBIMPL_DEFINE_BUFFER_CLASS(nnosTimer, nn::os::Timer, 4, u32); NN_UTIL_DETAIL_CLIBIMPL_DECLARE_CONVERSION(nnosTimerToWaitObject, nnosTimer, nnosWaitObject); NN_UTIL_DETAIL_CLIBIMPL_DECLARE_CONVERSION(nnosWaitObjectToTimer, nnosWaitObject, nnosTimer); /*! @brief 対応する C++ 関数 @ref nn::os::Timer::Initialize を参照してください。 */ NN_EXTERN_C void nnosTimerInitialize(nnosTimer* this_, bool isManualReset); /*! @brief 対応する C++ 関数 @ref nn::os::Timer::TryInitialize を参照してください。 */ NN_EXTERN_C bool nnosTimerTryInitialize(nnosTimer* this_, bool isManualReset); /*! @brief 対応する C++ 関数 @ref nn::os::Timer::StartPeriodic を参照してください。 */ NN_EXTERN_C void nnosTimerStartPeriodic(nnosTimer* this_, s64 first, s64 interval); /*! @brief 対応する C++ 関数 @ref nn::os::Timer::StartOneShot を参照してください。 */ NN_EXTERN_C void nnosTimerStartOneShot(nnosTimer* this_, s64 time); /*! @brief 対応する C++ 関数 @ref nn::os::Timer::Wait を参照してください。 */ NN_EXTERN_C void nnosTimerWait(nnosTimer* this_); /*! @brief 対応する C++ 関数 @ref nn::os::Timer::Stop を参照してください。 */ NN_EXTERN_C void nnosTimerStop(nnosTimer* this_); /*! @brief 対応する C++ 関数 @ref nn::os::Timer::ClearSignal を参照してください。 */ NN_EXTERN_C void nnosTimerClearSignal(nnosTimer* this_); /*! @brief 対応する C++ 関数 @ref nn::os::Timer::Finalize を参照してください。 */ NN_EXTERN_C void nnosTimerFinalize(nnosTimer* this_); /*! @brief 対応する C++ 関数 @ref nn::os::Timer::Signal を参照してください。 */ NN_EXTERN_C void nnosTimerSignal(nnosTimer* this_); /*! @} @} */ #endif