Skip to content
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

Added "oldest save" and "slots 1-5" as options for "auto load savestate" #11202

Merged
merged 2 commits into from
Jun 26, 2018

Conversation

hissingshark
Copy link
Contributor

This adds some functionality to Auto Load Savestate. Previously it toggled on/off auto-loading of the newest savestate.
Now there is a choice of newest, oldest or a fixed slot number.
In other emulators I often use an oldest savestate that takes you straight to the main menu "press start" type of screen, to cut down on loading times as my default (good for guests too). The option of a set slot number just gave some additional flexibility whilst I was there.

In UI/EmuScreen.cpp I've used a switch/case and a ternary operator. I've tried a version that uses if/else instead but couldn't decide which was preferable for readability. I look forward to your guidance there.

Core/Config.cpp Outdated
@@ -352,7 +352,7 @@ static ConfigSetting generalSettings[] = {
ConfigSetting("ForceLagSync", &g_Config.bForceLagSync, false, true, true),

ReportedConfigSetting("NumWorkerThreads", &g_Config.iNumWorkerThreads, &DefaultNumWorkers, true, true),
ConfigSetting("EnableAutoLoad", &g_Config.bEnableAutoLoad, false, true, true),
ConfigSetting("EnableAutoLoad", &g_Config.iEnableAutoLoad, false, true, true),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default should be 0, rather than false, now. It would be preferable to add an enum to ConfigValues.h assuming #11187 gets merged.

Also, since we're changing the value anyway, maybe "AutoLoadSaveState" or something is a better name. AutoLoad makes me think about auto loading a game (and auto loading the last played game is not a totally crazy feature...)

-[Unknown]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes of course, misunderstood the prototype there. I've gone the enum way as suggested.

}

bool operator ! (const tm &t1) {
if (t1.tm_year | t1.tm_mon | t1.tm_mday | t1.tm_hour | t1.tm_min | t1.tm_sec) return false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, bitwise | seems odd here, although it might be fine. Maybe better to use || for clarity?

-[Unknown]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bitwise works. Was quite pleased with that solution. I'd brushed up on them the week before and as I was overloading I was thinking low level.
But as the members of the tm struct are only int I can use || just fine. And as you say that's more readable.

if (File::Exists(fn)) {
tm time;
bool success = File::GetModifTime(fn, time);
if ( (success && !oldestDate) || (success && oldestDate > time) ) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Would prefer (success && (!oldestDate || oldestDate > time)).

-[Unknown]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's much better. Like simplifying like terms in an equation.
Got carried away with overloading the ! and the >.

UI/EmuScreen.cpp Outdated
SaveState::LoadSlot(gamePath_, lastSlot, &AfterSaveStateAction);
g_Config.iCurrentStateSlot = lastSlot;
switch (g_Config.iEnableAutoLoad) {
case 0 : return; // "AutoLoad Off"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general for switches, we use the convention:

switch (variable) {
case value1:
	stuff();
	break;

case value2:
case value3:
	stuffFor2Or3();

default:
	break;
}

It's fine on the same line, but the cases shouldn't indent (like labels) and shoudln't have a space before the :.

All that said, maybe it could just be like...

switch (g_Config.iEnableAutoLoad) {
case (int)SaveStateAutoLoad::OFF: return;

case (int)SaveStateAutoLoad::OLDEST: autoSlot = SaveState::GetOldestSlot(gamePath_); break;
case (int)SaveStateAutoLoad::NEWEST: autoSlot = SaveState::GetNewestSlot(gamePath_); break;

default:
	// The only other values supported are actual slot numbers.
	// (code for that)
}

That way it automatically handles if we add new slots later or whatever.

-[Unknown]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The enum improves readability but makes the config file less intuitive. I guess users aren't meant to be editing it by hand so no matter.

And as you say, it more easily allows for more slots in future. With that in mind I spent some time looking into generating
static const char *autoLoadSaveStateChoices[] = { "Off", "Oldest Save", "Newest Save", "Slot 1", "Slot 2", "Slot 3", "Slot 4", "Slot 5" };
dynamically based on the
static const int NUM_SLOTS = 5;
so there's just that 1 constant to change, but as PopupMultiChoice takes a const array it can't be done, so far as I can tell.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right - I think it's okay for now. But PopupMultiChoiceDynamic exists for that purpose.

-[Unknown]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did see that and thought I'd cracked it, but didn't think it was going to be suitable for some reason. Likely I've misunderstood the prototype. Will have a another look at that for completeness.

@hissingshark
Copy link
Contributor Author

hissingshark commented Jun 25, 2018

Thank you for all of the constructive feedback. It's been educational.
All changes so far build and test ok in practice.

edit: just realised I've not cast my cases to int e.g.
case (int)AutoLoadSaveState::OFF:
It works, but should I be adding that for extra type safety or something?

Copy link
Collaborator

@unknownbrackets unknownbrackets left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, just one nit - sorry, enum class is new in c++11.

-[Unknown]

@@ -71,3 +71,9 @@ enum class SmallDisplayZoom {
AUTO = 2,
MANUAL = 3,
};

enum AutoLoadSaveState {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will "pollute" the global namespace so that OFF is 0. If you use enum class AutoLoadSaveState { instead, it will require AutoLoadSaveState::OFF and OFF alone won't mean anything.

But in that case, it will require a cast to (int).

-[Unknown]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that explains your cast. I'll implement and test now.
For future reference should I be squashing my commits as I go along like this, or leaving them perhaps to show how we got here?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either way - usually I worry about if it would give me useful information 6 months from now. So a typo fix, definitely not. Whether something is a struct or a class, or enum vs enum class, probably not... but why it's slot - 3 or why something uses a mutex - probably so.

But generally I err on more commits than less, since bisecting 2000 commits vs 1000 commits is not a big difference anyway.

-[Unknown]

@unknownbrackets unknownbrackets merged commit aa927e0 into hrydgard:master Jun 26, 2018
@hissingshark hissingshark deleted the autoload branch June 26, 2018 21:11
@unknownbrackets unknownbrackets added this to the v1.7.0 milestone Jun 29, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants