For example, the Red Alert 3 team at Electronic Arts observed that writing data into log files was causing significant performance degradation. They changed the logging system so that it accumulated its output into a memory buffer, writing the buffer out to disk only when it was filled. Then they moved the buffer dump routine out into a separate thread to avoid stalling the main game loop.
Streaming refers to the act of loading data in the background while the main program continues to run. Many games provide the player with a seam- less, load-screen-free playing experience by streaming data for upcoming lev- els from the DVD-ROM, Blu-ray disk or hard drive while the game is being played. Audio and texture data are probably the most commonly streamed types of data, but any type of data can be streamed, including geometry, level layouts and animation clips.
It should be pretty obvious from looking at the above list that creating a reliable and robust resource database is no small task. When designed well and implemented properly, the resource database can quite literally make the difference between a team that ships a hit game and a team that spins its wheels for 18 months before being forced by management to abandon the project (or worse). I know this to be true, because I’ve personally experienced both.
When loading data from files, the three biggest costs are seek times (i.e., moving the read head to the correct place on the physical media), the time required to open each individual file, and the time to read the data from the file into memory
When a single large file is used, all of these costs are minimized. A single file can be organized sequentially on the disk, reducing seek times to a minimum. And with only one file to open, the cost of opening individual resource files is eliminated
Solid-state drives (SSD) do not suffer from the seek time problems that plague spinning media like DVDs, Blu-ray discs and hard disc drives (HDD). However, no game console to date includes a solid-state drive as the primary fixed storage device (not even the PS4 and Xbox One)
Storing resources as a ZIP file is advantageous:
Every resource in a game must have some kind of globally unique identifier (GUID). The most common choice of GUID is the resource’s file system path (stored either as a string or a 32-bit hash)
C++ Object can be stored/loaded to and from a file then reconstructed
Uses "placement new" syntax
void *pObject = ConvertOffsetToPointer(objectOffset, pAddressOfFileImage);
::new(pObject) ClassName; // placement new syntax
Example Code:
// TestClass.h
\#ifndef TEST_CLASS_H_INCLUDED
\#define TEST_CLASS_H_INCLUDED
\#include \<iostream\>
class TestClass
{
public:
TestClass()
{
std::cout \<\< "Initial A,B: " \<\< a \<\< ", " \<\< b \<\< std::endl;
a = 5;
b = 4;
std::cout \<\< "Initted A,B: " \<\< a \<\< ", " \<\< b \<\< std::endl;
}
void myfunc2()
{
a -= 7;
b += a;
std::cout \<\< "a,b after myfunc2: " \<\< a \<\< ", " \<\< b \<\< std::endl;
}
private:
int a;
int b;
};
\#endif // end TEST_CLASS_H_INCLUDED
// create.cpp
\#include \<fstream\>
\#include \<iostream\>
\#include "TestClass.h"
int main(void)
{
TestClass testClass;
testClass.myfunc2();
std::ofstream outfile("TestClassBinary.bin");
if (!outfile.is_open()) {
std::cerr \<\< "Error opening file" \<\< std::endl;
return -1;
}
outfile.write((const char*)&testClass, sizeof(TestClass));
outfile.close();
return 0;
}
// read.cpp
\#include \<fstream\>
\#include \<iostream\>
\#include "TestClass.h"
int main(void)
{
TestClass testClass;
std::ifstream infile("TestClassBinary.bin");
if (!infile.is_open()) {
std::cerr \<\< "Error opening file" \<\< std::endl;
return -1;
}
infile.read((char*)&testClass, sizeof(TestClass));
infile.close();
// call the constructor on our read in object
std::cout \<\< "Calling constructor on object" \<\< std::endl;
::new((void*)&testClass) TestClass;
return 0;
}