1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-10-04 16:17:17 +02:00

Merge removing Boost Filesystem; resolves #682

This commit is contained in:
tsjost 2021-10-12 21:54:16 +02:00
commit c5e6709643
31 changed files with 139 additions and 182 deletions

View File

@ -28,11 +28,10 @@ matrix:
# - os: osx # - os: osx
# compiler: clang # compiler: clang
# env: NAME="Apple macOS" NAME_SUFFIX="mac" # env: NAME="Apple macOS" NAME_SUFFIX="mac"
# osx_image: xcode10.1 # osx_image: xcode11
# install: # install:
# - brew update # - brew update
# - /usr/bin/yes | pip2 uninstall numpy # see https://github.com/travis-ci/travis-ci/issues/6688 # - /usr/bin/yes | pip2 uninstall numpy # see https://github.com/travis-ci/travis-ci/issues/6688
# - brew upgrade python
# - brew upgrade # - brew upgrade
# - brew install boost cmake bullet ffmpeg glm openal-soft qt5 sdl2 jack freetype # - brew install boost cmake bullet ffmpeg glm openal-soft qt5 sdl2 jack freetype
# - export PATH="/usr/local/opt/qt/bin:$PATH" # - export PATH="/usr/local/opt/qt/bin:$PATH"

View File

@ -33,7 +33,6 @@ function(rwdep_wrap_conan_targets)
endif() endif()
rwdep_wrap_conan_target(Boost::boost boost) rwdep_wrap_conan_target(Boost::boost boost)
rwdep_wrap_conan_target(Boost::filesystem boost)
rwdep_wrap_conan_target(Boost::program_options boost) rwdep_wrap_conan_target(Boost::program_options boost)
rwdep_wrap_conan_target(Boost::system boost) rwdep_wrap_conan_target(Boost::system boost)
rwdep_wrap_conan_target(Boost::unit_test_framework boost) rwdep_wrap_conan_target(Boost::unit_test_framework boost)

View File

@ -115,19 +115,8 @@ if(USE_CONAN)
endif() endif()
endif() endif()
if(FILESYSTEM_LIBRARY STREQUAL "CXX17") if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(CMAKE_CXX_STANDARD 17) target_link_libraries(rw_interface INTERFACE "stdc++fs")
target_compile_definitions(rw_interface INTERFACE "RW_FS_LIBRARY=0")
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
target_link_libraries(rw_interface INTERFACE "stdc++fs")
endif()
elseif(FILESYSTEM_LIBRARY STREQUAL "CXXTS")
target_compile_definitions(rw_interface INTERFACE "RW_FS_LIBRARY=1")
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
target_link_libraries(rw_interface INTERFACE "stdc++fs")
endif()
else()
message(FATAL_ERROR "Illegal FILESYSTEM_LIBRARY option. (was '${FILESYSTEM_LIBRARY}')")
endif() endif()
if(ENABLE_SCRIPT_DEBUG) if(ENABLE_SCRIPT_DEBUG)

View File

@ -12,9 +12,6 @@ option(TEST_DATA "Enable tests that require game data")
set(FAILED_CHECK_ACTION "IGNORE" CACHE STRING "What action to perform on a failed RW_CHECK (in debug mode)") set(FAILED_CHECK_ACTION "IGNORE" CACHE STRING "What action to perform on a failed RW_CHECK (in debug mode)")
set_property(CACHE FAILED_CHECK_ACTION PROPERTY STRINGS "IGNORE" "ABORT" "BREAKPOINT") set_property(CACHE FAILED_CHECK_ACTION PROPERTY STRINGS "IGNORE" "ABORT" "BREAKPOINT")
set(FILESYSTEM_LIBRARY "CXX17" CACHE STRING "Which filesystem library to use")
set_property(CACHE FILESYSTEM_LIBRARY PROPERTY STRINGS "CXX17" "CXXTS")
set(CMAKE_CONFIGURATION_TYPES "Release;Debug;RelWithDebInfo;MinSizeRel" CACHE INTERNAL "Build types supported by this project.") set(CMAKE_CONFIGURATION_TYPES "Release;Debug;RelWithDebInfo;MinSizeRel" CACHE INTERNAL "Build types supported by this project.")
if(NOT CMAKE_BUILD_TYPE) if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: ${CMAKE_CONFIGURATION_TYPES}") set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: ${CMAKE_CONFIGURATION_TYPES}")

View File

@ -14,8 +14,6 @@
{ "include": [ "@<glm/gtx/\\.\\./gtc/quaternion\\.hpp>", "public", "<glm/gtc/quaternion.hpp>", "public"] }, { "include": [ "@<glm/gtx/\\.\\./gtc/quaternion\\.hpp>", "public", "<glm/gtc/quaternion.hpp>", "public"] },
{ "include": [ "@<glm/gtx/\\.\\./gtx/quaternion\\.hpp>", "public", "<glm/gtx/quaternion.hpp>", "public"] }, { "include": [ "@<glm/gtx/\\.\\./gtx/quaternion\\.hpp>", "public", "<glm/gtx/quaternion.hpp>", "public"] },
{ "symbol": [ "glm::value_ptr", "private", "<glm/gtc/type_ptr.hpp>", "public"] }, { "symbol": [ "glm::value_ptr", "private", "<glm/gtc/type_ptr.hpp>", "public"] },
# Boost filesystem:
{ "include": [ "@<boost/filesystem/.*>", "private", "<boost/filesystem.hpp>", "public"] },
# Boost iterator: # Boost iterator:
{ "include": [ "@<boost/range/iterator_range_core\\.hpp>", "private", "<boost/range/iterator_range.hpp>", "public"] }, { "include": [ "@<boost/range/iterator_range_core\\.hpp>", "private", "<boost/range/iterator_range.hpp>", "public"] },
# Bullet: # Bullet:

View File

