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

Track Time Played (Core and QT) #11469

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open

Conversation

aminoa
Copy link
Contributor

@aminoa aminoa commented Jan 22, 2023

This adds a total "Time Played" tab in the QT interface - the time is started at the beginning of emulation and ended when emulation shuts down. A general TimePlayed class is implemented which the desktop QT interface pulls from. This does not require a standard exit of emulation to count the time.

image

Edit (January 2025): A toggle has been added to allow the user to disable time tracking if desired.

image

Copy link
Member

@BhaaLseN BhaaLseN left a comment

Choose a reason for hiding this comment

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

@dolphin-emu-bot rebuild

I like the idea in general; and we could explore a future extension of this to also work for Wii games and write their playtime to the NAND (so they show up in the Wii menu).

Also, your commits are currently structured in a way that they reflect your personal TODO list and/or progression, which is not too useful for us. We'd prefer one (or more) commits that are self-contained, build in isolation and have a commit message that explains their intent.
In this case, one commit is probably good enough, and should be easily possible as follows:


To squash those commits into one before continuing; you can use the following commands (replace upstream with the name of the Dolphin remote and origin with the name of your Fork remote):

git fetch upstream
git reset --soft upstream/master
git commit -m "your commit message here"
git push -f origin HEAD

The first command makes sure you get the latest commits from master (from the Dolphin repository) to work on; the second picks all your changes, switches to that master state and puts the changes in the staging area. The third command then commits it so you have one commit total that has all the changes (which you can also replace with your commit method of choice, such as git gui or any other GUI tool); and the fourth command pushes your current branch into your own remote (which should be your Fork) while overwriting all previous changes (to update this PR).

Source/Core/Common/CommonPaths.h Outdated Show resolved Hide resolved
Source/Core/Core/ConfigManager.cpp Outdated Show resolved Hide resolved
Source/Core/Core/Core.cpp Outdated Show resolved Hide resolved
Source/Core/Core/Core.cpp Outdated Show resolved Hide resolved
Source/Core/Core/Core.cpp Outdated Show resolved Hide resolved
Source/Core/Core/Core.cpp Outdated Show resolved Hide resolved
Source/Core/Core/TimePlayed.cpp Outdated Show resolved Hide resolved
Source/Core/DolphinLib.vcxproj Outdated Show resolved Hide resolved
Source/UnitTests/UnitTests.vcxproj Outdated Show resolved Hide resolved
Source/UnitTests/UnitTests.vcxproj.user Outdated Show resolved Hide resolved
@aminoa aminoa closed this Jan 25, 2023
@aminoa aminoa reopened this Jan 25, 2023
@aminoa aminoa marked this pull request as draft January 26, 2023 01:59
@delroth
Copy link
Member

delroth commented Jan 26, 2023

This needs to be made translatable. https://doc.qt.io/qt-6/i18n-source-translation.html#using-numbered-arguments

@aminoa aminoa marked this pull request as ready for review January 26, 2023 05:42
@MayImilae
Copy link
Contributor

So design wise, but I'm concerned about the amount of horizontal space the time played takes in that screenshot. I would definitely prefer if it was in a shortened format like this - "6h 8m". It still conveys the information but it takes WAY less space.

Source/Core/Core/CMakeLists.txt Outdated Show resolved Hide resolved
Source/Core/Core/HW/CPU.cpp Outdated Show resolved Hide resolved
@aminoa
Copy link
Contributor Author

aminoa commented Jan 26, 2023

I squashed the commits again though the language files seemed to be automatically modified

@JosJuice
Copy link
Member

JosJuice commented Jan 26, 2023

It looks as if you rebased this pull request on the latest version of master but then undid the changes from the last version of master.

EDIT: You undid more than just the latest commit, actually. See the change to State.cpp, for instance.

@BhaaLseN
Copy link
Member

The git fetch upstream is important, and must be done before every reset if you stick to the recipe above.

@JosJuice
Copy link
Member

JosJuice commented Jan 26, 2023

@BhaaLseN Hold on, why is there a soft reset in the instructions you posted? I'm pretty sure that's the cause of this happening.

@aminoa
Copy link
Contributor Author

