- Don't use a class, it doesn't add anything.
- Use constexpr for the individual version numbers
- Use a function to get the revision string, for consistency with the
version string.
As recommended by C++ Core Guidelines C.12.
Plugin and Game are still non-copy-constructable or assignable due to
having members that are non-copy-constructable/assignable, but
consistency is still good.
This follows the advice of C++ Core Guidelines C.161 and C.168.
The File equality and less than comparison operators have not been
moved because File::GetDisplayName() is not a trivial accessor.
- CreateGameHandle() should return a unique_ptr because it transfers
ownership.
- GameInterface::GetDatabase() should return a reference because it
returns an existing object that will always be valid at call time.
- GameInterface::GetPlugin() and GameInterface::GetLoadedPlugins()
return raw pointers because they do not transfer or share ownership.
It's unfortunately that references can't be used instead (ignoring
std::reference_wrapper), as std::optional<const Plugin&> and
std::vector<const Plugin&> would be more meaningful return types.
Internally, there were a few uses of shared_ptr that could be unique_ptr
and a few that could be non-pointer types.
A few uses of shared_ptr remain:
- Game and ApiDatabase share a ConditionEvaluator, so it's kept inside a
shared_ptr. Technically ApiDatabase is used such that the
ConditionEvaluator it uses will always outlive it, but that's not
guaranteed, so shared_ptr is used for safety.
- Plugin objects are cached inside shared_ptr so that the map of
them can be iterated over. Ideally they'd be stored in unique_ptr,
but unique_ptr not being copyable means the map entries can't be
iterated over.