datahead <automailer(a)forum.secretchronicles.de> writes:
Post via forum by datahead <cjj_009@xxxxxxxxxx>:
This was grimshaw's response:
[quote]
Yeah, reading C++ objects in the binary form will never be 100%
efficient, but it can approach that pretty close. But it will depend
on how you design it too.
I have to agree that I didn’t understood the point first. With “binary
format” I thought you wanted to use a structured binary file format with
a specification other programs can implement easily. That is, like XML,
but with raw bytes, like a binary protocol that is spoken over a TCP
line. I didn’t realise you meant a memory dump.
Which brings me to my first point. Sure, a memory dump is fairly easy to
generate and reload. However, it lacks any kind of specification and
makes it near to impossible for other programs to read it in. This was
for example the problem with MS Word 2003 .doc files; they were
basically memory dumps of MS Word, which made it so hard to create an
implementation for them in OpenOffice. This is, as I understood it, the
main reason why MS Word switched to — guess what — an XML-based format
(OOXML). There was an attempt to write a level generator on the old SMC
forums; things like that will become overly complicated with memory
dumps from TSC.
For example, I inspected your level format
Regarding the current level format, we are not content with it
anyway. It should not be used for comparison. There are even two
tickets on the tracker concerning themselves with the level format:
*
https://github.com/Secretchronicles/TSC/issues/169
*
https://github.com/Secretchronicles/TSC/issues/354
And one for the savegame format:
*
https://github.com/Secretchronicles/TSC/issues/380
{
std::vector<SpriteInstance> sprites(numSpritesInTheFile);
fread(&sprites[0], sizeof(SpriteInstance), numSpritesInTheFile, filePointer);
}
So, here’s the memory dump (or rather the loading of it). This results
in a file format depending on the memory layout of the target
machine. How does one distribute a level then? Say, if I want to run my
level created on a little-endian system on a big-endian one? What do we
do when we expand the sprite struct with new members in later versions,
which will break any existing memory dump? What happens if the target
system uses another implementation of the C++ standard library, which
lays memory out differently? Oh okay, that’s why you used a C struct
instead of a proper object-oriented C++ class, they have more defined
memory behaviour. So sacrifice OOP/code design for speed. Since I
usually prefer a well-layed-out and -designed codebase over speed, I find
this an unusual approach.
Apart from that I suspect such code to rely on undefined behaviour. Is
there a gurantee in the C++ standard that the elements in an std::vector
are really consecutive in the underlying memory, with nothing
in-between? This seems like an implementation detail one should not rely
on (and doing so violates the secrecy principle anyway). I could imagine
the container class to encapsulate the respective items in an own
element class instance, thus breaking the assumption of consecutive
memory. If it indeed causes undefined behaviour, we would make ourselves
dependant on a specific compiler/libstdc++ version, which is something
definitely to avoid.
[quote]Apart from that I find binary file formats a nightmare for
debugging purposes.[/quote]
We would be using XML for most debugging, and we would make this the
most visible format to end users who create levels.
So instead of one level loader to maintain we then have two level
loaders to maintain, which may expose different behaviour due to bugs
that will happen anyway. I don’t find this a good idea.
Vale,
Quintus
--
#!/sbin/quintus
Blog:
http://www.guelkerdev.de
GnuPG key: F1D8799FBCC8BC4F