这让我想起了一个文件系统,它可以在极短的时间内加载CD的级别文件(将加载时间从10秒缩短到几乎瞬间),并且也适用于非CD媒体。它由三个版本的类组成,用于包装文件IO函数,所有版本都具有相同的接口:
class IFile
{
public:
IFile (class FileSystem &owner);
virtual Seek (...);
virtual Read (...);
virtual GetFilePosition ();
};
还有一个额外的类:
class FileSystem
{
public:
BeginStreaming (filename);
EndStreaming ();
IFile *CreateFile ();
};
你可以这样编写加载代码:
void LoadLevel (levelname)
{
FileSystem fs;
fs.BeginStreaming (levelname);
IFile *file = fs.CreateFile (level_map_name);
ReadLevelMap (fs, file);
delete file;
fs.EndStreaming ();
}
void ReadLevelMap (FileSystem &fs, IFile *file)
{
read some data from fs
get names of other files to load (like textures, object definitions, etc...)
for each texture file
{
IFile *texture_file = fs.CreateFile (some other file name)
CreateTexture (texture_file);
delete texture_file;
}
}
接下来,您将有三种操作模式:调试模式、流文件构建模式和发布模式。
在每种模式下,FileSystem对象都会创建不同的IFile对象。
在调试模式下,IFile对象只包装了标准IO函数。
在流文件构建中,IFile对象还包装了标准IO函数,但添加了写入到流文件(所有者FileSystem打开了流文件)每个读取的字节,以及写入任何文件指针位置查询的返回值(因此,如果需要知道文件大小,该信息被写入流文件)。这将把各种文件连接成一个大文件,但仅包含实际读取的数据。
发布模式将创建一个IFile,它不会打开文件或在文件中查找,而只是从流文件中读取(由所有者FileSystem对象打开)。
这意味着在发布模式下,所有数据都是在一个连续的读取系列中读取的(操作系统会对其进行良好的缓冲),而不是大量的查找和读取。这对于CD,其中寻找时间非常慢,是理想的。不用说,这是为基于CD的控制台系统开发的。
副作用是数据被剥离了通常会被跳过的不必要的元数据。
它确实有缺点 - 每个级别的所有数据都在一个文件中。这些文件可能会变得非常大,而且数据不能在文件之间共享。例如,如果您有一组纹理在两个或多个级别中是常见的,则每个流文件中都会重复该数据。此外,加载过程必须每次加载数据时都相同,无法有条件地跳过或添加元素到级别。