aminoa commented Jan 26, 2023

The git fetch upstream is important, and must be done before every reset if you stick to the recipe above.

I did that, I followed these steps that were posted before.

git fetch upstream
git reset --soft upstream/master
git commit -m "your commit message here"
git push -f origin HEAD

@BhaaLseN
Copy link
Member

BhaaLseN commented Jan 27, 2023

@BhaaLseN Hold on, why is there a soft reset in the instructions you posted? I'm pretty sure that's the cause of this happening.

The soft reset leaves changes (from this branch; not from the diff between the old and new master) in the staging area, vs. a mixed reset that leaves them unstaged. It shouldn't cause this problem (at least not by itself). I didn't check history yet, but a git pull beforehand is likely to cause this.

It might cause this when the commits this branch is based on are suddenly gone; but this would mean that master was rewritten; or that this PR was based on another one (which was rebased in the mean time) - neither of which is the case here.

I'm afraid at this point, the only way to fix this is by unstaging the unintended reverts by hand, and resetting them locally. At least I can't think of a simple way to get back; other than git reset --hard a139affaf843231ce88b6cb75d34b19c72d37767 and trying again (except that I don't think I can force GitHub to give me that ref, so I can't try at the moment)

@JosJuice
Copy link
Member

The soft reset leaves changes (from this branch; not from the diff between the old and new master) in the staging area, vs. a mixed reset that leaves them unstaged. It shouldn't cause this problem (at least not by itself).

When you soft reset, the state of all files is kept as they were. That is, not only are the changes from the PR preserved, but none of the files that have been modified in master are brought up to date with master. When you then commit your staged changes, you are committing your old versions of files that have been modified in master.

@BhaaLseN
Copy link
Member

BhaaLseN commented Jan 27, 2023

The soft reset leaves changes (from this branch; not from the diff between the old and new master) in the staging area, vs. a mixed reset that leaves them unstaged. It shouldn't cause this problem (at least not by itself).

When you soft reset, the state of all files is kept as they were. That is, not only are the changes from the PR preserved, but none of the files that have been modified in master are brought up to date with master. When you then commit your staged changes, you are committing your old versions of files that have been modified in master.

Interresting, I've used this a bunch before and never had any issues. The docs are are bit ambiguous though, now that I read the section again ("doesn't touch the index" but "leaves all changed files to be committed"). Guess I'll drop this out of my saved replies for safety reasons if it has the potential to mess things up.

@aminoa
Copy link
Contributor Author

aminoa commented Jan 28, 2023

I removed the accidental changes and re-pushed.

@MayImilae
Copy link
Contributor

Could you update the image in the PR description please?

@aminoa
Copy link
Contributor Author

aminoa commented Jan 31, 2023

Could you update the image in the PR description please?

It's updated

Source/Core/Core/TimePlayed.cpp Outdated Show resolved Hide resolved
Source/Core/Core/TimePlayed.h Outdated Show resolved Hide resolved
Source/Core/DolphinQt/GameList/GameListModel.cpp Outdated Show resolved Hide resolved
Source/Core/Core/HW/CPU.cpp Outdated Show resolved Hide resolved
@AdmiralCurtiss
Copy link
Contributor

I also don't see any handling of the emulator pausing here, so paused time counts as playtime. I suspect that is not desired.

@aminoa
Copy link
Contributor Author

aminoa commented Feb 2, 2023

I also don't see any handling of the emulator pausing here, so paused time counts as playtime. I suspect that is not desired.

It would not count time while in the middle of TASing a game and have the game paused, but maybe an average user expects a paused game to not count time; I'm conflicted on whether to count it or not.

Edit: I decided to not add to the time when emulation is paused.

@Pokechu22
Copy link
Contributor

@BhaaLseN wrote:

I like the idea in general; and we could explore a future extension of this to also work for Wii games and write their playtime to the NAND (so they show up in the Wii menu).

I thought this already worked on master, but it looks like it only properly works if you launch games from the system menu (otherwise you get a 23:59 blank entry). Apparently the system menu needs to do some stuff with play_rec.dat beforehand, and then games will update it. But we aren't currently creating it beforehand, so things break (and presumably we'd also need to update the message board before each start so that things behave properly if multiple games are launched without loading the system menu).

