00001 /******************************************************************************* 00002 The content of this file includes portions of the AUDIOKINETIC Wwise Technology 00003 released in source code form as part of the SDK installer package. 00004 00005 Commercial License Usage 00006 00007 Licensees holding valid commercial licenses to the AUDIOKINETIC Wwise Technology 00008 may use this file in accordance with the end user license agreement provided 00009 with the software or, alternatively, in accordance with the terms contained in a 00010 written agreement between you and Audiokinetic Inc. 00011 00012 Apache License Usage 00013 00014 Alternatively, this file may be used under the Apache License, Version 2.0 (the 00015 "Apache License"); you may not use this file except in compliance with the 00016 Apache License. You may obtain a copy of the Apache License at 00017 http://www.apache.org/licenses/LICENSE-2.0. 00018 00019 Unless required by applicable law or agreed to in writing, software distributed 00020 under the Apache License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 00021 OR CONDITIONS OF ANY KIND, either express or implied. See the Apache License for 00022 the specific language governing permissions and limitations under the License. 00023 00024 Version: <VERSION> Build: <BUILDNUMBER> 00025 Copyright (c) <COPYRIGHTYEAR> Audiokinetic Inc. 00026 *******************************************************************************/ 00027 00028 #ifndef _AK_MIXERINPUTMAP_H_ 00029 #define _AK_MIXERINPUTMAP_H_ 00030 00031 #include <AK/SoundEngine/Common/AkTypes.h> 00032 00033 #include <AK/SoundEngine/Common/IAkPluginMemAlloc.h> 00034 #include <AK/Tools/Common/AkArray.h> 00035 #include <AK/SoundEngine/Common/IAkPlugin.h> 00036 00037 /// Collection class to manage inputs in mixer plugins. 00038 /// The inputs are identified by their context AK::IAkMixerInputContext. The type of data attached to it is the template argument USER_DATA. 00039 /// The collection performs allocation/deallocation of user data via AK_PLUGIN_NEW/DELETE(). 00040 /// Usage 00041 /// 00042 /// // Init 00043 /// AkMixerInputMap<MyStruct> m_mapInputs; 00044 /// m_mapInputs.Init( in_pAllocator ); // in_pAllocator passed at plugin init. 00045 /// 00046 /// // Add an input. 00047 /// m_mapInputs.AddInput( in_pInput ); // AK::IAkMixerInputContext * in_pInput passed to OnInputConnected() 00048 /// 00049 /// // Find an input 00050 /// MyStruct * pInput = m_mapInputs.Exists( in_pInputContext ); // AK::IAkMixerInputContext * in_pInputContext passed to ConsumeInput() 00051 /// 00052 /// // Iterate through inputs. 00053 /// AkMixerInputMap<MyStruct>::Iterator it = m_mapInputs.End(); 00054 /// while ( it != m_mapInputs.End() ) 00055 /// { 00056 /// MyStruct * pInput = (*it).pUserData; 00057 /// ... 00058 /// ++it; 00059 /// } 00060 00061 /// Structure of an entry in the AkMixerInputMap map. 00062 template <class USER_DATA> 00063 struct AkInputMapSlot 00064 { 00065 AK::IAkMixerInputContext * pContext; 00066 USER_DATA * pUserData; /// User data. Here we have a buffer. Other relevant info would be the game object position and input parameters of the previous frame. 00067 00068 AkInputMapSlot() : pContext( NULL ), pUserData( NULL ) {} 00069 bool operator ==(const AkInputMapSlot& in_Op) const { return ( pContext == in_Op.pContext ); } 00070 }; 00071 00072 /// Allocator for plugin-friendly arrays. 00073 /// TODO Replace by a sorted array. 00074 class AkPluginArrayAllocator 00075 { 00076 public: 00077 AkForceInline AkPluginArrayAllocator() : m_pAllocator( NULL ) {} 00078 AkForceInline void Init( AK::IAkPluginMemAlloc * in_pAllocator ) { m_pAllocator = in_pAllocator; } 00079 protected: 00080 AkForceInline void * Alloc( size_t in_uSize ) { AKASSERT( m_pAllocator || !"Allocator not set. Did you forget to call AkMixerInputMap::Init()?" ); return AK_PLUGIN_ALLOC( m_pAllocator, in_uSize ); } 00081 AkForceInline void Free( void * in_pAddress ) { AKASSERT( m_pAllocator || !"Allocator not set. Did you forget to call AkMixerInputMap::Init()?" ); AK_PLUGIN_FREE( m_pAllocator, in_pAddress ); } 00082 AkForceInline AK::IAkPluginMemAlloc * GetAllocator() { return m_pAllocator; } 00083 private: 00084 AK::IAkPluginMemAlloc * m_pAllocator; 00085 }; 00086 00087 /// AkMixerInputMap: Map of inputs (identified with AK::IAkMixerInputContext *) to user-defined blocks of data. 00088 template <class USER_DATA> 00089 class AkMixerInputMap : public AkArray<AkInputMapSlot<USER_DATA>, const AkInputMapSlot<USER_DATA>&, AkPluginArrayAllocator, 1> 00090 { 00091 public: 00092 typedef AkArray<AkInputMapSlot<USER_DATA>, const AkInputMapSlot<USER_DATA>&, AkPluginArrayAllocator, 1> BaseClass; 00093 00094 /// Returns the user data associated with given input context. Returns NULL if none found. 00095 USER_DATA * Exists( AK::IAkMixerInputContext * in_pInput ) 00096 { 00097 typename AkArray<AkInputMapSlot<USER_DATA>, const AkInputMapSlot<USER_DATA>&, AkPluginArrayAllocator, 1>::Iterator it = FindEx( in_pInput ); 00098 return ( it != BaseClass::End() ) ? (*it).pUserData : NULL; 00099 } 00100 00101 /// Adds an input with new user data. 00102 USER_DATA * AddInput( AK::IAkMixerInputContext * in_pInput ) 00103 { 00104 typename AkArray<AkInputMapSlot<USER_DATA>, const AkInputMapSlot<USER_DATA>&, AkPluginArrayAllocator, 1>::Iterator it = FindEx( in_pInput ); 00105 if ( it != BaseClass::End() ) 00106 return (*it).pUserData; 00107 else 00108 { 00109 AkInputMapSlot<USER_DATA> * pSlot = AkArray<AkInputMapSlot<USER_DATA>, const AkInputMapSlot<USER_DATA>&, AkPluginArrayAllocator, 1>::AddLast(); 00110 if ( pSlot ) 00111 { 00112 pSlot->pUserData = AK_PLUGIN_NEW( AkPluginArrayAllocator::GetAllocator(), USER_DATA ); 00113 if ( pSlot->pUserData ) 00114 { 00115 pSlot->pContext = in_pInput; 00116 return pSlot->pUserData; 00117 } 00118 BaseClass::RemoveLast(); 00119 } 00120 } 00121 return NULL; 00122 } 00123 00124 /// Removes an input and destroys its associated user data. 00125 bool RemoveInput( AK::IAkMixerInputContext * in_pInput ) 00126 { 00127 typename AkArray<AkInputMapSlot<USER_DATA>, const AkInputMapSlot<USER_DATA>&, AkPluginArrayAllocator, 1>::Iterator it = FindEx( in_pInput ); 00128 if ( it != BaseClass::End() ) 00129 { 00130 AKASSERT( (*it).pUserData ); 00131 AK_PLUGIN_DELETE( AkPluginArrayAllocator::GetAllocator(), (*it).pUserData ); 00132 BaseClass::EraseSwap( it ); 00133 return true; 00134 } 00135 return false; 00136 } 00137 00138 /// Terminate array. 00139 void Term() 00140 { 00141 if ( BaseClass::m_pItems ) 00142 { 00143 RemoveAll(); 00144 AkPluginArrayAllocator::Free( BaseClass::m_pItems ); 00145 BaseClass::m_pItems = 0; 00146 BaseClass::m_ulReserved = 0; 00147 } 00148 } 00149 00150 /// Finds an item in the array. 00151 typename AkArray<AkInputMapSlot<USER_DATA>, const AkInputMapSlot<USER_DATA>&, AkPluginArrayAllocator, 1>::Iterator FindEx( AK::IAkMixerInputContext * in_pInput ) const 00152 { 00153 AkInputMapSlot<USER_DATA> mapSlot; 00154 mapSlot.pContext = in_pInput; 00155 return BaseClass::FindEx( mapSlot ); 00156 } 00157 00158 /// Removes and destroys all items in the array. 00159 void RemoveAll() 00160 { 00161 for ( typename AkArray<AkInputMapSlot<USER_DATA>, const AkInputMapSlot<USER_DATA>&, AkPluginArrayAllocator, 1>::Iterator it = BaseClass::Begin(), itEnd = BaseClass::End(); it != itEnd; ++it ) 00162 { 00163 AKASSERT( (*it).pUserData ); 00164 AK_PLUGIN_DELETE( AkPluginArrayAllocator::GetAllocator(), (*it).pUserData ); 00165 (*it).~AkInputMapSlot(); 00166 } 00167 BaseClass::m_uLength = 0; 00168 } 00169 }; 00170 00171 #endif // _AK_MIXERINPUTMAP_H_
Questions? Problems? Need more info? Contact us, and we can help!
Visit our Support pageRegister your project and we'll help you get started with no strings attached!
Get started with Wwise