-
Notifications
You must be signed in to change notification settings - Fork 793
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mpqapi: saner handling of hash/block tables #2855
base: master
Are you sure you want to change the base?
Conversation
Haven't looked at this, but i'm pretty excited :D |
if (!cur_archive.exists) { | ||
InitDefaultMpqHeader(&cur_archive, &fhdr); | ||
} else if (!ReadMPQHeader(&cur_archive, &fhdr)) { | ||
goto on_error; | ||
} | ||
cur_archive.sgpBlockTbl = new _BLOCKENTRY[BlockEntrySize / sizeof(_BLOCKENTRY)]; | ||
std::memset(cur_archive.sgpBlockTbl, 0, BlockEntrySize); | ||
cur_archive.blockTbl.resize(INDEX_ENTRIES); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This always uses a static size? Can blockTbl be made a std::array instead of a vector?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be made a std::array
, but if you want to move the tables quickly to/from the cache (rather than copying them), you'd have to go the extra step and make it a std::unique_ptr<std::array>>
. This would mess up the syntax when accessing the tables.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than a vector for a fixed-size array, use a unique_ptr<T[]>
. It is specialised for square brackets access.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would the advantage of using unique_ptr<T[]>
over vector
be? We lose the ability to do range-based for loops.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A vector is not the appropriate type for a fixed-size container. While it offers the nicest syntax among the options in stdlib, that alone not a good reason to use the wrong abstraction. In this case, unique_ptr<array>
is also a good option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't see how unique_ptr<T[]>
is superior to vector
in this case, when expressing and enforcing the container size is the main issue:
vector
is resizable when it ideally shouldn't be.unique_ptr<T[]>
has indeterminate size, and can be replaced with an array of a different size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds like unique_ptr<array>
is the most appropriate type here, despite somewhat awkward access syntax
Making this a draft for the moment. I've got a few more commits coming. |
0996900
to
947caa5
Compare
I've noticed problems w.r.t. error handling, or rather, lack thereof. Both Should Diablo outright crash when something like this happens? |
For one thing, the On the other hand, the game doesn't produce any log files so the log messages would get lost in most cases. I believe a failure to write is typically an indication of either a full disk, a permissions issue, or a hardware failure. Such errors should be rare, should typically manifest early on, and often require the user to take action. I'd say crashing is probably better than doing nothing, but given how unlikely these errors probably are, I don't feel very strongly one way or the other. Just my two cents. |
Avoiding corrupt saved games would, in essence, require atomic modifications to the MPQs. It would probably be done as follows:
|
The rationale for this is two-fold:
std::vector
is used to store the tables;new
anddelete
are gone