mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 20:12:21 +02:00
151 lines
No EOL
5.7 KiB
C++
151 lines
No EOL
5.7 KiB
C++
#include "BFPlatform.h"
|
|
|
|
#ifdef BF_WWISE_ENABLED
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// AkDefaultLowLevelIODispatcher.cpp
|
|
//
|
|
// Canvas for implementation of the AK::StreamMgr::IAkFileLocationResolver,
|
|
// meant to be used in a multiple streaming devices system. It is this
|
|
// object that should be registered as the one and only
|
|
// AK::StreamMgr::IAkFileLocationResolver of the Stream Manager
|
|
// (by calling AK::StreamMgr::SetFileLocationResolver()).
|
|
//
|
|
// It forwards the calls to Open() to one of the low level I/O devices
|
|
// that were added to it using AddDevice(). These devices must thus also
|
|
// implement AK::StreamMgr::IAkFileLocationResolver.
|
|
//
|
|
// The strategy for device dispatching is that of a chain of responsibility:
|
|
// the dispatcher asks the first file resolver hook to open the file. If it
|
|
// fails, then it tries with the second, and so on, until a hook succeeds.
|
|
// This is inefficient. In your game, you should implement a strategy of
|
|
// your own (see CAkDefaultLowLevelIODispatcher::Open()).
|
|
//
|
|
// Copyright (c) 2006 Audiokinetic Inc. / All Rights Reserved
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "Common.h"
|
|
#include "AkDefaultLowLevelIODispatcher.h"
|
|
#include <AK/Tools/Common/AkAssert.h>
|
|
|
|
|
|
CAkDefaultLowLevelIODispatcher::CAkDefaultLowLevelIODispatcher()
|
|
:m_uNumDevices( 0 )
|
|
{
|
|
RemoveAllDevices();
|
|
}
|
|
|
|
CAkDefaultLowLevelIODispatcher::~CAkDefaultLowLevelIODispatcher()
|
|
{
|
|
}
|
|
|
|
// Returns a file descriptor for a given file name (string).
|
|
AKRESULT CAkDefaultLowLevelIODispatcher::Open(
|
|
const AkOSChar* in_pszFileName, // File name.
|
|
AkOpenMode in_eOpenMode, // Open mode.
|
|
AkFileSystemFlags * in_pFlags, // Special flags. Can pass NULL.
|
|
bool & io_bSyncOpen, // If true, the file must be opened synchronously. Otherwise it is left at the File Location Resolver's discretion. Return false if Open needs to be deferred.
|
|
AkFileDesc & out_fileDesc // Returned file descriptor.
|
|
)
|
|
{
|
|
// Here, you need to define a strategy to determine which device is going to handle this file's I/O.
|
|
// You could use some naming convention, or use the AkFileSystemFlags or file name extension if it depends
|
|
// on file type, or define a map, or read the mapping from an XML file... it is up to the game's organization.
|
|
// Since this default implementation doesn't know anything about that, it forwards the calls to each
|
|
// device until one of them succeeds.
|
|
|
|
// Disable deferred opening because devices may usually return AK_Success if io_bSyncOpen=false,
|
|
// and we count on the fact that they will return AK_Fail to select the proper device.
|
|
io_bSyncOpen = true;
|
|
|
|
AKRESULT eResult = AK_FileNotFound;
|
|
AkUInt32 uDevice = 0;
|
|
while ( uDevice < AK_MAX_IO_DEVICES
|
|
&& eResult != AK_Success )
|
|
{
|
|
if ( m_arDevices[uDevice] )
|
|
{
|
|
eResult = m_arDevices[uDevice]->Open(
|
|
in_pszFileName, // File name.
|
|
in_eOpenMode, // Open mode.
|
|
in_pFlags, // Special flags. Can pass NULL.
|
|
io_bSyncOpen, // If true, the file must be opened synchronously. Otherwise it is left at the File Location Resolver's discretion. Return false if Open needs to be deferred.
|
|
out_fileDesc // Returned file descriptor.
|
|
);
|
|
AKASSERT( io_bSyncOpen || !"It is illegal to reset io_bSyncOpen" );
|
|
}
|
|
++uDevice;
|
|
}
|
|
|
|
return eResult;
|
|
}
|
|
|
|
// Returns a file descriptor for a given file ID.
|
|
AKRESULT CAkDefaultLowLevelIODispatcher::Open(
|
|
AkFileID in_fileID, // File ID.
|
|
AkOpenMode in_eOpenMode, // Open mode.
|
|
AkFileSystemFlags * in_pFlags, // Special flags. Can pass NULL.
|
|
bool & io_bSyncOpen, // If true, the file must be opened synchronously. Otherwise it is left at the File Location Resolver's discretion. Return false if Open needs to be deferred.
|
|
AkFileDesc & out_fileDesc // Returned file descriptor.
|
|
)
|
|
{
|
|
// Here, you need to define a strategy to determine which device is going to handle this file's I/O.
|
|
// You could use the AkFileSystemFlags if it depends on file type, or define a map, or read the mapping
|
|
// from an XML file... it is up to the game's organization.
|
|
// Since this default implementation doesn't know anything about that, it forwards the calls to each
|
|
// device until one of them succeeds.
|
|
|
|
// Disable deferred opening because devices may usually return AK_Success if io_bSyncOpen=false,
|
|
// and we count on the fact that they will return AK_Fail to select the proper device.
|
|
io_bSyncOpen = true;
|
|
|
|
AKRESULT eResult = AK_FileNotFound;
|
|
AkUInt32 uDevice = 0;
|
|
while ( uDevice < AK_MAX_IO_DEVICES
|
|
&& eResult != AK_Success )
|
|
{
|
|
if ( m_arDevices[uDevice] )
|
|
{
|
|
eResult = m_arDevices[uDevice]->Open(
|
|
in_fileID, // File ID.
|
|
in_eOpenMode, // Open mode.
|
|
in_pFlags, // Special flags. Can pass NULL.
|
|
io_bSyncOpen, // If true, the file must be opened synchronously. Otherwise it is left at the File Location Resolver's discretion. Return false if Open needs to be deferred.
|
|
out_fileDesc // Returned file descriptor.
|
|
);
|
|
AKASSERT( io_bSyncOpen || !"It is illegal to reset io_bSyncOpen" );
|
|
}
|
|
++uDevice;
|
|
}
|
|
|
|
return eResult;
|
|
}
|
|
|
|
AKRESULT CAkDefaultLowLevelIODispatcher::AddDevice(
|
|
AK::StreamMgr::IAkFileLocationResolver * in_pHook
|
|
)
|
|
{
|
|
// Add the device in a free slot.
|
|
for ( AkUInt32 uRecord = 0; uRecord < AK_MAX_IO_DEVICES; uRecord++ )
|
|
{
|
|
if ( !m_arDevices[uRecord] )
|
|
{
|
|
m_arDevices[uRecord] = in_pHook;
|
|
++m_uNumDevices;
|
|
return AK_Success;
|
|
}
|
|
}
|
|
AKASSERT( !"Cannot hold any more I/O devices" );
|
|
return AK_Fail;
|
|
}
|
|
|
|
void CAkDefaultLowLevelIODispatcher::RemoveAllDevices()
|
|
{
|
|
for ( AkUInt32 uRecord = 0; uRecord < AK_MAX_IO_DEVICES; uRecord++ )
|
|
m_arDevices[uRecord] = NULL;
|
|
m_uNumDevices = 0;
|
|
}
|
|
|
|
#endif |