/*---------------------------------------------------------------------------* Project: Horizon File: os_Event.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: 33844 $ *---------------------------------------------------------------------------*/ /*! @file @brief Event に関するAPI の宣言 :include nn/os.h */ #ifndef NN_OS_OS_EVENT_H_ #define NN_OS_OS_EVENT_H_ #include #include #include #include #include #include #ifdef __cplusplus namespace nn{ namespace os { /*! @brief ライブラリが内部的に使うクラスです。このクラスを直接使わないでください。 */ class EventBase : public InterruptEvent { protected: explicit EventBase(ResetType resetType); EventBase() {} ~EventBase() {} void Initialize(ResetType resetType); nn::Result TryInitialize(ResetType resetType); void Finalize(); void Signal(); void ClearSignal(); private: Result TryInitializeImpl(ResetType resetType); }; // インライン実装 inline Result EventBase::TryInitializeImpl(ResetType resetType) { Handle handle; NN_UTIL_RETURN_IF_FAILED(nn::svc::CreateEvent(&handle, resetType)); this->SetHandle(handle); return ResultSuccess(); } inline void EventBase::Initialize(ResetType resetType) { NN_ERR_THROW_FATAL(TryInitializeImpl(resetType)); } inline nn::Result EventBase::TryInitialize(ResetType resetType) { Result result = TryInitializeImpl(resetType); if (result.GetSummary() == Result::SUMMARY_OUT_OF_RESOURCE) { return result; } NN_ERR_THROW_FATAL(result); return result; } inline void EventBase::Finalize() { InterruptEvent::Finalize(); } inline EventBase::EventBase(ResetType resetType) { Initialize(resetType); } inline void EventBase::Signal() { NN_ERR_THROW_FATAL(nn::svc::SignalEvent(GetHandle())); } inline void EventBase::ClearSignal() { NN_ERR_THROW_FATAL(nn::svc::ClearEvent(GetHandle())); } /*! @brief イベントを扱う為のクラスです。イベントはイベントの発生を通知する同期オブジェクトです。 通常は @ref nn::os::Event ではなく、@ref nn::os::LightEvent を使用すべきです。 複数の同期オブジェクトを同時に待つことができないという点を除いて @ref nn::os::Event より @ref nn::os::LightEvent の方が優れています。 イベントは、シグナル状態と非シグナル状態の二つの状態持ちます。 Event の Wait 動作では、イベントがシグナル状態になるのを待ちます。 イベントには、「手動リセットイベント」と「自動リセットイベント」の二つがあり、 初期化時のパラメータによって設定することができます。 手動リセットイベントでは、@ref Signal によってシグナル状態になると、 @ref ClearSignal が呼び出されるまで、常にシグナル状態が維持されます。 シグナル状態の間、このイベントに対する全ての Wait 動作は解放されます。 自動リセットイベントでは、@ref Signal によってシグナル状態になると、 Wait 動作の解放されうるスレッドの中で最も優先度の高いもののうち唯一つだけがが解放されます。 そのほかのスレッドは解放されません。 Event オブジェクトは 32個まで作成することが出来ます。 また、API によってはこの制限にカウントされるリソースを消費する場合がありますので、ご注意ください。 @see nn::os::Semaphore */ class Event : public EventBase { public: /*! @brief イベントを構築し、初期化します。 @param[in] manualReset 手動リセットイベントか否かを指定します。 */ explicit Event(bool manualReset) : EventBase(manualReset ? RESET_TYPE_STICKY: RESET_TYPE_ONESHOT) {} /*! @brief イベントオブジェクトを構築します。初期化はしません。 イベントを使用する場合は、明示的に @ref Initialize を呼ぶ必要があります。 */ Event() {} /*! @brief イベントを初期化します。 @param[in] manualReset 手動リセットイベントか否かを指定します。 */ void Initialize(bool manualReset) { EventBase::Initialize(manualReset ? RESET_TYPE_STICKY: RESET_TYPE_ONESHOT); } void Initialize(ResetType resetType) { EventBase::Initialize(resetType); } nn::Result TryInitialize(bool manualReset) { return EventBase::TryInitialize(manualReset ? RESET_TYPE_STICKY: RESET_TYPE_ONESHOT); } /*! @brief イベントを破棄します。 デストラクタからも自動で呼ばれます。 @return 無し。 */ void Finalize() { EventBase::Finalize(); } /*! @brief デストラクタです。 */ ~Event() {} /*! @brief イベントをシグナル状態にします。 @return 無し。 */ void Signal() { EventBase::Signal(); } /*! @brief イベントがシグナル状態になるのを待ちます。 @return 無し。 */ void Wait() { EventBase::WaitOne(); } /*! @brief イベントが発生するまでブロックします。 イベントがシグナル状態であれば、即座に true が返ります。 シグナル状態でなかった場合、最大で timeout で指定した時間だけ待ち、 その間にシグナルを受け取ることができれば true を返します。 timeout で指定した時間だけ待ってもシグナルを受け取れなかった場合は、false を返します。 @param[in] timeout タイムアウト時間を指定します。0 を指定すると即座に処理を返します。 @return タイムアウト時間までにイベントが発生したかを返します。 */ bool Wait(nn::fnd::TimeSpan timeout) { return EventBase::WaitOne(timeout); } /*! @brief イベントを手動でクリアします。 @return 無し。 */ void ClearSignal() { EventBase::ClearSignal(); } }; }} // namesapce nn::os #endif // __cplusplus // 以下、C 用宣言 #include /*! @addtogroup nn_os @{ @defgroup nn_os_Event_c Event (C) @brief @ref nn::os::Event の C インタフェースモジュールです。 @{ */ /*! @struct nnosEvent @brief イベントを表す C の構造体です。 @brief 対応するクラス @ref nn::os::Event を参照してください。 */ NN_UTIL_DETAIL_CLIBIMPL_DEFINE_BUFFER_CLASS(nnosEvent, nn::os::Event, 4, u32); NN_UTIL_DETAIL_CLIBIMPL_DECLARE_CONVERSION(nnosEventToWaitObject, nnosEvent, nnosWaitObject); NN_UTIL_DETAIL_CLIBIMPL_DECLARE_CONVERSION(nnosWaitObjectToEvent, nnosWaitObject, nnosEvent); /*! @brief 対応する C++ 関数 @ref nn::os::Event::Initialize を参照してください。 */ NN_EXTERN_C void nnosEventInitialize(nnosEvent* this_, bool manualReset); /*! @brief 対応する C++ 関数 @ref nn::os::Event::TryInitialize を参照してください。 */ NN_EXTERN_C bool nnosEventTryInitialize(nnosEvent* this_, bool manualReset); /*! @brief 対応する C++ 関数 @ref nn::os::Event::Signal を参照してください。 */ NN_EXTERN_C void nnosEventSignal(nnosEvent* this_); /*! @brief 対応する C++ 関数 @ref nn::os::Event::Wait を参照してください。 */ NN_EXTERN_C void nnosEventWaitSignal(nnosEvent* this_); /*! @brief 対応する C++ 関数 @ref nn::os::Event::Wait を参照してください。 */ NN_EXTERN_C bool nnosEventTryWaitSignal(nnosEvent* this_, s64 nanoSecondsTimeout); /*! @brief 対応する C++ 関数 @ref nn::os::Event::ClearSignal を参照してください。 */ NN_EXTERN_C void nnosEventClearSignal(nnosEvent* this_); /*! @brief 対応する C++ 関数 @ref nn::os::Event::Finalize を参照してください。 */ NN_EXTERN_C void nnosEventFinalize(nnosEvent* this_); /*! @} @} */ #endif