Table des matières

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 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_