Table of Contents

include/AK/Plugin/PluginServices/AkMixerInputMap.h

Go to the documentation of this file.
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 * ReAlloc(void * in_pCurrent, size_t in_uOldSize, size_t in_uNewSize)
00082     {
00083         void* pNew = Alloc(in_uNewSize);
00084         if (pNew && in_pCurrent)
00085         {
00086             AKPLATFORM::AkMemCpy(pNew, in_pCurrent, (AkUInt32)in_uOldSize);
00087             Free(in_pCurrent);
00088         }
00089         return pNew;
00090 
00091     }
00092     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 ); }
00093     AkForceInline AK::IAkPluginMemAlloc * GetAllocator() { return m_pAllocator; }
00094 private:
00095     AK::IAkPluginMemAlloc *     m_pAllocator;
00096 };
00097 
00098 /// AkMixerInputMap: Map of inputs (identified with AK::IAkMixerInputContext *) to user-defined blocks of data.
00099 template <class USER_DATA>
00100 class AkMixerInputMap : public AkArray<AkInputMapSlot<USER_DATA>, const AkInputMapSlot<USER_DATA>&, AkPluginArrayAllocator, 1>
00101 {
00102 public:
00103     typedef AkArray<AkInputMapSlot<USER_DATA>, const AkInputMapSlot<USER_DATA>&, AkPluginArrayAllocator, 1> BaseClass;
00104 
00105     /// Returns the user data associated with given input context. Returns NULL if none found.
00106     USER_DATA * Exists( AK::IAkMixerInputContext * in_pInput )
00107     {
00108         typename AkArray<AkInputMapSlot<USER_DATA>, const AkInputMapSlot<USER_DATA>&, AkPluginArrayAllocator, 1>::Iterator it = FindEx( in_pInput );
00109         return ( it != BaseClass::End() ) ? (*it).pUserData : NULL;
00110     }
00111 
00112     /// Adds an input with new user data.
00113     USER_DATA * AddInput( AK::IAkMixerInputContext * in_pInput )
00114     {
00115         typename AkArray<AkInputMapSlot<USER_DATA>, const AkInputMapSlot<USER_DATA>&, AkPluginArrayAllocator, 1>::Iterator it = FindEx( in_pInput );
00116         if ( it != BaseClass::End() )
00117             return (*it).pUserData;
00118         else
00119         {
00120             AkInputMapSlot<USER_DATA> * pSlot = AkArray<AkInputMapSlot<USER_DATA>, const AkInputMapSlot<USER_DATA>&, AkPluginArrayAllocator, 1>::AddLast();
00121             if ( pSlot )
00122             {
00123                 pSlot->pUserData = AK_PLUGIN_NEW( AkPluginArrayAllocator::GetAllocator(), USER_DATA );
00124                 if ( pSlot->pUserData )
00125                 {
00126                     pSlot->pContext = in_pInput;
00127                     return pSlot->pUserData;
00128                 }
00129                 BaseClass::RemoveLast();
00130             }
00131         }
00132         return NULL;
00133     }
00134 
00135     /// Removes an input and destroys its associated user data.
00136     bool RemoveInput( AK::IAkMixerInputContext * in_pInput )
00137     {
00138         typename AkArray<AkInputMapSlot<USER_DATA>, const AkInputMapSlot<USER_DATA>&, AkPluginArrayAllocator, 1>::Iterator it = FindEx( in_pInput );
00139         if ( it != BaseClass::End() )
00140         {
00141             AKASSERT( (*it).pUserData );
00142             AK_PLUGIN_DELETE( AkPluginArrayAllocator::GetAllocator(), (*it).pUserData );
00143             BaseClass::EraseSwap( it );
00144             return true;
00145         }
00146         return false;
00147     }
00148 
00149     /// Terminate array.
00150     void Term()
00151     {
00152         if ( BaseClass::m_pItems )
00153         {
00154             RemoveAll();
00155             AkPluginArrayAllocator::Free( BaseClass::m_pItems );
00156             BaseClass::m_pItems = 0;
00157             BaseClass::m_ulReserved = 0;
00158         }
00159     }
00160 
00161     /// Finds an item in the array.
00162     typename AkArray<AkInputMapSlot<USER_DATA>, const AkInputMapSlot<USER_DATA>&, AkPluginArrayAllocator, 1>::Iterator FindEx( AK::IAkMixerInputContext * in_pInput ) const
00163     {
00164         AkInputMapSlot<USER_DATA> mapSlot;
00165         mapSlot.pContext = in_pInput;
00166         return BaseClass::FindEx( mapSlot );
00167     }
00168 
00169     /// Removes and destroys all items in the array.
00170     void RemoveAll()
00171     {
00172         for ( typename AkArray<AkInputMapSlot<USER_DATA>, const AkInputMapSlot<USER_DATA>&, AkPluginArrayAllocator, 1>::Iterator it = BaseClass::Begin(), itEnd = BaseClass::End(); it != itEnd; ++it )
00173         {
00174             AKASSERT( (*it).pUserData );
00175             AK_PLUGIN_DELETE( AkPluginArrayAllocator::GetAllocator(), (*it).pUserData );
00176             (*it).~AkInputMapSlot();
00177         }
00178         BaseClass::m_uLength = 0;
00179     }
00180 };
00181 
00182 #endif // _AK_MIXERINPUTMAP_H_