As far as I can tell, the feature added by this PR works correctly for Wii games, though.

Copy link
Member

@JosJuice JosJuice left a comment

Choose a reason for hiding this comment

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

Consider adding an option to disable the tracking. I would be interested in turning it off personally, at least.

Source/Core/Core/HW/CPU.cpp Show resolved Hide resolved
Source/Core/Core/HW/CPU.h Outdated Show resolved Hide resolved
Source/Core/Core/HW/CPU.h Show resolved Hide resolved
@aminoa
Copy link
Contributor Author

aminoa commented Jan 22, 2025

I have addressed the changes requested and made the time tracking optional. Let me know if there's anything else that needs to be done.

@AdmiralCurtiss
Copy link
Contributor

Please squash the commits.

Otherwise, this seems fine enough I guess. One could definitely improve this further (eg. there's a rather large timing inaccuracy around pausing) but it'll probably do the job for now. Completely untested.

Creates TimePlayed class and implemented constructors, AddTime, GetTimePlayed, and Reload methods. Updates CMakeLists.txt and DolphinLib.props as appropriate.
Introduce method to track the time played for a game via time differences and TimePlayed methods. Threads are synchronized via Common::Event.
All metadata access methods now acquire a lock on `m_metadata_lock` to prevent race conditions.
Shows minutes/hours in the list view and handles column visibility.
Copy link
Contributor

@MayImilae MayImilae left a comment

Choose a reason for hiding this comment

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

Gave this a quick try on macOS. First of all, it works on macOS! Tried a few other quick tests too.

  • Does Dolphin record time if time tracking is disabled? Test result: No. (good)
  • Does Dolphin record time if time tracking is enabled but the column removed? Test result: Yes. (good)

That's very very basic testing, but yea, it works!

UX notes, I have mixed feelings about it being enabled by default, but since you added the ability to turn it off, it's fine. It would also be nice if the column updated live while a game was being played, but updating when a game is stopped is acceptable. Also all of the previous UX quibbles I had in this PR are resolved.

So yea, design LGTM. I did not review the code and only performed light testing.

@aminoa aminoa force-pushed the master branch 2 times, most recently from f24c9b7 to 1476a92 Compare January 23, 2025 20:34
@mbc07
Copy link
Member

mbc07 commented Jan 23, 2025

Don't think I'll be able to do a throughout review in time, but when exactly is the play time saved to the user folder? What happens if Dolphin crashes during emulation, is the playtime of that session (until the crash) also gone?

@aminoa
Copy link
Contributor Author

aminoa commented Jan 23, 2025

Don't think I'll be able to do a throughout review in time, but when exactly is the play time saved to the user folder? What happens if Dolphin crashes during emulation, is the playtime of that session (until the crash) also gone?

It's saved every 30 seconds to an ini file so a crash would at most lose 30 seconds too.

Copy link
Member

@mbc07 mbc07 left a comment

Choose a reason for hiding this comment

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

LGTM. Did some basic testing on Windows and reviewed the new user-facing strings. Can't comment about the rest of the code, but from a (very) quick look it seems fine...

Introduce a new "Enable Time Tracking" checkbox in the InterfacePane UI. The checkbox is dynamically enabled or disabled based on the emulation state, preventing changes while emulation is active.
@dolphin-ci
Copy link

dolphin-ci bot commented Jan 24, 2025

FifoCI detected that this change impacts graphical rendering. Here are the behavior differences detected by the system:

  • sw3-dt on ogl-lin-mesa: diff

automated-fifoci-reporter

@Dentomologist
Copy link
Contributor

I'm in the middle of a more complete review but I want to prioritize this point since changing Config names later would break backward compatibility. I'd like to get feedback on this from other people, so don't make these changes until they've had a chance to respond.

The config Display section contains settings affecting how the render window is displayed and behaves, so I don't think it's the right place for the TimeTracking setting. I'd say either General or Interface would be a better fit.

As for the name, I think something like TrackPlayTime or EnablePlayTimeTracking would be clearer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.