mirror of
https://github.com/libretro/scummvm.git
synced 2025-04-02 06:41:51 +00:00
ENGINES: Clean up SaveStateDescriptor.
Now SaveStateDescriptor no longer subclasses HashMap. Instead all possible saved meta data is included directly into SaveStateDescriptor. This is slightly less flexible, but we never needed that flexibility so far. On the other hand it should reduce the memory usage. At least on my system (Linux/amd64) the old SaveStateDescriptor had a size of 928 and the new SaveStateDescriptor has a size of 200.
This commit is contained in:
parent
a5b0792295
commit
09501be85b
@ -662,7 +662,7 @@ static Common::Error listSaves(const char *target) {
|
||||
" ---- ------------------------------------------------------\n");
|
||||
|
||||
for (SaveStateList::const_iterator x = saveList.begin(); x != saveList.end(); ++x) {
|
||||
printf(" %-4s %s\n", x->save_slot().c_str(), x->description().c_str());
|
||||
printf(" %-4d %s\n", x->getSaveSlot(), x->getDescription().c_str());
|
||||
// TODO: Could also iterate over the full hashmap, printing all key-value pairs
|
||||
}
|
||||
} else {
|
||||
|
@ -102,7 +102,7 @@ Common::InSaveFile *SaveLoad::openForLoading(const Common::String &target, int s
|
||||
// Fill the SaveStateDescriptor if it was provided
|
||||
if (descriptor) {
|
||||
// Initialize the SaveStateDescriptor
|
||||
descriptor->setVal("save_slot", Common::String('0' + slot));
|
||||
descriptor->setSaveSlot(slot);
|
||||
descriptor->setDeletableFlag(true);
|
||||
descriptor->setWriteProtectedFlag(false);
|
||||
|
||||
@ -132,7 +132,7 @@ Common::InSaveFile *SaveLoad::openForLoading(const Common::String &target, int s
|
||||
description += c;
|
||||
}
|
||||
}
|
||||
descriptor->setVal("description", description);
|
||||
descriptor->setDescription(description);
|
||||
}
|
||||
|
||||
// Return a substream, skipping the metadata
|
||||
|
@ -1350,15 +1350,15 @@ void Script::o_checkvalidsaves() {
|
||||
uint count = 0;
|
||||
SaveStateList::iterator it = list.begin();
|
||||
while (it != list.end()) {
|
||||
int8 slot = it->getVal("save_slot").lastChar() - '0';
|
||||
int8 slot = it->getSaveSlot();
|
||||
if (SaveLoad::isSlotValid(slot)) {
|
||||
debugScript(2, true, " Found valid savegame: %s", it->getVal("description").c_str());
|
||||
debugScript(2, true, " Found valid savegame: %s", it->getDescription().c_str());
|
||||
|
||||
// Mark this slot as used
|
||||
setVariable(slot, 1);
|
||||
|
||||
// Cache this slot's description
|
||||
_saveNames[slot] = it->getVal("description");
|
||||
_saveNames[slot] = it->getDescription();
|
||||
count++;
|
||||
}
|
||||
it++;
|
||||
|
@ -24,6 +24,17 @@
|
||||
#include "graphics/surface.h"
|
||||
#include "common/textconsole.h"
|
||||
|
||||
SaveStateDescriptor::SaveStateDescriptor()
|
||||
// FIXME: default to 0 (first slot) or to -1 (invalid slot) ?
|
||||
: _slot(-1), _description(), _isDeletable(true), _isWriteProtected(false),
|
||||
_saveDate(), _saveTime(), _playTime(), _thumbnail() {
|
||||
}
|
||||
|
||||
SaveStateDescriptor::SaveStateDescriptor(int s, const Common::String &d)
|
||||
: _slot(s), _description(d), _isDeletable(true), _isWriteProtected(false),
|
||||
_saveDate(), _saveTime(), _playTime(), _thumbnail() {
|
||||
}
|
||||
|
||||
void SaveStateDescriptor::setThumbnail(Graphics::Surface *t) {
|
||||
if (_thumbnail.get() == t)
|
||||
return;
|
||||
@ -31,42 +42,16 @@ void SaveStateDescriptor::setThumbnail(Graphics::Surface *t) {
|
||||
_thumbnail = Common::SharedPtr<Graphics::Surface>(t, Graphics::SharedPtrSurfaceDeleter());
|
||||
}
|
||||
|
||||
bool SaveStateDescriptor::getBool(const Common::String &key) const {
|
||||
if (contains(key)) {
|
||||
const Common::String value = getVal(key);
|
||||
bool valueAsBool;
|
||||
if (Common::parseBool(value, valueAsBool))
|
||||
return valueAsBool;
|
||||
error("SaveStateDescriptor: %s '%s' has unknown value '%s' for boolean '%s'",
|
||||
save_slot().c_str(), description().c_str(), value.c_str(), key.c_str());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SaveStateDescriptor::setDeletableFlag(bool state) {
|
||||
setVal("is_deletable", state ? "true" : "false");
|
||||
}
|
||||
|
||||
void SaveStateDescriptor::setWriteProtectedFlag(bool state) {
|
||||
setVal("is_write_protected", state ? "true" : "false");
|
||||
}
|
||||
|
||||
void SaveStateDescriptor::setSaveDate(int year, int month, int day) {
|
||||
Common::String buffer;
|
||||
buffer = Common::String::format("%.2d.%.2d.%.4d", day, month, year);
|
||||
setVal("save_date", buffer);
|
||||
_saveDate = Common::String::format("%.2d.%.2d.%.4d", day, month, year);
|
||||
}
|
||||
|
||||
void SaveStateDescriptor::setSaveTime(int hour, int min) {
|
||||
Common::String buffer;
|
||||
buffer = Common::String::format("%.2d:%.2d", hour, min);
|
||||
setVal("save_time", buffer);
|
||||
_saveTime = Common::String::format("%.2d:%.2d", hour, min);
|
||||
}
|
||||
|
||||
void SaveStateDescriptor::setPlayTime(int hours, int minutes) {
|
||||
Common::String buffer;
|
||||
buffer = Common::String::format("%.2d:%.2d", hours, minutes);
|
||||
setVal("play_time", buffer);
|
||||
_playTime = Common::String::format("%.2d:%.2d", hours, minutes);
|
||||
}
|
||||
|
||||
void SaveStateDescriptor::setPlayTime(uint32 msecs) {
|
||||
|
@ -24,7 +24,7 @@
|
||||
#define ENGINES_SAVESTATE_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/hash-str.h"
|
||||
#include "common/str.h"
|
||||
#include "common/ptr.h"
|
||||
|
||||
|
||||
@ -33,65 +33,60 @@ struct Surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* A hashmap describing details about a given save state.
|
||||
* TODO
|
||||
* Guaranteed to contain save_slot and description values.
|
||||
* Additional ideas: Playtime, creation date, thumbnail, ...
|
||||
* Object describing a save state.
|
||||
*
|
||||
* This at least includes the save slot number and a human readable
|
||||
* description of the save state.
|
||||
*
|
||||
* Further possibilites are a thumbnail, play time, creation date,
|
||||
* creation time, delete protected, write protection.
|
||||
*/
|
||||
class SaveStateDescriptor : public Common::StringMap {
|
||||
protected:
|
||||
Common::SharedPtr<Graphics::Surface> _thumbnail; // can be 0
|
||||
|
||||
class SaveStateDescriptor {
|
||||
public:
|
||||
SaveStateDescriptor() : _thumbnail() {
|
||||
setVal("save_slot", "-1"); // FIXME: default to 0 (first slot) or to -1 (invalid slot) ?
|
||||
setVal("description", "");
|
||||
}
|
||||
SaveStateDescriptor();
|
||||
SaveStateDescriptor(int s, const Common::String &d);
|
||||
|
||||
SaveStateDescriptor(int s, const Common::String &d) : _thumbnail() {
|
||||
setVal("save_slot", Common::String::format("%d", s));
|
||||
setVal("description", d);
|
||||
}
|
||||
/**
|
||||
* @param slot The saveslot id, as it would be passed to the "-x" command line switch.
|
||||
*/
|
||||
void setSaveSlot(int slot) { _slot = slot; }
|
||||
|
||||
SaveStateDescriptor(const Common::String &s, const Common::String &d) : _thumbnail() {
|
||||
setVal("save_slot", s);
|
||||
setVal("description", d);
|
||||
}
|
||||
/**
|
||||
* @return The saveslot id, as it would be passed to the "-x" command line switch.
|
||||
*/
|
||||
int getSaveSlot() const { return _slot; }
|
||||
|
||||
/** The saveslot id, as it would be passed to the "-x" command line switch. */
|
||||
Common::String &save_slot() { return getVal("save_slot"); }
|
||||
/**
|
||||
* @param desc A human readable description of the save state.
|
||||
*/
|
||||
void setDescription(const Common::String &desc) { _description = desc; }
|
||||
|
||||
/** The saveslot id, as it would be passed to the "-x" command line switch (read-only variant). */
|
||||
const Common::String &save_slot() const { return getVal("save_slot"); }
|
||||
|
||||
/** A human readable description of the save state. */
|
||||
Common::String &description() { return getVal("description"); }
|
||||
|
||||
/** A human readable description of the save state (read-only variant). */
|
||||
const Common::String &description() const { return getVal("description"); }
|
||||
/**
|
||||
* @return A human readable description of the save state.
|
||||
*/
|
||||
const Common::String &getDescription() const { return _description; }
|
||||
|
||||
/** Optional entries only included when querying via MetaEngine::querySaveMetaInfo */
|
||||
|
||||
/**
|
||||
* Returns the value of a given key as boolean.
|
||||
* It accepts 'true', 'yes' and '1' for true and
|
||||
* 'false', 'no' and '0' for false.
|
||||
* (FIXME:) On unknown value it errors out ScummVM.
|
||||
* On unknown key it returns false as default.
|
||||
* Defines whether the save state is allowed to be deleted.
|
||||
*/
|
||||
bool getBool(const Common::String &key) const;
|
||||
void setDeletableFlag(bool state) { _isDeletable = state; }
|
||||
|
||||
/**
|
||||
* Sets the 'is_deletable' key, which indicates if the
|
||||
* given savestate is safe for deletion.
|
||||
* Queries whether the save state is allowed to be deleted.
|
||||
*/
|
||||
void setDeletableFlag(bool state);
|
||||
bool getDeletableFlag() const { return _isDeletable; }
|
||||
|
||||
/**
|
||||
* Sets the 'is_write_protected' key, which indicates if the
|
||||
* given savestate can be overwritten or not
|
||||
* Defines whether the save state is write protected.
|
||||
*/
|
||||
void setWriteProtectedFlag(bool state);
|
||||
void setWriteProtectedFlag(bool state) { _isWriteProtected = state; }
|
||||
|
||||
/**
|
||||
* Queries whether the save state is write protected.
|
||||
*/
|
||||
bool getWriteProtectedFlag() const { return _isWriteProtected; }
|
||||
|
||||
/**
|
||||
* Return a thumbnail graphics surface representing the savestate visually.
|
||||
@ -109,24 +104,100 @@ public:
|
||||
void setThumbnail(Graphics::Surface *t);
|
||||
|
||||
/**
|
||||
* Sets the 'save_date' key properly, based on the given values.
|
||||
* Sets the date the save state was created.
|
||||
*
|
||||
* @param year Year of creation.
|
||||
* @param month Month of creation.
|
||||
* @param day Day of creation.
|
||||
*/
|
||||
void setSaveDate(int year, int month, int day);
|
||||
|
||||
/**
|
||||
* Sets the 'save_time' key properly, based on the given values.
|
||||
* Queries a human readable description of the date the save state was created.
|
||||
*
|
||||
* This will return an empty string in case the value is not set.
|
||||
*/
|
||||
const Common::String &getSaveDate() const { return _saveDate; }
|
||||
|
||||
/**
|
||||
* Sets the time the save state was created.
|
||||
*
|
||||
* @param hour Hour of creation.
|
||||
* @param min Minute of creation.
|
||||
*/
|
||||
void setSaveTime(int hour, int min);
|
||||
|
||||
/**
|
||||
* Sets the 'play_time' key properly, based on the given values.
|
||||
* Queries a human readable description of the time the save state was created.
|
||||
*
|
||||
* This will return an empty string in case the value is not set.
|
||||
*/
|
||||
const Common::String &getSaveTime() const { return _saveTime; }
|
||||
|
||||
/**
|
||||
* Sets the time the game was played before the save state was created.
|
||||
*
|
||||
* @param hours How many hours the user played the game so far.
|
||||
* @param min How many minutes the user played the game so far.
|
||||
*/
|
||||
void setPlayTime(int hours, int minutes);
|
||||
|
||||
/**
|
||||
* Sets the 'play_time' key properly, based on the given value.
|
||||
* Sets the time the game was played before the save state was created.
|
||||
*
|
||||
* @param msecs How many milliseconds the user played the game so far.
|
||||
*/
|
||||
void setPlayTime(uint32 msecs);
|
||||
|
||||
/**
|
||||
* Queries a human readable description of the time the game was played
|
||||
* before the save state was created.
|
||||
*
|
||||
* This will return an empty string in case the value is not set.
|
||||
*/
|
||||
const Common::String &getPlayTime() const { return _playTime; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* The saveslot id, as it would be passed to the "-x" command line switch.
|
||||
*/
|
||||
int _slot;
|
||||
|
||||
/**
|
||||
* A human readable description of the save state.
|
||||
*/
|
||||
Common::String _description;
|
||||
|
||||
/**
|
||||
* Whether the save state can be deleted.
|
||||
*/
|
||||
bool _isDeletable;
|
||||
|
||||
/**
|
||||
* Whether the save state is write protected.
|
||||
*/
|
||||
bool _isWriteProtected;
|
||||
|
||||
/**
|
||||
* Human readable description of the date the save state was created.
|
||||
*/
|
||||
Common::String _saveDate;
|
||||
|
||||
/**
|
||||
* Human readable description of the time the save state was created.
|
||||
*/
|
||||
Common::String _saveTime;
|
||||
|
||||
/**
|
||||
* Human readable description of the time the game was played till the
|
||||
* save state was created.
|
||||
*/
|
||||
Common::String _playTime;
|
||||
|
||||
/**
|
||||
* The thumbnail of the save state.
|
||||
*/
|
||||
Common::SharedPtr<Graphics::Surface> _thumbnail;
|
||||
};
|
||||
|
||||
/** List of savestates. */
|
||||
|
@ -131,7 +131,7 @@ void SaveLoadChooser::handleCommand(CommandSender *sender, uint32 cmd, uint32 da
|
||||
if (_list->isEditable() || !_list->getSelectedString().empty()) {
|
||||
_list->endEditMode();
|
||||
if (!_saveList.empty()) {
|
||||
setResult(atoi(_saveList[selItem].save_slot().c_str()));
|
||||
setResult(_saveList[selItem].getSaveSlot());
|
||||
_resultString = _list->getSelectedString();
|
||||
}
|
||||
close();
|
||||
@ -141,7 +141,7 @@ void SaveLoadChooser::handleCommand(CommandSender *sender, uint32 cmd, uint32 da
|
||||
case kChooseCmd:
|
||||
_list->endEditMode();
|
||||
if (!_saveList.empty()) {
|
||||
setResult(atoi(_saveList[selItem].save_slot().c_str()));
|
||||
setResult(_saveList[selItem].getSaveSlot());
|
||||
_resultString = _list->getSelectedString();
|
||||
}
|
||||
close();
|
||||
@ -154,7 +154,7 @@ void SaveLoadChooser::handleCommand(CommandSender *sender, uint32 cmd, uint32 da
|
||||
MessageDialog alert(_("Do you really want to delete this savegame?"),
|
||||
_("Delete"), _("Cancel"));
|
||||
if (alert.runModal() == GUI::kMessageOK) {
|
||||
(*_plugin)->removeSaveState(_target.c_str(), atoi(_saveList[selItem].save_slot().c_str()));
|
||||
(*_plugin)->removeSaveState(_target.c_str(), _saveList[selItem].getSaveSlot());
|
||||
|
||||
setResult(-1);
|
||||
_list->setSelected(-1);
|
||||
@ -241,10 +241,10 @@ void SaveLoadChooser::updateSelection(bool redraw) {
|
||||
_playtime->setLabel(_("No playtime saved"));
|
||||
|
||||
if (selItem >= 0 && !_list->getSelectedString().empty() && _metaInfoSupport) {
|
||||
SaveStateDescriptor desc = (*_plugin)->querySaveMetaInfos(_target.c_str(), atoi(_saveList[selItem].save_slot().c_str()));
|
||||
SaveStateDescriptor desc = (*_plugin)->querySaveMetaInfos(_target.c_str(), _saveList[selItem].getSaveSlot());
|
||||
|
||||
isDeletable = desc.getBool("is_deletable") && _delSupport;
|
||||
isWriteProtected = desc.getBool("is_write_protected");
|
||||
isDeletable = desc.getDeletableFlag() && _delSupport;
|
||||
isWriteProtected = desc.getWriteProtectedFlag();
|
||||
|
||||
// Don't allow the user to change the description of write protected games
|
||||
if (isWriteProtected)
|
||||
@ -259,16 +259,19 @@ void SaveLoadChooser::updateSelection(bool redraw) {
|
||||
}
|
||||
|
||||
if (_saveDateSupport) {
|
||||
if (desc.contains("save_date"))
|
||||
_date->setLabel(_("Date: ") + desc.getVal("save_date"));
|
||||
const Common::String &saveDate = desc.getSaveDate();
|
||||
if (!saveDate.empty())
|
||||
_date->setLabel(_("Date: ") + saveDate);
|
||||
|
||||
if (desc.contains("save_time"))
|
||||
_time->setLabel(_("Time: ") + desc.getVal("save_time"));
|
||||
const Common::String &saveTime = desc.getSaveTime();
|
||||
if (!saveTime.empty())
|
||||
_time->setLabel(_("Time: ") + saveTime);
|
||||
}
|
||||
|
||||
if (_playTimeSupport) {
|
||||
if (desc.contains("play_time"))
|
||||
_playtime->setLabel(_("Playtime: ") + desc.getVal("play_time"));
|
||||
const Common::String &playTime = desc.getPlayTime();
|
||||
if (!playTime.empty())
|
||||
_playtime->setLabel(_("Playtime: ") + playTime);
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,25 +329,25 @@ void SaveLoadChooser::updateSaveList() {
|
||||
ListWidget::ColorList colors;
|
||||
for (SaveStateList::const_iterator x = _saveList.begin(); x != _saveList.end(); ++x) {
|
||||
// Handle gaps in the list of save games
|
||||
saveSlot = atoi(x->save_slot().c_str());
|
||||
saveSlot = x->getSaveSlot();
|
||||
if (curSlot < saveSlot) {
|
||||
while (curSlot < saveSlot) {
|
||||
SaveStateDescriptor dummySave(curSlot, "");
|
||||
_saveList.insert_at(curSlot, dummySave);
|
||||
saveNames.push_back(dummySave.description());
|
||||
saveNames.push_back(dummySave.getDescription());
|
||||
colors.push_back(ThemeEngine::kFontColorNormal);
|
||||
curSlot++;
|
||||
}
|
||||
|
||||
// Sync the save list iterator
|
||||
for (x = _saveList.begin(); x != _saveList.end(); ++x) {
|
||||
if (atoi(x->save_slot().c_str()) == saveSlot)
|
||||
if (x->getSaveSlot() == saveSlot)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Show "Untitled savestate" for empty/whitespace savegame descriptions
|
||||
Common::String description = x->description();
|
||||
Common::String description = x->getDescription();
|
||||
Common::String trimmedDescription = description;
|
||||
trimmedDescription.trim();
|
||||
if (trimmedDescription.empty()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user