This is more reliable, as this guarantees subsystems will be
shut down in the same order they were initialised (if they were
initialised). It also allows us to stop keeping track of what needs to
be shut down manually and just return in case of errors.
This should prevent the emulator from getting totally stuck when
the boot process does fail.
This makes it hard to support different boot params for different boot
types. We should not be making the assumption that Dolphin will
always be booting directly from a file (and in particular, only
using a string).
It's incompatible with future changes that will allow Dolphin to boot
a NAND title properly from well, the NAND, as opposed to booting from
WADs. (And no, treating the title TMD as a "bootable" path doesn't
count. Especially when that approach won't work with NAND images
or IOS LLE.)
And it's confusing to expose this functionality from the UI. It's
pretty bad for UX to change the play button's behaviour depending on
whether the user has launched something before, configured a default
file to boot, added a directory to their game paths.
This commit moves the write function to where it should be (IOS),
especially when ES::ImportTicket() is the only place to use it.
Prevents misusing the ticket import function, and removes one unsafe
direct write to the NAND that does not go through IOS.
This also fixes the destination path: the session root is the one which
should be used for determining the ticket path, not the configured one.
The whole NANDContentLoader stuff is truly awful and will be removed
as soon as possible.
For now, this fixes a bug that was exposed by std::optional::operator*.
std::optional makes a few things a bit neater and less error prone.
However, we still cannot use C++17 (unfortunately), so this commit
adds an implementation of std::optional that we can use right now.
Based on https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/lib/gtl/optional.h
which seems to be fairly similar to C++17's <optional> and standards
compliant. It's one of the few implementations that handle propagating
type traits like copy constructibility, just like libc++/libstdc++.
`MainWindow` initializes a number of input interfaces but never shuts
them down. This was causing a crash-after-exit on macOS where the
ControllerInterface backend stores a `std::thread` object in a static
variable and only stops it when ControllerInterface::Shutdown is called.