The class NonCopyable is, like the name says, supposed to disallow
copying. But should it allow moving?
For a long time, NonCopyable used to not allow moving. (It declared
a deleted copy constructor and assigment operator without declaring
a move constructor and assignment operator, making the compiler
implicitly delete the move constructor and assignment operator.)
That's fine if the classes that inherit from NonCopyable don't need
to be movable or if writing the move constructor and assignment
operator by hand is fine, but that's not the case for all classes,
as I discovered when I was working on the DirectoryBlob PR.
Because of that, I decided to make NonCopyable movable in c7602cc,
allowing me to use NonCopyable in DirectoryBlob.h. That was however
an unfortunate decision, because some of the classes that inherit
from NonCopyable have incorrect behavior when moved by default-
generated move constructors and assignment operators, and do not
explicitly delete the move constructors and assignment operators,
relying on NonCopyable being non-movable.
So what can we do about this? There are four solutions that I can
think of:
1. Make NonCopyable non-movable and tell DirectoryBlob to suck it.
2. Keep allowing moving NonCopyable, and expect that classes that
don't support moving will delete the move constructor and
assignment operator manually. Not only is this inconsistent
(having classes disallow copying one way and disallow moving
another way), but deleting the move constructor and assignment
operator manually is too easy to forget compared to how tricky
the resulting problems are.
3. Have one "MovableNonCopyable" and one "NonMovableNonCopyable".
It works, but it feels rather silly...
4. Don't have a NonCopyable class at all. Considering that deleting
the copy constructor and assignment operator only takes two lines
of code, I don't see much of a reason to keep NonCopyable. I
suppose that there was more of a point in having NonCopyable back
in the pre-C++11 days, when it wasn't possible to use "= delete".
I decided to go with the fourth one (like the commit title says).
The implementation of the commit is fairly straight-forward, though
I would like to point out that I skipped adding "= delete" lines
for classes whose only reason for being uncopyable is that they
contain uncopyable classes like File::IOFile and std::unique_ptr,
because the compiler makes such classes uncopyable automatically.
I'm not sure why this hasn't popped up as an error on the buildbots,
but the build fails on my new install of VS2017. The error is C2445:
result type of conditional expression is ambiguous: types 'wxString'
and 'const char [1]' can be converted to multiple common types
to get bigger, breaking an optimization. This forces the emitter to use a
32bit pointer instead of an 8bit one, fixing the issue at the expense of
efficiency.
Seems like I was wrong that ANDI2R doesn't require a temporary register here.
There is *one* case when the mask won't fit in the ARM AND instruction:
mask = 0xFFFFFFFF
But let's just use MOV instead of AND here for this case...
Currently, GameFile returns a generic banner if the file didn't have one
available (either because the file format doesn't support it, or because
it's a Wii file without an associated save).
It makes more sense to handle the lack of banner in the UI layer. The
game list will use the generic missing banner explicitly (no change from before), and the game info window now omits the banner display entirely if the file didn't have one (since it's not useful to display/allow the user to save the "missing banner" banner).
Given a relatively recent proposal (P0657R0), which calls for deprecation of putting stuff into the global namespace when using C++ headers, this just futureproofs our code a little more.
Technically this is what we should have been doing initially, since an
implementation is allowed to not provide these types in the global
namespace and still be compliant.
It's strange to see GameTracker add its own initial paths in
construction, because you might expect a race condition where the
GameLoaded signal is emitted before it gets connected to in
GameListModel.
In fact, this doesn't happen, but only because of how it abuses the Qt
signals mechanism to load files asynchronously: GameLoader emits a
GameLoaded signal which gets forwarded to the GameTracker::GameLoaded
signal _after_ control returns to the event loop, at which point
GameListModel has connected.
This commit moves the logic of adding initial paths out of GameTracker
to a point after the signals are connected, which is more obvious and
doesn't rely on how GameTracker implements concurrency.
ifstream::read() sets the failbit if trying to read over the end, which
means that (!input) would be hit for the 'last' block if it wasn't
exactly BSIZE (1024) bytes.
Makes it easier to turn off general IOS messages that can be
distracting (e.g. /dev/net/ssl being opened hundreds of time...)
without losing the ability to view WFS messages.
The opagent library was (incorrectly) marked as a dependency for "Core"
instead of "Common".
When linked with --as-needed, any symbols the linker can tell are not
used are discarded. As the link is done in command-line order, and the
Core library (and dependencies) are processed before Common, it would
link in Core, then opagent, but as at that point no opagent symbols are
used the whole opagent library would be discarded.
Moving the opagent library to be a dependency of Common fixes this, as
after the Common library is linked, there *are* opagent symbols used.
This helpers are not for general CR calculation, they are just for the
common case of the sign extended result of integer instructions if the
rc bit is set.
They must not be used by other instructions like cmp, so there is no
need to be as flexible.
cmpi shall compare two signed 32 bit values. The used difference a-b
may overflow and so the resulting 32 bit value can't represent it.
A correct way would be cr = s64(a) - s64(b) and it should be done in
this way in the JITs, but the Interpreter shall implement the most
readable way.
Also drops the now unused helper function.
The switch statements in these functions appear to get transformed into
an if..else chain on NVIDIA's OpenGL/Vulkan drivers, resulting in lower
performance than the D3D counterparts. Transforming the switch into a
binary tree of ifs can increase performance by up to 20%.
Since we don't want users to have to configure the region manually
and always enforce one automatically, we should fall back to a region
that was likely to be chosen by the user instead of always using
PAL whenever the title region cannot be detected.
Dolphin doesn't mess with installed NAND titles like the system menu,
so it is a reliable indicator of what region the user wants.
"Pad size" just doesn't make much sense. Let's go with "Buffer size"
instead, since the control for it is labeled "Buffer".
(Another possibility is "Pad buffer size", but I'm against that,
because we've stopped referring to controllers as "pads" in almost
all GUI strings.)
* Add missing Language setting loading/saving. This was added after the
original OnionConfig PR, which is why support for it was missing.
* Change MovieConfigLoader to reuse ConfigInfos. Less duplication.
* Extract MovieConfigLoader::Save into SaveToDTM. The DTM should use
the current config and not just the movie layer. This makes more
sense than just saving the movie layer, which may not always exist,
and also fixes a crash that would happen when creating a new
recording because the movie layer wouldn't exist in that case.
(Plus, having to get the loader from the layer and call ChangeDTM
on it manually is not very pretty.)
Not really used anywhere yet, but useful for not having to duplicate
config locations and for getting rid of conflicts when I get around
to rebase my Main.Core and Main.DSP porting PR.
Settings that come from the SYSCONF are now included in Dolphin's
config system as part of the base layer. They are handled in a
special way compared to other settings to make sure they are only
loaded from and saved to the SYSCONF (to avoid different, possibly
contradicting sources of truth).
This could cause the first branch of the bootucode procedure, which
takes its parameters from the AX registers, to run during the ROM init
sequence. Since the ROM doesn't set any of the AX registers, the values
aren't meaningful, and can cause bad DMA transfers and crashes.
This adds a WiiWad constructor that takes a BlobReader, so that the
class can be used with more than just files from the host filesystem.
Required for using WiiWad with WADs from update partitions.