/*---------------------------------------------------------------------------* Project: NintendoWare File: snd_SoundInstanceManager.h Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. 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. $Revision: 20634 $ *---------------------------------------------------------------------------*/ #ifndef NW_SND_SOUND_INSTANCE_MANAGER_H_ #define NW_SND_SOUND_INSTANCE_MANAGER_H_ #include #include #include namespace nw { namespace snd { namespace internal { /* ======================================================================== SoundInstanceManager class ======================================================================== */ template < typename Sound, typename Player > class SoundInstanceManager { /* ------------------------------------------------------------------------ typename definition ------------------------------------------------------------------------ */ public: typedef ut::LinkList< Sound, offsetof(Sound,m_PriorityLink)> PriorityList; typedef typename PriorityList::Iterator Iterator; /* ------------------------------------------------------------------------ class member ------------------------------------------------------------------------ */ public: SoundInstanceManager() { // m_CriticalSection.Initialize(); } ~SoundInstanceManager() { // m_CriticalSection.Finalize(); } unsigned long GetRequiredMemSize( int instanceCount ) { return sizeof(Sound) * instanceCount; } /*---------------------------------------------------------------------------* Name: Create Description: 指定したメモリ領域をインスタンスマネージャに割り当てます Arguments: buffer - メモリ領域の開始アドレス size - メモリ領域のサイズ Returns: 無し *---------------------------------------------------------------------------*/ unsigned long Create( void* buffer, unsigned long size ) { NW_NULL_ASSERT( buffer ); // nn::os::CriticalSection::ScopedLock lock(m_CriticalSection); char* ptr = static_cast(buffer); const unsigned long numObjects = size / sizeof(Sound); for( unsigned long i=0 ;iCalcCurrentPlayerPriority() ) return NULL; // m_CriticalSection.Leave(); NW_WARNING( ! internal::Debug_GetWarningFlag( internal::Debug_GetDebugWarningFlagFromSoundType( lowPrioSound->GetSoundType() ) ), "Sound (id:%d) is stopped for not enough %s sound instance.", lowPrioSound->GetId(), internal::Debug_GetSoundTypeString( lowPrioSound->GetSoundType() ) ); lowPrioSound->Stop( 0 ); // m_CriticalSection.Enter(); } } sound->Initialize(); sound->SetPriority( priority, ambientPriority ); InsertPriorityList( sound, allocPriority ); return sound; } /*---------------------------------------------------------------------------* Name: Free Description: インスタンスをマネージャーに解放する 指定したインスタンスをマネージャーに対して解放します。 解放するインスタンスは、あらかじめ停止されている必要があります。 Arguments: sound - インスタンス Returns: 無し *---------------------------------------------------------------------------*/ void Free( Sound* sound ) { NW_NULL_ASSERT( sound ); // nn::os::CriticalSection::ScopedLock lock( m_CriticalSection ); RemovePriorityList( sound ); sound->Finalize(); m_FreeList.PushBack( sound ); } /*---------------------------------------------------------------------------* Name: UpdatePriority Description: 引数に指定したサウンドのプライオリティをプライオリティリストに 反映させる Arguments: sound - インスタンス priority - プライオリティ Returns: 無し *---------------------------------------------------------------------------*/ void UpdatePriority( Sound* sound, int priority ) { // nn::os::CriticalSection::ScopedLock lock( m_CriticalSection ); RemovePriorityList( sound ); InsertPriorityList( sound, priority ); } /*---------------------------------------------------------------------------* Name: SortPriorityList Description: プライオリティリストをソートする Arguments: 無し Returns: 無し *---------------------------------------------------------------------------*/ void SortPriorityList() { if ( m_PriorityList.GetSize() < 2 ) return; // nn::os::CriticalSection::ScopedLock lock( m_CriticalSection ); static const int TMP_NUM = internal::BasicSound::PRIORITY_MAX - internal::BasicSound::PRIORITY_MIN + 1; PriorityList tmplist[ TMP_NUM ]; // notice: large stack while ( !m_PriorityList.IsEmpty() ) { Sound& front = m_PriorityList.GetFront(); m_PriorityList.PopFront(); tmplist[ front.CalcCurrentPlayerPriority() ].PushBack( &front ); } for ( int i=0; iCalcCurrentPlayerPriority() ) break; (void)++itr; } m_PriorityList.Insert( itr, sound ); } void RemovePriorityList( Sound* sound ) { m_PriorityList.Erase( sound ); } PriorityList m_PriorityList; PriorityList m_FreeList; // nn::os::CriticalSection m_CriticalSection; }; } // namespace nw::snd::internal } // namespace nw::snd } // namespace nw #endif /* NW_SND_SOUND_INSTANCE_MANAGER_H_ */