This is a small test we did once: non-blocking/asynchronous file loading. While a new resource is read from disk, at the same time the resource that was loaded before is parsed. In theory this should bring some speedups, especially when reading from slow media. However, I did not really notice any improvement when loading a limited amount of data from HDD (HDDs are much faster than optical media). Furthermore, the async loading code is very platform dependent and only works on Windows right now (Linux has some special functions as well). So we decided to not put it into the h3dutLoadResourcesFromDisk function, to keep the code there simple. Anyway, maybe the code is useful for someone, so I post it here:
Code:
#ifdef PLATFORM_WIN // Do asynchronous file loading on Windows
HANDLE hFile = INVALID_HANDLE_VALUE;
OVERLAPPED overlapped;
char *data0 = 0x0, *data1 = 0x0;
int size0 = 0, size1 = 0;
int res0 = 0, res1 = 0;
while( h3dQueryUnloadedResource( 0 ) != 0 )
{
// Wait until previous file reading request has finished (if any)
if( hFile != INVALID_HANDLE_VALUE )
{
if( !HasOverlappedIoCompleted( &overlapped ) ) continue;
CloseHandle( hFile ); hFile = INVALID_HANDLE_VALUE;
}
// Start reading next resource
res1 = h3dQueryUnloadedResource( res0 == 0 ? 0 : 1 );
if( res1 != 0 )
{
// Loop over search paths and try to open files
for( unsigned int i = 0; i < dirs.size(); ++i )
{
string fileName = dirs[i] + resourcePaths[h3dGetResType( res1 )] + "/" + h3dGetResName( res1 );
hFile = CreateFile( fileName.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED | FILE_FLAG_SEQUENTIAL_SCAN, 0 );
if( hFile != INVALID_HANDLE_VALUE ) break;
}
if( hFile != INVALID_HANDLE_VALUE )
{
// Start asynchronous reading
ZeroMemory( &overlapped, sizeof( OVERLAPPED ) );
size1 = GetFileSize( hFile, 0x0 );
data1 = new char[size1 + 1];
ReadFile( hFile, data1, size1, 0x0, &overlapped );
}
else
{
// Tell engine that file could not be found
h3dLoadResource( res1, 0x0, 0 );
result = false;
data1 = 0x0; size1 = 0; res1 = 0;
}
}
// Load current resource
if( res0 != 0 )
{
data0[size0] = '\0'; // NULL-terminate for XML
result &= h3dLoadResource( res0, data0, size0 + 1 );
delete[] data0;
}
// Set next resource as current resource
data0 = data1; size0 = size1; res0 = res1;
}
#else // Standard (blocking) file loading