@ -11,7 +11,6 @@ add_library(rwcore
rw/abort.cpp rw/abort.cpp
rw/casts.hpp rw/casts.hpp
rw/filesystem.hpp
rw/forward.hpp rw/forward.hpp
rw/types.hpp rw/types.hpp
rw/debug.hpp rw/debug.hpp

View File

@ -22,7 +22,7 @@ void to_lowercase_inplace(char* name) {
} }
bool LoaderIMG::load(const rwfs::path& filepath) { bool LoaderIMG::load(const std::filesystem::path& filepath) {
assert(m_archive.empty()); assert(m_archive.empty());
m_archive = filepath; m_archive = filepath;

View File

@ -2,13 +2,12 @@
#define _LIBRW_LOADERIMG_HPP_ #define _LIBRW_LOADERIMG_HPP_
#include <cstddef> #include <cstddef>
#include <filesystem>
#include <string> #include <string>
#include <vector> #include <vector>
#include <memory> #include <memory>
#include <fstream> #include <fstream>
#include <rw/filesystem.hpp>
/// \brief Points to one file within the archive /// \brief Points to one file within the archive
class LoaderIMGFile { class LoaderIMGFile {
public: public:
@ -40,7 +39,7 @@ public:
/// Load the structure of the archive /// Load the structure of the archive
/// Omit the extension in filename so both .dir and .img are loaded when /// Omit the extension in filename so both .dir and .img are loaded when
/// appropriate /// appropriate
bool load(const rwfs::path& filepath); bool load(const std::filesystem::path& filepath);
/// Load a file from the archive to memory and pass a pointer to it /// Load a file from the archive to memory and pass a pointer to it
/// Warning: Returns nullptr if by any reason it can't load the file /// Warning: Returns nullptr if by any reason it can't load the file
@ -72,7 +71,7 @@ public:
private: private:
Version m_version = GTAIIIVC; ///< Version of this IMG archive Version m_version = GTAIIIVC; ///< Version of this IMG archive
rwfs::path m_archive; ///< Path to the archive being used (no extension) std::filesystem::path m_archive; ///< Path to the archive being used (no extension)
std::ifstream m_archive_stream; ///< File stream for archive std::ifstream m_archive_stream; ///< File stream for archive
std::vector<LoaderIMGFile> m_assets; ///< Asset info of the archive std::vector<LoaderIMGFile> m_assets; ///< Asset info of the archive

View File

@ -6,7 +6,7 @@
#include "rw/debug.hpp" #include "rw/debug.hpp"
bool LoaderSDT::load(const rwfs::path& sdtPath, const rwfs::path& rawPath) { bool LoaderSDT::load(const std::filesystem::path& sdtPath, const std::filesystem::path& rawPath) {
const auto sdtName = sdtPath.string(); const auto sdtName = sdtPath.string();
const auto rawName = rawPath.string(); const auto rawName = rawPath.string();

View File

@ -1,10 +1,9 @@
#ifndef _LIBRW_LOADERSDT_HPP_ #ifndef _LIBRW_LOADERSDT_HPP_
#define _LIBRW_LOADERSDT_HPP_ #define _LIBRW_LOADERSDT_HPP_
#include <rw/filesystem.hpp>
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <filesystem>
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
@ -62,7 +61,7 @@ public:
~LoaderSDT() = default; ~LoaderSDT() = default;
/// Load the structure of the archive /// Load the structure of the archive
bool load(const rwfs::path& sdtPath, const rwfs::path& rawPath); bool load(const std::filesystem::path& sdtPath, const std::filesystem::path& rawPath);
/// Load a file from the archive to memory and pass a pointer to it /// Load a file from the archive to memory and pass a pointer to it
/// Warning: Returns nullptr if by any reason it can't load the file /// Warning: Returns nullptr if by any reason it can't load the file

View File

@ -19,14 +19,14 @@ std::string FileIndex::normalizeFilePath(const std::string &filePath) {
return oss.str(); return oss.str();
} }
void FileIndex::indexTree(const rwfs::path &path) { void FileIndex::indexTree(const std::filesystem::path &path) {
// Remove the trailing "/" or "/." from base_path. Boost 1.66 and c++17 have different lexically_relative behavior. // Remove the trailing "/" or "/." from base_path. Boost 1.66 and c++17 have different lexically_relative behavior.
rwfs::path basePath = (path / ".").lexically_normal(); std::filesystem::path basePath = (path / ".").lexically_normal();
basePath = basePath.parent_path(); basePath = basePath.parent_path();
for (const rwfs::path &path : for (const std::filesystem::path &path :
rwfs::recursive_directory_iterator(basePath)) { std::filesystem::recursive_directory_iterator(basePath)) {
if (!rwfs::is_regular_file(path)) { if (!std::filesystem::is_regular_file(path)) {
continue; continue;
} }
auto relPath = path.lexically_relative(basePath); auto relPath = path.lexically_relative(basePath);
@ -43,7 +43,7 @@ const FileIndex::IndexedData *FileIndex::getIndexedDataAt(const std::string &fil
return &indexedData_.at(normPath); return &indexedData_.at(normPath);
} }
rwfs::path FileIndex::findFilePath(const std::string &filePath) const { std::filesystem::path FileIndex::findFilePath(const std::string &filePath) const {
return getIndexedDataAt(filePath)->path; return getIndexedDataAt(filePath)->path;
} }
@ -70,7 +70,7 @@ FileContentsInfo FileIndex::openFileRaw(const std::string &filePath) const {
} }
void FileIndex::indexArchive(const std::string &archive) { void FileIndex::indexArchive(const std::string &archive) {
rwfs::path path = findFilePath(archive); std::filesystem::path path = findFilePath(archive);
LoaderIMG& img = loaders_[path.string()]; LoaderIMG& img = loaders_[path.string()];
if (!img.load(path.string())) { if (!img.load(path.string())) {
@ -109,7 +109,7 @@ FileContentsInfo FileIndex::openFile(const std::string &filePath) {
auto& loader = loaderPos->second; auto& loader = loaderPos->second;
LoaderIMGFile file; LoaderIMGFile file;
auto filename = rwfs::path(indexedData.assetData).filename().string(); auto filename = std::filesystem::path(indexedData.assetData).filename().string();
if (loader.findAssetInfo(filename, file)) { if (loader.findAssetInfo(filename, file)) {
length = file.size * 2048; length = file.size * 2048;
data = loader.loadToMemory(filename); data = loader.loadToMemory(filename);

View File

@ -1,11 +1,11 @@
#ifndef _LIBRW_FILEINDEX_HPP_ #ifndef _LIBRW_FILEINDEX_HPP_
#define _LIBRW_FILEINDEX_HPP_ #define _LIBRW_FILEINDEX_HPP_
#include <filesystem>
#include <unordered_map> #include <unordered_map>
#include <memory> #include <memory>
#include <loaders/LoaderIMG.hpp> #include <loaders/LoaderIMG.hpp>
#include <rw/filesystem.hpp>
#include <rw/forward.hpp> #include <rw/forward.hpp>
@ -25,7 +25,7 @@ public:
* This is used to build the mapping of lower-case file paths to the * This is used to build the mapping of lower-case file paths to the
* true case on the file system for platforms where this is an issue. * true case on the file system for platforms where this is an issue.
*/ */
void indexTree(const rwfs::path &path); void indexTree(const std::filesystem::path &path);
/** /**
* @brief findFilePath finds disk path for a game data file * @brief findFilePath finds disk path for a game data file
@ -33,7 +33,7 @@ public:
* @return The file path as it exists on disk * @return The file path as it exists on disk
* @throws if this FileIndex has not indexed the path * @throws if this FileIndex has not indexed the path
*/ */
rwfs::path findFilePath(const std::string &filePath) const; std::filesystem::path findFilePath(const std::string &filePath) const;
/** /**
* @brief openFileRaw Opens a raw file on the disk * @brief openFileRaw Opens a raw file on the disk

View File

@ -1,34 +0,0 @@
#ifndef _LIBRW_FILESYSTEM_HPP_
#define _LIBRW_FILESYSTEM_HPP_
#define RW_FS_CXX17 0
#define RW_FS_CXXTS 1
#if RW_FS_LIBRARY == RW_FS_CXX17
#include <filesystem>
#include <system_error>
namespace rwfs {
using namespace std::filesystem;
using error_code = std::error_code;
}
#elif RW_FS_LIBRARY == RW_FS_CXXTS
#include <experimental/filesystem>
#include <system_error>
namespace rwfs {
using namespace std::experimental::filesystem;
using error_code = std::error_code;
}
#else
#error Invalid RW_FS_LIBRARY value
#endif
namespace std {
template <>
struct hash<rwfs::path> {
size_t operator()(const rwfs::path& p) const {
return rwfs::hash_value(p);
}
};
}
#endif

View File

@ -7,7 +7,6 @@
#include <glm/vec3.hpp> #include <glm/vec3.hpp>
#include <rw/filesystem.hpp>
#include <loaders/LoaderSDT.hpp> #include <loaders/LoaderSDT.hpp>
#include <string> #include <string>

View File

@ -34,7 +34,7 @@ bool SoundSource::allocateAudioFrame() {
return true; return true;
} }
bool SoundSource::allocateFormatContext(const rwfs::path& filePath) { bool SoundSource::allocateFormatContext(const std::filesystem::path& filePath) {
formatContext = nullptr; formatContext = nullptr;
if (avformat_open_input(&formatContext, filePath.string().c_str(), nullptr, if (avformat_open_input(&formatContext, filePath.string().c_str(), nullptr,
nullptr) != 0) { nullptr) != 0) {
@ -100,7 +100,7 @@ bool SoundSource::prepareFormatContextSfx(LoaderSDT& sdt, size_t index,
return true; return true;
} }
bool SoundSource::findAudioStream(const rwfs::path& filePath) { bool SoundSource::findAudioStream(const std::filesystem::path& filePath) {
RW_UNUSED(filePath); // it's used by macro RW_UNUSED(filePath); // it's used by macro
if (avformat_find_stream_info(formatContext, nullptr) < 0) { if (avformat_find_stream_info(formatContext, nullptr) < 0) {
@ -354,7 +354,7 @@ void SoundSource::decodeFrames(size_t framesToDecode) {
} }
} }
void SoundSource::decodeFramesWrap(const rwfs::path& filePath) { void SoundSource::decodeFramesWrap(const std::filesystem::path& filePath) {
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 37, 100) #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 37, 100)
decodeFramesLegacy(kNrFramesToPreload); decodeFramesLegacy(kNrFramesToPreload);
#else #else
@ -362,7 +362,7 @@ void SoundSource::decodeFramesWrap(const rwfs::path& filePath) {
#endif #endif
} }
void SoundSource::decodeAndResampleFrames(const rwfs::path& filePath, void SoundSource::decodeAndResampleFrames(const std::filesystem::path& filePath,
size_t framesToDecode) { size_t framesToDecode) {
RW_UNUSED(filePath); // it's used by macro RW_UNUSED(filePath); // it's used by macro
AVFrame* resampled = av_frame_alloc(); AVFrame* resampled = av_frame_alloc();
@ -485,7 +485,7 @@ void SoundSource::exposeSfxMetadata(LoaderSDT& sdt) {
sampleRate = sdt.assetInfo.sampleRate; sampleRate = sdt.assetInfo.sampleRate;
} }
void SoundSource::decodeRestSoundFramesAndCleanup(const rwfs::path& filePath) { void SoundSource::decodeRestSoundFramesAndCleanup(const std::filesystem::path& filePath) {
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 37, 100) #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 37, 100)
decodeFramesLegacy(0); decodeFramesLegacy(0);
#else #else
@ -505,7 +505,7 @@ void SoundSource::decodeRestSfxFramesAndCleanup() {
cleanupAfterSfxLoading(); cleanupAfterSfxLoading();
} }
void SoundSource::loadFromFile(const rwfs::path& filePath, bool streaming) { void SoundSource::loadFromFile(const std::filesystem::path& filePath, bool streaming) {
if (allocateAudioFrame() && allocateFormatContext(filePath) && if (allocateAudioFrame() && allocateFormatContext(filePath) &&
findAudioStream(filePath) && prepareCodecContextWrap()) { findAudioStream(filePath) && prepareCodecContextWrap()) {
exposeSoundMetadata(); exposeSoundMetadata();

View File

@ -1,14 +1,13 @@
#ifndef _RWENGINE_SOUND_SOURCE_HPP_ #ifndef _RWENGINE_SOUND_SOURCE_HPP_
#define _RWENGINE_SOUND_SOURCE_HPP_ #define _RWENGINE_SOUND_SOURCE_HPP_
#include <rw/filesystem.hpp>
extern "C" { extern "C" {
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
#include <libavutil/avutil.h> #include <libavutil/avutil.h>
} }
#include <cstdint> #include <cstdint>
#include <filesystem>
#include <future> #include <future>
#include <mutex> #include <mutex>
#include <vector> #include <vector>
@ -25,8 +24,6 @@ class AVStream;
class AVIOContext; class AVIOContext;
class LoaderSDT; class LoaderSDT;
class LoaderSDT;
/// Opaque for raw sound, /// Opaque for raw sound,
/// cooperate with ffmpeg /// cooperate with ffmpeg
/// (loading and decoding sound) /// (loading and decoding sound)
@ -38,10 +35,10 @@ class SoundSource {
public: public:
bool allocateAudioFrame(); bool allocateAudioFrame();
bool allocateFormatContext(const rwfs::path& filePath); bool allocateFormatContext(const std::filesystem::path& filePath);
bool prepareFormatContextSfx(LoaderSDT& sdt, size_t index, bool asWave); bool prepareFormatContextSfx(LoaderSDT& sdt, size_t index, bool asWave);
bool findAudioStream(const rwfs::path& filePath); bool findAudioStream(const std::filesystem::path& filePath);
bool findAudioStreamSfx(); bool findAudioStreamSfx();
bool prepareCodecContextWrap(); bool prepareCodecContextWrap();
@ -59,10 +56,10 @@ public:
void decodeFramesLegacy(size_t framesToDecode); void decodeFramesLegacy(size_t framesToDecode);
#endif #endif
void decodeFramesWrap(const rwfs::path& filePath); void decodeFramesWrap(const std::filesystem::path& filePath);
void decodeFramesSfxWrap(); void decodeFramesSfxWrap();
void decodeFrames(size_t framesToDecode); void decodeFrames(size_t framesToDecode);
void decodeAndResampleFrames(const rwfs::path& filePath, void decodeAndResampleFrames(const std::filesystem::path& filePath,
size_t framesToDecode); size_t framesToDecode);
void cleanupAfterSoundLoading(); void cleanupAfterSoundLoading();
@ -71,11 +68,11 @@ public:
void exposeSoundMetadata(); void exposeSoundMetadata();
void exposeSfxMetadata(LoaderSDT& sdt); void exposeSfxMetadata(LoaderSDT& sdt);
void decodeRestSoundFramesAndCleanup(const rwfs::path& filePath); void decodeRestSoundFramesAndCleanup(const std::filesystem::path& filePath);
void decodeRestSfxFramesAndCleanup(); void decodeRestSfxFramesAndCleanup();
/// Load sound from mp3/wav file /// Load sound from mp3/wav file
void loadFromFile(const rwfs::path& filePath, bool streaming = false); void loadFromFile(const std::filesystem::path& filePath, bool streaming = false);
/// Load sound from sdt file /// Load sound from sdt file
void loadSfx(LoaderSDT& sdt, std::size_t index, bool asWave = true, void loadSfx(LoaderSDT& sdt, std::size_t index, bool asWave = true,

View File

@ -33,7 +33,7 @@
#include "loaders/LoaderGXT.hpp" #include "loaders/LoaderGXT.hpp"
#include "platform/FileIndex.hpp" #include "platform/FileIndex.hpp"
GameData::GameData(Logger* log, const rwfs::path& path) GameData::GameData(Logger* log, const std::filesystem::path& path)
: datpath(path), logger(log) { : datpath(path), logger(log) {
dffLoader.setTextureLookupCallback( dffLoader.setTextureLookupCallback(
[&](const std::string& texture, const std::string&) { [&](const std::string& texture, const std::string&) {
@ -766,8 +766,8 @@ float GameData::getWaveHeightAt(const glm::vec3& ws) const {
} }
bool GameData::isValidGameDirectory() const { bool GameData::isValidGameDirectory() const {
rwfs::error_code ec; std::error_code ec;
if (!rwfs::is_directory(datpath, ec)) { if (!std::filesystem::is_directory(datpath, ec)) {
return false; return false;
} }

View File

@ -43,7 +43,7 @@ class SCMFile;
*/ */
class GameData { class GameData {
private: private:
rwfs::path datpath; std::filesystem::path datpath;
std::string splash; std::string splash;
std::string currenttextureslot; std::string currenttextureslot;
@ -55,7 +55,7 @@ public:
* ctor * ctor
* @param path Path to the root of the game data. * @param path Path to the root of the game data.
*/ */
GameData(Logger* log, const rwfs::path& path); GameData(Logger* log, const std::filesystem::path& path);
~GameData() = default; ~GameData() = default;
GameWorld* engine = nullptr; GameWorld* engine = nullptr;
@ -70,7 +70,7 @@ public:
/** /**
* Returns the game data path * Returns the game data path
*/ */
const rwfs::path& getDataPath() const { const std::filesystem::path& getDataPath() const {
return datpath; return datpath;
} }

View File

@ -4,11 +4,9 @@
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
#include <filesystem>
#include <iostream> #include <iostream>
#include <rw/filesystem.hpp>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp> #include <glm/gtc/quaternion.hpp>
@ -1359,13 +1357,13 @@ std::vector<SaveGameInfo> SaveGame::getAllSaveGameInfo() {
} }
const char gameDir[] = "GTA3 User Files"; const char gameDir[] = "GTA3 User Files";
rwfs::path gamePath(homedir); std::filesystem::path gamePath(homedir);
gamePath /= gameDir; gamePath /= gameDir;
if (!rwfs::exists(gamePath) || !rwfs::is_directory(gamePath)) return {}; if (!std::filesystem::exists(gamePath) || !std::filesystem::is_directory(gamePath)) return {};
std::vector<SaveGameInfo> infos; std::vector<SaveGameInfo> infos;
for (const rwfs::path& save_path : rwfs::directory_iterator(gamePath)) { for (const std::filesystem::path& save_path : std::filesystem::directory_iterator(gamePath)) {
if (save_path.extension() == ".b") { if (save_path.extension() == ".b") {
infos.emplace_back( infos.emplace_back(
SaveGameInfo{save_path.string(), false, BasicState()}); SaveGameInfo{save_path.string(), false, BasicState()});

View File

@ -37,7 +37,7 @@ RWConfig GameBase::buildConfig(const std::optional<RWArgConfigLayer> &args) {
auto defaultLayer = buildDefaultConfigLayer(); auto defaultLayer = buildDefaultConfigLayer();
config.setLayer(RWConfig::LAYER_DEFAULT, defaultLayer); config.setLayer(RWConfig::LAYER_DEFAULT, defaultLayer);
rwfs::path configPath; std::filesystem::path configPath;
if (args.has_value() && args->configPath.has_value()) { if (args.has_value() && args->configPath.has_value()) {
configPath = *args->configPath; configPath = *args->configPath;
} else { } else {

View File

@ -174,22 +174,22 @@ RWConfigLayer buildDefaultConfigLayer() {
static constexpr auto kConfigDirectoryName = "OpenRW"; static constexpr auto kConfigDirectoryName = "OpenRW";
rwfs::path RWConfigParser::getDefaultConfigPath() { std::filesystem::path RWConfigParser::getDefaultConfigPath() {
#if defined(RW_LINUX) || defined(RW_FREEBSD) || defined(RW_NETBSD) || \ #if defined(RW_LINUX) || defined(RW_FREEBSD) || defined(RW_NETBSD) || \
defined(RW_OPENBSD) defined(RW_OPENBSD)
char *config_home = getenv("XDG_CONFIG_HOME"); char *config_home = getenv("XDG_CONFIG_HOME");
if (config_home != nullptr) { if (config_home != nullptr) {
return rwfs::path(config_home) / kConfigDirectoryName; return std::filesystem::path(config_home) / kConfigDirectoryName;
} }
char *home = getenv("HOME"); char *home = getenv("HOME");
if (home != nullptr) { if (home != nullptr) {
return rwfs::path(home) / ".config/" / kConfigDirectoryName; return std::filesystem::path(home) / ".config/" / kConfigDirectoryName;
} }
#elif defined(RW_OSX) #elif defined(RW_OSX)
char *home = getenv("HOME"); char *home = getenv("HOME");
if (home) if (home)
return rwfs::path(home) / "Library/Preferences/" / kConfigDirectoryName; return std::filesystem::path(home) / "Library/Preferences/" / kConfigDirectoryName;
#elif defined(RW_WINDOWS) #elif defined(RW_WINDOWS)
wchar_t *widePath; wchar_t *widePath;
@ -197,15 +197,15 @@ rwfs::path RWConfigParser::getDefaultConfigPath() {
nullptr, &widePath); nullptr, &widePath);
if (SUCCEEDED(res)) { if (SUCCEEDED(res)) {
auto utf8Path = wideStringToACP(widePath); auto utf8Path = wideStringToACP(widePath);
return rwfs::path(utf8Path) / kConfigDirectoryName; return std::filesystem::path(utf8Path) / kConfigDirectoryName;
} }
#else #else
return rwfs::path(); return std::filesystem::path();
#endif #endif
// Well now we're stuck. // Well now we're stuck.
RW_ERROR("No default config path found."); RW_ERROR("No default config path found.");
return rwfs::path(); return std::filesystem::path();
} }
namespace { namespace {
@ -406,7 +406,7 @@ TreeParser buildTreeParser() {
} }
std::tuple<RWConfigLayer, RWConfigParser::ParseResult> RWConfigParser::loadFile(const rwfs::path &path) const { std::tuple<RWConfigLayer, RWConfigParser::ParseResult> RWConfigParser::loadFile(const std::filesystem::path &path) const {
ParseResult parseResult(path.string(), "<internal>"); ParseResult parseResult(path.string(), "<internal>");
auto treeParser = buildTreeParser(); auto treeParser = buildTreeParser();
@ -429,7 +429,8 @@ std::tuple<RWConfigLayer, RWConfigParser::ParseResult> RWConfigParser::loadFile(
return std::make_tuple(layer, parseResult); return std::make_tuple(layer, parseResult);
} }
RWConfigParser::ParseResult RWConfigParser::saveFile(const rwfs::path &path, const RWConfigLayer &layer, const std::map<std::string, std::string> &extra) const { RWConfigParser::ParseResult RWConfigParser::saveFile(const std::filesystem::path &path,
const RWConfigLayer &layer, const std::map<std::string, std::string> &extra) const {
ParseResult parseResult("<internal>", path.string()); ParseResult parseResult("<internal>", path.string());
auto treeParser = buildTreeParser(); auto treeParser = buildTreeParser();
@ -454,7 +455,7 @@ RWConfigParser::ParseResult RWConfigParser::saveFile(const rwfs::path &path, con
return parseResult; return parseResult;
} }
RWConfigParser::ParseResult RWConfigParser::saveFile(const rwfs::path &path, const RWConfigLayer &layer) const { RWConfigParser::ParseResult RWConfigParser::saveFile(const std::filesystem::path &path, const RWConfigLayer &layer) const {
ParseResult parseResult("<internal>", path.string()); ParseResult parseResult("<internal>", path.string());
auto treeParser = buildTreeParser(); auto treeParser = buildTreeParser();

View File

@ -1,11 +1,10 @@
#ifndef RWGAME_RWCONFIG_HPP #ifndef RWGAME_RWCONFIG_HPP
#define RWGAME_RWCONFIG_HPP #define RWGAME_RWCONFIG_HPP
#include <rw/filesystem.hpp>
#include <boost/program_options.hpp> #include <boost/program_options.hpp>
#include <array> #include <array>
#include <filesystem>
#include <iosfwd> #include <iosfwd>
#include <map> #include <map>
#include <optional> #include <optional>
@ -243,13 +242,14 @@ public:
*/ */
RWConfigParser() = default; RWConfigParser() = default;
static rwfs::path getDefaultConfigPath(); static std::filesystem::path getDefaultConfigPath();
std::tuple<RWConfigLayer, RWConfigParser::ParseResult> loadFile(const rwfs::path &path) const; std::tuple<RWConfigLayer, RWConfigParser::ParseResult> loadFile(const std::filesystem::path &path) const;
ParseResult saveFile(const rwfs::path &path, const RWConfigLayer &layer) const; ParseResult saveFile(const std::filesystem::path &path, const RWConfigLayer &layer) const;
ParseResult saveFile(const rwfs::path &path, const RWConfigLayer &layer, const std::map<std::string, std::string> &extra) const; ParseResult saveFile(const std::filesystem::path &path, const RWConfigLayer &layer,
const std::map<std::string, std::string> &extra) const;
/** /**
* @brief layer_to_string Convert the layer to a INI string string * @brief layer_to_string Convert the layer to a INI string string

View File

@ -98,7 +98,7 @@ RWGame::RWGame(Logger& log, const std::optional<RWArgConfigLayer> &args)
btIDebugDraw::DBG_DrawConstraintLimits); btIDebugDraw::DBG_DrawConstraintLimits);
debug.setShaderProgram(renderer.worldProg.get()); debug.setShaderProgram(renderer.worldProg.get());
data.loadDynamicObjects((rwfs::path{config.gamedataPath()} / "data/object.dat") data.loadDynamicObjects((std::filesystem::path{config.gamedataPath()} / "data/object.dat")
.string()); // FIXME: use path .string()); // FIXME: use path
data.loadGXT("text/" + config.gameLanguage() + ".gxt"); data.loadGXT("text/" + config.gameLanguage() + ".gxt");

View File

@ -1,6 +1,5 @@
#include <fonts/FontMapGta3.hpp> #include <fonts/FontMapGta3.hpp>
#include <fonts/Unicode.hpp> #include <fonts/Unicode.hpp>
#include <rw/filesystem.hpp>
#include <ft2build.h> #include <ft2build.h>
#include FT_FREETYPE_H #include FT_FREETYPE_H
@ -12,6 +11,7 @@
#include <cstdint> #include <cstdint>
#include <cstdlib> #include <cstdlib>
#include <filesystem>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <string> #include <string>
@ -182,7 +182,7 @@ public:
} }
} }
void write(const rwfs::path &bitmap_path, const rwfs::path &advance_path) { void write(const std::filesystem::path &bitmap_path, const std::filesystem::path &advance_path) {
QImageWriter writer(QString::fromStdString(bitmap_path.string())); QImageWriter writer(QString::fromStdString(bitmap_path.string()));
writer.write(m_texture); writer.write(m_texture);
std::ofstream ofs(advance_path.string(), std::ios_base::out); std::ofstream ofs(advance_path.string(), std::ios_base::out);
@ -219,8 +219,8 @@ int main(int argc, const char *argv[])
("ratio,r", po::value<float>()->value_name("ASPECTRATIO"), "Aspect ratio") ("ratio,r", po::value<float>()->value_name("ASPECTRATIO"), "Aspect ratio")
("map,m", po::value<unsigned>()->value_name("MAP")->required(), "Font map to use") ("map,m", po::value<unsigned>()->value_name("MAP")->required(), "Font map to use")
("font,f", po::value<std::vector<std::string>>()->value_name("PATH")->required(), "Path to fonts") ("font,f", po::value<std::vector<std::string>>()->value_name("PATH")->required(), "Path to fonts")
("texture,t", po::value<rwfs::path>()->value_name("PATH")->required(), "Output texture") ("texture,t", po::value<std::filesystem::path>()->value_name("PATH")->required(), "Output texture")
("advance,a", po::value<rwfs::path>()->value_name("PATH")->required(), "Output advances") ("advance,a", po::value<std::filesystem::path>()->value_name("PATH")->required(), "Output advances")
; ;
po::variables_map vm; po::variables_map vm;
@ -267,6 +267,6 @@ int main(int argc, const char *argv[])
texBuffer.create_font_map(fontmaps_gta3_font[fontmap_index], FontTextureBuffer::RenderMode::NORMAL); texBuffer.create_font_map(fontmaps_gta3_font[fontmap_index], FontTextureBuffer::RenderMode::NORMAL);
texBuffer.write(vm["texture"].as<rwfs::path>(), vm["advance"].as<rwfs::path>()); texBuffer.write(vm["texture"].as<std::filesystem::path>(), vm["advance"].as<std::filesystem::path>());
return 0; return 0;
} }

View File

@ -1,14 +1,13 @@
#include "TextViewer.hpp" #include "TextViewer.hpp"
#include <render/TextRenderer.hpp> #include <render/TextRenderer.hpp>
#include <rw/filesystem.hpp>
#include <algorithm> #include <algorithm>
#include <cctype> #include <cctype>
#include <filesystem>
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
#include <boost/filesystem.hpp>
#include <fonts/GameTexts.hpp> #include <fonts/GameTexts.hpp>
#include <loaders/LoaderGXT.hpp> #include <loaders/LoaderGXT.hpp>
#include <models/TextModel.hpp> #include <models/TextModel.hpp>
@ -221,10 +220,10 @@ void TextViewer::worldChanged() {
} }
std::vector<std::string> TextViewer::getFontTextureNames() { std::vector<std::string> TextViewer::getFontTextureNames() {
const auto &gameDataPath = rwfs::path(world()->data->getDataPath()); const auto &gameDataPath = std::filesystem::path(world()->data->getDataPath());
rwfs::path textPath; std::filesystem::path textPath;
for (const rwfs::path &p : rwfs::directory_iterator(gameDataPath)) { for (const std::filesystem::path &p : std::filesystem::directory_iterator(gameDataPath)) {
if (!rwfs::is_directory(p)) { if (!std::filesystem::is_directory(p)) {
continue; continue;
} }
std::string filename = p.filename().string(); std::string filename = p.filename().string();
@ -238,7 +237,7 @@ std::vector<std::string> TextViewer::getFontTextureNames() {
throw std::runtime_error("text directory not found in gamedata path"); throw std::runtime_error("text directory not found in gamedata path");
} }
std::vector<std::string> names; std::vector<std::string> names;
for (const rwfs::path &p : rwfs::directory_iterator(textPath)) { for (const std::filesystem::path &p : std::filesystem::directory_iterator(textPath)) {
// auto langName = p.lexically_relative(gameDataPath).string(); // auto langName = p.lexically_relative(gameDataPath).string();
auto langName = p.filename().string(); auto langName = p.filename().string();
std::transform(langName.begin(), langName.end(), langName.begin(), ::tolower); std::transform(langName.begin(), langName.end(), langName.begin(), ::tolower);

View File

@ -4,10 +4,10 @@
#include "ViewerInterface.hpp" #include "ViewerInterface.hpp"
#include <fonts/GameTexts.hpp> #include <fonts/GameTexts.hpp>
#include <rw/filesystem.hpp>
#include <QTableView> #include <QTableView>
#include <filesystem>
#include <vector> #include <vector>
class TextModel; class TextModel;

View File

@ -5,9 +5,9 @@ RUN apt-get update \
build-essential \ build-essential \
cmake \ cmake \
ninja-build \ ninja-build \
gcc-7 \ gcc-8 \
g++-7 \ g++-8 \
clang-6.0 \ clang-7 \
llvm \ llvm \
lcov \ lcov \
curl \ curl \
@ -66,9 +66,9 @@ RUN apt-get update \
libxinerama-dev \ libxinerama-dev \
libxkbcommon-dev \ libxkbcommon-dev \
&& apt-get clean \ && apt-get clean \
&& update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 60 \ && update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 60 \
&& update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 60 \ && update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 60 \
&& update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-7 60 && update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-8 60
# RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 50 --slave /usr/bin/g++ g++ /usr/bin/g++-8 # RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 50 --slave /usr/bin/g++ g++ /usr/bin/g++-8

View File

@ -15,8 +15,8 @@ RUN apt-get update \
curl \ curl \
libavcodec-dev \ libavcodec-dev \
libavformat-dev \ libavformat-dev \
libboost-filesystem-dev \
libboost-program-options-dev \ libboost-program-options-dev \
libboost-system-dev \
libbullet-dev \ libbullet-dev \
libglm-dev \ libglm-dev \
libopenal-dev \ libopenal-dev \

View File

@ -5,19 +5,19 @@
#include <boost/property_tree/ini_parser.hpp> #include <boost/property_tree/ini_parser.hpp>
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
#include <filesystem>
#include <fstream> #include <fstream>
#include <map> #include <map>
#include <chrono> #include <random>
#include <rw/debug.hpp> #include <rw/debug.hpp>
#include <rw/filesystem.hpp>
namespace pt = boost::property_tree; namespace pt = boost::property_tree;
typedef std::map<std::string, std::map<std::string, std::string>> typedef std::map<std::string, std::map<std::string, std::string>>
simpleConfig_t; simpleConfig_t;
simpleConfig_t readConfig(const rwfs::path &path) { simpleConfig_t readConfig(const std::filesystem::path &path) {
simpleConfig_t cfg; simpleConfig_t cfg;
pt::ptree tree; pt::ptree tree;
pt::read_ini(path.string(), tree); pt::read_ini(path.string(), tree);
@ -68,9 +68,9 @@ public:
virtual ~Temp() { virtual ~Temp() {
} }
bool exists() const { bool exists() const {
return rwfs::exists(this->m_path); return std::filesystem::exists(this->m_path);
} }
const rwfs::path &path() const { const std::filesystem::path &path() const {
return this->m_path; return this->m_path;
} }
std::string filename() const { std::string filename() const {
@ -88,18 +88,35 @@ protected:
Temp(const Temp &) = delete; Temp(const Temp &) = delete;
Temp() : m_path(getRandomFilePath()) { Temp() : m_path(getRandomFilePath()) {
} }
Temp(const rwfs::path &dirname) : m_path(getRandomFilePath(dirname)) { Temp(const std::filesystem::path &dirname) : m_path(getRandomFilePath(dirname)) {
} }
private: private:
static rwfs::path getRandomFilePath(const rwfs::path &dirname) { static std::default_random_engine& getRandomEngine() {
const long current_time = std::chrono::high_resolution_clock::now().time_since_epoch().count(); static std::default_random_engine defaultRandomEngine = std::default_random_engine(std::random_device{}());
return dirname / ("openrw_test_" + std::to_string(current_time)); return defaultRandomEngine;
} }
static rwfs::path getRandomFilePath() { static std::string gen_random(size_t len) {
return getRandomFilePath(rwfs::temp_directory_path()); constexpr std::string_view alphanum =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
std::uniform_int_distribution<size_t> dist(0u, alphanum.size());
std::string res;
res.reserve(len);
std::generate_n(std::back_inserter(res), len, [&]() {
return alphanum[dist(getRandomEngine())];
});
return res;
} }
rwfs::path m_path; static std::filesystem::path getRandomFilePath(const std::filesystem::path &dirname) {
const std::string name = "openrw_test_" + gen_random(16);
return dirname / name;
}
static std::filesystem::path getRandomFilePath() {
return getRandomFilePath(std::filesystem::temp_directory_path());
}
std::filesystem::path m_path;
}; };
class TempFile; class TempFile;
@ -114,24 +131,24 @@ public:
this->remove(); this->remove();
} }
virtual void change_perms_normal() const override { virtual void change_perms_normal() const override {
rwfs::permissions(this->path(), std::filesystem::permissions(this->path(),
rwfs::perms::owner_read | rwfs::perms::owner_write | rwfs::perms::owner_exec | std::filesystem::perms::owner_read | std::filesystem::perms::owner_write | std::filesystem::perms::owner_exec |
rwfs::perms::group_read | rwfs::perms::group_exec | std::filesystem::perms::group_read | std::filesystem::perms::group_exec |
rwfs::perms::others_read | rwfs::perms::others_exec); std::filesystem::perms::others_read | std::filesystem::perms::others_exec);
} }
virtual void change_perms_readonly() const override { virtual void change_perms_readonly() const override {
rwfs::permissions(this->path(), std::filesystem::permissions(this->path(),
rwfs::perms::owner_read | rwfs::perms::owner_exec | std::filesystem::perms::owner_read | std::filesystem::perms::owner_exec |
rwfs::perms::group_read | rwfs::perms::group_exec | std::filesystem::perms::group_read | std::filesystem::perms::group_exec |
rwfs::perms::others_read | rwfs::perms::others_exec); std::filesystem::perms::others_read | std::filesystem::perms::others_exec);
} }
virtual void remove() const override { virtual void remove() const override {
// Remove may fail if this directory contains a read-only entry. Ignore. // Remove may fail if this directory contains a read-only entry. Ignore.
rwfs::error_code ec; std::error_code ec;
rwfs::remove_all(this->path(), ec); std::filesystem::remove_all(this->path(), ec);
} }
void touch() const override { void touch() const override {
rwfs::create_directories(this->path()); std::filesystem::create_directories(this->path());
} }
friend class TempFile; friend class TempFile;
}; };
@ -146,19 +163,20 @@ public:
this->remove(); this->remove();
} }
virtual void change_perms_normal() const override { virtual void change_perms_normal() const override {
rwfs::permissions(this->path(), std::filesystem::permissions(this->path(),
rwfs::perms::owner_read | rwfs::perms::owner_write | std::filesystem::perms::owner_read | std::filesystem::perms::owner_write |
rwfs::perms::group_read | std::filesystem::perms::group_read |
rwfs::perms::others_read); std::filesystem::perms::others_read);
} }
virtual void change_perms_readonly() const override { virtual void change_perms_readonly() const override {
rwfs::permissions(this->path(), rwfs::perms::owner_read | std::filesystem::permissions(this->path(),
rwfs::perms::group_read | std::filesystem::perms::owner_read |
rwfs::perms::others_read); std::filesystem::perms::group_read |
std::filesystem::perms::others_read);
} }
virtual void remove() const override { virtual void remove() const override {
rwfs::error_code ec; std::error_code ec;
rwfs::remove_all(this->path(), ec); std::filesystem::remove_all(this->path(), ec);
} }
virtual void touch() const override { virtual void touch() const override {
std::ofstream ofs(this->path().string(), std::ios::out | std::ios::app); std::ofstream ofs(this->path().string(), std::ios::out | std::ios::app);
@ -225,14 +243,14 @@ BOOST_AUTO_TEST_CASE(test_TempDir) {
tempChildDir.touch(); tempChildDir.touch();
BOOST_CHECK(tempChildDir.exists()); BOOST_CHECK(tempChildDir.exists());
rwfs::path path; std::filesystem::path path;
{ {
TempDir tempLocal; TempDir tempLocal;
tempLocal.touch(); tempLocal.touch();
BOOST_CHECK(tempLocal.exists()); BOOST_CHECK(tempLocal.exists());
path = tempLocal.path(); path = tempLocal.path();
} }
BOOST_CHECK(!rwfs::exists(path)); BOOST_CHECK(!std::filesystem::exists(path));
} }
BOOST_AUTO_TEST_CASE(test_TempFile) { BOOST_AUTO_TEST_CASE(test_TempFile) {
@ -261,14 +279,14 @@ BOOST_AUTO_TEST_CASE(test_TempFile) {
BOOST_CHECK(!tempFile.write("abc")); BOOST_CHECK(!tempFile.write("abc"));
BOOST_CHECK(!tempFile.append("def")); BOOST_CHECK(!tempFile.append("def"));
rwfs::path path; std::filesystem::path path;
{ {
TempFile tempLocal; TempFile tempLocal;
tempLocal.touch(); tempLocal.touch();
BOOST_CHECK(tempLocal.exists()); BOOST_CHECK(tempLocal.exists());
path = tempLocal.path(); path = tempLocal.path();
} }
BOOST_CHECK(!rwfs::exists(path)); BOOST_CHECK(!std::filesystem::exists(path));
} }
BOOST_AUTO_TEST_CASE(test_configParser_initial) { BOOST_AUTO_TEST_CASE(test_configParser_initial) {

View File

@ -30,7 +30,7 @@ BOOST_AUTO_TEST_CASE(test_indexTree, DATA_TEST_PREDICATE) {
auto truepath = index.findFilePath(upperpath); auto truepath = index.findFilePath(upperpath);
BOOST_ASSERT(!truepath.empty()); BOOST_ASSERT(!truepath.empty());
BOOST_CHECK(upperpath != truepath); BOOST_CHECK(upperpath != truepath);
rwfs::path expected{Global::getGamePath()}; std::filesystem::path expected{Global::getGamePath()};
expected /= "data/CULLZONE.DAT"; expected /= "data/CULLZONE.DAT";
BOOST_CHECK(expected.compare(expected) == 0); BOOST_CHECK(expected.compare(expected) == 0);
} }
@ -39,7 +39,7 @@ BOOST_AUTO_TEST_CASE(test_indexTree, DATA_TEST_PREDICATE) {
auto truepath = index.findFilePath(upperpath); auto truepath = index.findFilePath(upperpath);
BOOST_ASSERT(!truepath.empty()); BOOST_ASSERT(!truepath.empty());
BOOST_CHECK(upperpath != truepath); BOOST_CHECK(upperpath != truepath);
rwfs::path expected{Global::getGamePath()}; std::filesystem::path expected{Global::getGamePath()};
expected /= "data/maps/comnbtm/comNbtm.ipl"; expected /= "data/maps/comnbtm/comNbtm.ipl";
BOOST_CHECK(expected.compare(truepath) == 0); BOOST_CHECK(expected.compare(truepath) == 0);
} }

View File

@ -3,7 +3,7 @@
#include <RWConfig.hpp> #include <RWConfig.hpp>
std::string Global::getGamePath() { std::string Global::getGamePath() {
rwfs::path configPath = RWConfigParser::getDefaultConfigPath() / "openrw.ini"; std::filesystem::path configPath = RWConfigParser::getDefaultConfigPath() / "openrw.ini";
RWConfigParser cfgParser; RWConfigParser cfgParser;
auto [cfgLayer, parseResult] = cfgParser.loadFile(configPath); auto [cfgLayer, parseResult] = cfgParser.loadFile(configPath);
BOOST_REQUIRE(parseResult.isValid()); BOOST_REQUIRE(parseResult.isValid());