这让我想起了一个文件系统,我在极短的时间内想出了加载 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 的控制台系统开发的。
副作用是数据被剥离了通常会被跳过的不必要的元数据。
它确实有缺点——一个关卡的所有数据都在一个文件中。这些可能会变得非常大,并且数据无法在文件之间共享,如果您有一组纹理,例如,它们在两个或多个级别中是通用的,则数据将在每个流文件中复制。另外,每次加载数据的加载过程都必须相同,不能有条件地跳过或添加元素到关卡。