watcher ran a thread per watched directory (the texture pack's, the
graphics mods') so that a texture file changed on disk while a game
ran was loaded again; on Windows its backend throws, so its file was
the one built with exceptions. A texture pack or mod is now read as the
game starts, and a change to it is seen at the next start.
With it go Common::FilesystemWatcher, the library's map from file to
asset kept only to answer the watcher, and the asset cache's dirty
asset queue that only the watcher filled.
Every JSON reader (Triforce card decks, dynamic input textures, graphics
mods and their per-game profiles) now pulls its file through rjson from a
VFS filestream and fills its structures as it parses, with no document
tree in between. JsonUtil and the vendored picojson go away, as does the
graphics mod serialization nothing called.
Move and scale actions take their X, Y and Z straight from the parsed
feature instead of re-reading a kept JSON value. rjson.c and rjson.h are
imported unchanged from libretro-common.
AtomicHashMap.h was a pair of C++ templates. Common/AtomicMap.{h,c}
replaces it with the same structure in C89, keyed by bytes: each key's
node is pushed at its bucket's head with a CAS and stays until the map
is freed.
- atomic_slot_map: one atomic pointer slot per key, for the OGL
pipeline programs (keyed by the PipelineProgramKey bytes) and the
D3D state cache (keyed by each state's hex word).
- atomic_value_map: values that begin with a quiesce_node_t, published
whole and freed once no reader is inside, for the asset library's
id-to-files and path-to-id maps (keyed by the string's bytes).
The OGL program cache's reference count and shader id counter move to
retro_atomic too, and PipelineProgramKeyHash goes with the template
that used it.
Every std::mutex, lock_guard, unique_lock, scoped_lock,
condition_variable, call_once and semaphore left in Source/Core is
replaced by a lock-free design:
- Input: the device list, control bindings, stick calibration and
default device are published snapshots read under a quiesce; a
rebind requested while another thread is rebinding is handed to
that thread instead of waited for.
- WiimoteReal: the pool thread owns the slots and runs commands from
an MPSC queue; the active Wiimotes are atomic slots.
- EXI/SI/IOS devices: socket and packet traffic goes through SPSC
rings or MPSC handoffs owned by one thread; USB scanning publishes
its device list, and libusb transfers drain through a CallGate.
- Memory cards: the flush thread applies change records queued by
the CPU thread.
- Custom assets: loads are scheduled as a published batch with an
atomic cursor, results come back over an MPSC stack, and busy
assets are skipped and retried.
- D3D state and GL program caches use insert-only atomic maps
(Common/AtomicHashMap.h).
- Logging appends with O_APPEND / FILE_APPEND_DATA; FatFs reports
busy instead of waiting; per-socket WSAStartup/WSACleanup.
Deleted as unused by the libretro core: the profiler, the FIFO
recorder, the volume verifier, the touch InputOverrider and the
GameCube adapter's libusb path.
Both fed user-written GLSL to the backends at runtime, which the move to
bytecode emitted straight from the shader generators leaves no compiler
for. The frontend's own shader pipeline covers post-processing.
The presentation pass keeps a plain copy and the built-in correction
shader for output resampling, colour space and gamma correction and HDR
scaling, now compiled in rather than loaded from Sys/Shaders. The
graphics-mod system keeps its draw, EFB, projection and texture actions;
custom pipelines, materials, shader, mesh and sampler assets, the custom
constant buffers in every backend and the two mods built on them are
gone, along with the shader generators' custom-shader hooks.
Yellow squiggly lines begone!
Done automatically on .cpp files through `run-clang-tidy`, with manual corrections to the mistakes.
If an import is directly used, but is technically unnecessary since it's recursively imported by something else, it is *not* removed.
The tool doesn't touch .h files, so I did some of them by hand while fixing errors due to old recursive imports.
Not everything is removed, but the cleanup should be substantial enough.
Because this done on Linux, code that isn't used on it is mostly untouched.
(Hopefully no open PR is depending on these imports...)
In std::string, you can store strings using any encoding, but in Dolphin
we have decided to use UTF-8. The problem is that if you convert between
std::string and std::filesystem::path using the built-in methods, the
standard library will make up its own assumption of what encoding you're
using in the std::string. On most OSes this is UTF-8, but on Windows
it's whatever the user's code page is.
What I believe is the C++ standard authors' intended solution to this is
to use std::u8string instead of std::string, but that's a big hassle to
move over to, because there's no convenient way to convert between
std::string and std::u8string. Instead, in Dolphin, we have added helper
functions that convert between std::string and std::filesystem::path in
the manner we want. You *always* have to use these when converting
between std::string and std::filesystem::path, otherwise we get these
kinds of encoding problems that we've been having with custom textures.
Fixes https://bugs.dolphin-emu.org/issues/13328.