• Announcements

Archived

This topic is now archived and is closed to further replies.

Supporting multiple versions of a file

Recommended Posts

RajanSky    100
class Dude
{
public:
char   m_Name[20];
int    m_Age;
}; 
Then, here's what the enum would look like:
enum Dude_IOParams
{
Dude_IO_name1,   // the 1 signifies the version
Dude_IO_age1
};

---2. Writing the read/write functions--- Here's what the read function would look like:
bool Dude::Read( ulong param, File &file )
{
switch( param )
{
case Dude_IO_name1:
return file.Read( &m_Name, 20, 1 );

case Dude_IO_age1:
return file.Read( &m_Age, sizeof(int), 1 );
};
}

---3. Representing the structure as an array of IO Params--- Here's what the version would look like:
ulong DudeVersion1[] =
{
DUDE_IO_name1,
DUDE_IO_age1
}

Read( DudeVersion1 );

... So, that's how it works. Now, here's the advantages of this method. ===1. Why this helps easily write and maintain save/load functions=== Suppose we decide to make a version2, but we change the age to be a float instead of an int. No problem- here's what we do: 1. We create our new structure:
ulong DudeVersion2[] =
{
DUDE_IO_name1,
DUDE_IO_age2    // this has been changed to float
}

case Dude_IO_age1:
{
int temp;
bool success = file.Read( &temp, sizeof(int), 1 );
m_Age = (float) temp;
return success;
}

So, now any time it encounters an outdated age parameter, it handles it correctly. This is nice because say we had not just DudeVersion1 which was outdated, but say there were 15 outdated versions. We only have to make the change in 1 place, not 15 places, so maintenance is relatively easy. The major drawbacks of this system though, are that it's a bit slower due to all the switch's, and a bit of a pain to set up initially... I'm not sure if much can be done about the speed, but as for the syntax, I got around that using macros. There are lots of neat tricks that this system lends itself to.. For example, say you have this structure:
ulong MonsterVersion5[] =
{
MONSTER_IO_hp1,
MONSTER_IO_mp1,
MONSTER_IO_stamina1,
MONSTER_IO_armor2,
MONSTER_IO_attack1,
MONSTER_IO_speed2
};

Now, say we want to create a version6, but all we want to do is add *one* new parameter- say it's "MONSTER_IO_weapon1"... Instead of recopying all of those parameters, all we have to do is:
ulong MonsterVersion6[] =
{
STRUCTURE( MonsterVersion5 ),
MONSTER_IO_weapon1
};