diff --git a/apps/bsatool/bsatool.cpp b/apps/bsatool/bsatool.cpp index c02c64356f..ad4556ddc6 100644 --- a/apps/bsatool/bsatool.cpp +++ b/apps/bsatool/bsatool.cpp @@ -17,7 +17,7 @@ namespace bpo = boost::program_options; struct Arguments { std::string mode; - std::string filename; + std::filesystem::path filename; std::string extractfile; std::string addfile; std::string outdir; @@ -112,7 +112,7 @@ bool parseOptions (int argc, char** argv, Arguments &info) << desc << std::endl; return false; } - info.filename = variables["input-file"].as< std::vector >()[0]; + info.filename = variables["input-file"].as< std::vector >()[0]; //TODO(Project579): This will probably break in windows with unicode paths // Default output to the working directory info.outdir = "."; diff --git a/apps/bulletobjecttool/main.cpp b/apps/bulletobjecttool/main.cpp index aad8c5e082..6f9e7ac376 100644 --- a/apps/bulletobjecttool/main.cpp +++ b/apps/bulletobjecttool/main.cpp @@ -33,6 +33,7 @@ namespace namespace bpo = boost::program_options; using StringsVector = std::vector; + using PathsVector = std::vector; bpo::options_description makeOptionsDescription() { @@ -145,7 +146,7 @@ namespace const auto fsStrict = variables["fs-strict"].as(); const auto resDir = variables["resources"].as(); - Version::Version v = Version::getOpenmwVersion(resDir.string()); + Version::Version v = Version::getOpenmwVersion(resDir); Log(Debug::Info) << v.describe(); dataDirs.insert(dataDirs.begin(), resDir / "vfs"); const auto fileCollections = Files::Collections(dataDirs, !fsStrict); diff --git a/apps/esmtool/arguments.hpp b/apps/esmtool/arguments.hpp index e3be98fd2a..bc5795942f 100644 --- a/apps/esmtool/arguments.hpp +++ b/apps/esmtool/arguments.hpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include @@ -18,8 +18,8 @@ namespace EsmTool std::string mode; std::string encoding; - std::string filename; - std::string outname; + std::filesystem::path filename; + std::filesystem::path outname; std::vector types; std::string name; diff --git a/apps/esmtool/esmtool.cpp b/apps/esmtool/esmtool.cpp index 381f46c3c4..a9971c1867 100644 --- a/apps/esmtool/esmtool.cpp +++ b/apps/esmtool/esmtool.cpp @@ -154,9 +154,9 @@ bool parseOptions (int argc, char** argv, Arguments &info) return false; }*/ - info.filename = variables["input-file"].as< std::vector >()[0]; + info.filename = variables["input-file"].as< std::vector >()[0]; if (variables["input-file"].as< std::vector >().size() > 1) - info.outname = variables["input-file"].as< std::vector >()[1]; + info.outname = variables["input-file"].as< std::vector >()[1]; if (const auto it = variables.find("raw"); it != variables.end()) info.mRawFormat = ESM::parseFormat(it->second.as()); @@ -284,9 +284,9 @@ void loadCell(const Arguments& info, ESM::Cell &cell, ESM::ESMReader &esm, ESMDa } } -void printRawTes3(std::string_view path) +void printRawTes3(const std::filesystem::path &path) { - std::cout << "TES3 RAW file listing: " << path << '\n'; + std::cout << "TES3 RAW file listing: " << path << '\n'; //TODO(Project579): This will probably break in windows with unicode paths ESM::ESMReader esm; esm.openRaw(path); while(esm.hasMoreRecs()) @@ -310,7 +310,7 @@ void printRawTes3(std::string_view path) int loadTes3(const Arguments& info, std::unique_ptr&& stream, ESMData* data) { - std::cout << "Loading TES3 file: " << info.filename << '\n'; + std::cout << "Loading TES3 file: " << info.filename << '\n'; //TODO(Project579): This will probably break in windows with unicode paths ESM::ESMReader esm; ToUTF8::Utf8Encoder encoder (ToUTF8::calculateEncoding(info.encoding)); @@ -419,7 +419,7 @@ int load(const Arguments& info, ESMData* data) printRawTes3(info.filename); break; case ESM::Format::Tes4: - std::cout << "Printing raw TES4 file is not supported: " << info.filename << "\n"; + std::cout << "Printing raw TES4 file is not supported: " << info.filename << "\n"; //TODO(Project579): This will probably break in windows with unicode paths break; } return 0; @@ -490,7 +490,7 @@ int clone(const Arguments& info) if (i % 3 != 0) std::cout << '\n'; - std::cout << "\nSaving records to: " << info.outname << "...\n"; + std::cout << "\nSaving records to: " << info.outname << "...\n"; //TODO(Project579): This will probably break in windows with unicode paths ESM::ESMWriter esm; ToUTF8::Utf8Encoder encoder (ToUTF8::calculateEncoding(info.encoding)); @@ -499,7 +499,7 @@ int clone(const Arguments& info) esm.setVersion(ESM::VER_13); esm.setRecordCount (recordCount); - std::fstream save(info.outname.c_str(), std::fstream::out | std::fstream::binary); + std::fstream save(info.outname, std::fstream::out | std::fstream::binary); esm.save(save); int saved = 0; @@ -563,14 +563,14 @@ int comp(const Arguments& info) ESMData dataOne; if (load(fileOne, &dataOne) != 0) { - std::cout << "Failed to load " << info.filename << ", aborting comparison." << std::endl; + std::cout << "Failed to load " << info.filename << ", aborting comparison." << std::endl; //TODO(Project579): This will probably break in windows with unicode paths return 1; } ESMData dataTwo; if (load(fileTwo, &dataTwo) != 0) { - std::cout << "Failed to load " << info.outname << ", aborting comparison." << std::endl; + std::cout << "Failed to load " << info.outname << ", aborting comparison." << std::endl; //TODO(Project579): This will probably break in windows with unicode paths return 1; } diff --git a/apps/esmtool/tes4.cpp b/apps/esmtool/tes4.cpp index 815eb6dd34..02e722631d 100644 --- a/apps/esmtool/tes4.cpp +++ b/apps/esmtool/tes4.cpp @@ -289,7 +289,7 @@ namespace EsmTool int loadTes4(const Arguments& info, std::unique_ptr&& stream) { - std::cout << "Loading TES4 file: " << info.filename << '\n'; + std::cout << "Loading TES4 file: " << info.filename << '\n'; //TODO(Project579): This will probably break in windows with unicode paths try { diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 2d52b6a066..d5f2259f2e 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -230,7 +230,7 @@ void Launcher::DataFilesPage::populateFileViews(const QString& contentModelName) if (!mDataLocal.isEmpty()) directories.insert(0, mDataLocal); - const auto globalDataDir = QString(mGameSettings.getGlobalDataDir().c_str()); + const auto globalDataDir = QString(mGameSettings.getGlobalDataDir().string().c_str()); //TODO(Project579): This will probably break in windows with unicode paths if (!globalDataDir.isEmpty()) directories.insert(0, globalDataDir); diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 8e5af37121..447dcb5193 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -155,7 +155,7 @@ Launcher::FirstRunDialogResult Launcher::MainDialog::showFirstRunDialog() return FirstRunDialogResultFailure; // Dialog wizard and setup will fail if the config directory does not already exist - QDir userConfigDir = QDir(QString::fromStdString(mCfgMgr.getUserConfigPath().string())); + QDir userConfigDir = QDir(QString::fromStdString(mCfgMgr.getUserConfigPath().string())); //TODO(Project579): This will probably break in windows with unicode paths, in Qt 6 it's possible to convert directly from std::filesystem::path to QDir and that would solve the issue if ( ! userConfigDir.exists() ) { if ( ! userConfigDir.mkpath(".") ) { @@ -295,7 +295,7 @@ bool Launcher::MainDialog::setupLauncherSettings() mLauncherSettings.setMultiValueEnabled(true); - QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str()); + QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str()); //TODO(Project579): This will probably break in windows with unicode paths QStringList paths; paths.append(QString(Config::LauncherSettings::sLauncherConfigFileName)); @@ -328,9 +328,9 @@ bool Launcher::MainDialog::setupGameSettings() { mGameSettings.clear(); - QString localPath = QString::fromUtf8(mCfgMgr.getLocalPath().string().c_str()); - QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str()); - QString globalPath = QString::fromUtf8(mCfgMgr.getGlobalPath().string().c_str()); + QString localPath = QString::fromUtf8(mCfgMgr.getLocalPath().string().c_str()); //TODO(Project579): This will probably break in windows with unicode paths + QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str()); //TODO(Project579): This will probably break in windows with unicode paths + QString globalPath = QString::fromUtf8(mCfgMgr.getGlobalPath().string().c_str()); //TODO(Project579): This will probably break in windows with unicode paths QFile file; @@ -479,7 +479,7 @@ bool Launcher::MainDialog::writeSettings() mSettingsPage->saveSettings(); mAdvancedPage->saveSettings(); - QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str()); + QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str()); //TODO(Project579): This will probably break in windows with unicode paths QDir dir(userPath); if (!dir.exists()) { @@ -509,13 +509,13 @@ bool Launcher::MainDialog::writeSettings() file.close(); // Graphics settings - const std::string settingsPath = (mCfgMgr.getUserConfigPath() / "settings.cfg").string(); + const auto settingsPath = mCfgMgr.getUserConfigPath() / "settings.cfg"; try { Settings::Manager::saveUser(settingsPath); } catch (std::exception& e) { std::string msg = "
Error writing settings.cfg

" + - settingsPath + "

" + e.what(); + settingsPath.string() + "

" + e.what(); //TODO(Project579): This will probably break in windows with unicode paths cfgError(tr("Error writing user settings file"), tr(msg.c_str())); return false; } diff --git a/apps/launcher/settingspage.cpp b/apps/launcher/settingspage.cpp index 96f11808f0..77d45e48ec 100644 --- a/apps/launcher/settingspage.cpp +++ b/apps/launcher/settingspage.cpp @@ -102,7 +102,7 @@ void Launcher::SettingsPage::on_importerButton_clicked() mMain->writeSettings(); // Create the file if it doesn't already exist, else the importer will fail - QString path(QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str())); + QString path(QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str())); //TODO(Project579): This will probably break in windows with unicode paths path.append(QLatin1String("openmw.cfg")); QFile file(path); diff --git a/apps/mwiniimporter/importer.cpp b/apps/mwiniimporter/importer.cpp index 305587162b..912aa2d5ed 100644 --- a/apps/mwiniimporter/importer.cpp +++ b/apps/mwiniimporter/importer.cpp @@ -661,7 +661,7 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::filesystem::pat std::string section(""); MwIniImporter::multistrmap map; - std::ifstream file((sfs::path(filename))); + std::ifstream file(filename); ToUTF8::Utf8Encoder encoder(mEncoding); std::string line; @@ -721,7 +721,7 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const std::filesystem::pat std::cout << "load cfg file: " << filename << std::endl; MwIniImporter::multistrmap map; - std::ifstream file((sfs::path(filename))); + std::ifstream file(filename); std::string line; while (std::getline(file, line)) { @@ -938,13 +938,13 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini, co reader.setEncoder(&encoder); for (auto& file : contentFiles) { - reader.open(file.second.string()); + reader.open(file.second); std::vector dependencies; for (auto& gameFile : reader.getGameFiles()) { dependencies.push_back(gameFile.name); } - unsortedFiles.emplace_back(std::filesystem::path(reader.getName()).filename().string(), dependencies); + unsortedFiles.emplace_back(reader.getName().filename().string(), dependencies); //TODO(Project579): This will probably break in windows with unicode paths reader.close(); } diff --git a/apps/mwiniimporter/main.cpp b/apps/mwiniimporter/main.cpp index d6afecb1ef..2de80ffb96 100644 --- a/apps/mwiniimporter/main.cpp +++ b/apps/mwiniimporter/main.cpp @@ -52,8 +52,6 @@ private: int wmain(int argc, wchar_t *wargv[]) { utf8argv converter(argc, wargv); char **argv = converter.get(); - // TODO(Project579): Temporarly disabled until a good solution is found (no solution might actually be needed) - //boost::filesystem::path::imbue(boost::locale::generator().generate("")); #endif try diff --git a/apps/navmeshtool/main.cpp b/apps/navmeshtool/main.cpp index de3ccdcf96..21751dca79 100644 --- a/apps/navmeshtool/main.cpp +++ b/apps/navmeshtool/main.cpp @@ -143,7 +143,7 @@ namespace NavMeshTool const auto fsStrict = variables["fs-strict"].as(); const auto resDir = variables["resources"].as(); - Version::Version v = Version::getOpenmwVersion(resDir.string()); + Version::Version v = Version::getOpenmwVersion(resDir); Log(Debug::Info) << v.describe(); dataDirs.insert(dataDirs.begin(), resDir / "vfs"); const auto fileCollections = Files::Collections(dataDirs, !fsStrict); @@ -179,9 +179,9 @@ namespace NavMeshTool const osg::Vec3f agentHalfExtents = Settings::Manager::getVector3("default actor pathfind half extents", "Game"); const DetourNavigator::AgentBounds agentBounds {agentCollisionShape, agentHalfExtents}; const std::uint64_t maxDbFileSize = static_cast(Settings::Manager::getInt64("max navmeshdb file size", "Navigator")); - const std::string dbPath = (config.getUserDataPath() / "navmesh.db").string(); + const auto dbPath = config.getUserDataPath() / "navmesh.db"; - DetourNavigator::NavMeshDb db(dbPath, maxDbFileSize); + DetourNavigator::NavMeshDb db(dbPath.string(), maxDbFileSize); //TODO(Project579): This will probably break in windows with unicode paths ESM::ReadersCache readers; EsmLoader::Query query; diff --git a/apps/niftest/niftest.cpp b/apps/niftest/niftest.cpp index 67d33c6b9d..60b13ae266 100644 --- a/apps/niftest/niftest.cpp +++ b/apps/niftest/niftest.cpp @@ -16,45 +16,45 @@ namespace bpo = boost::program_options; ///See if the file has the named extension -bool hasExtension(std::string filename, std::string extensionToFind) +bool hasExtension(const std::filesystem::path& filename, const std::string& extensionToFind) { - std::string extension = filename.substr(filename.find_last_of('.')+1); + std::string extension = filename.extension().string(); //TODO(Project579): let's hope unicode characters are never used in these extensions on windows or this will break return Misc::StringUtils::ciEqual(extension, extensionToFind); } ///See if the file has the "nif" extension. -bool isNIF(const std::string & filename) +bool isNIF(const std::filesystem::path &filename) { return hasExtension(filename,"nif"); } ///See if the file has the "bsa" extension. -bool isBSA(const std::string & filename) +bool isBSA(const std::filesystem::path &filename) { return hasExtension(filename,"bsa"); } /// Check all the nif files in a given VFS::Archive /// \note Can not read a bsa file inside of a bsa file. -void readVFS(std::unique_ptr&& anArchive, std::string archivePath = "") +void readVFS(std::unique_ptr&& anArchive, const std::filesystem::path& archivePath = {}) { VFS::Manager myManager(true); myManager.addArchive(std::move(anArchive)); myManager.buildIndex(); - for(const auto& name : myManager.getRecursiveDirectoryIterator("")) + for(const auto& name : myManager.getRecursiveDirectoryIterator("")) //TODO(Project579): This will probably break in windows with unicode paths { try{ if(isNIF(name)) { // std::cout << "Decoding: " << name << std::endl; - Nif::NIFFile temp_nif(myManager.get(name),archivePath+name); + Nif::NIFFile temp_nif(myManager.get(name),archivePath / name); } else if(isBSA(name)) { if(!archivePath.empty() && !isBSA(archivePath)) { // std::cout << "Reading BSA File: " << name << std::endl; - readVFS(std::make_unique(archivePath + name), archivePath + name + "/"); + readVFS(std::make_unique(archivePath / name), archivePath / name); // std::cout << "Done with BSA File: " << name << std::endl; } } @@ -75,7 +75,7 @@ bool parseOptions (int argc, char** argv, std::vector& files) "Allowed options"); desc.add_options() ("help,h", "print help message.") - ("input-file", bpo::value< std::vector >(), "input file") + ("input-file", bpo::value< std::vector >(), "input file") ; //Default option if none provided @@ -120,30 +120,30 @@ int main(int argc, char **argv) Nif::NIFFile::setLoadUnsupportedFiles(true); // std::cout << "Reading Files" << std::endl; - for(auto it=files.begin(); it!=files.end(); ++it) + for(const auto& name : files) { - std::string name = *it; - try { - if(isNIF(name)) + const std::filesystem::path path(name); //TODO(Project579): This will probably break in windows with unicode paths + + if(isNIF(path)) { //std::cout << "Decoding: " << name << std::endl; - Nif::NIFFile temp_nif(Files::openConstrainedFileStream(name), name); + Nif::NIFFile temp_nif(Files::openConstrainedFileStream(path), path); } - else if(isBSA(name)) + else if(isBSA(path)) { // std::cout << "Reading BSA File: " << name << std::endl; - readVFS(std::make_unique(name)); + readVFS(std::make_unique(path)); } - else if(std::filesystem::is_directory(std::filesystem::path(name))) + else if(std::filesystem::is_directory(path)) { // std::cout << "Reading All Files in: " << name << std::endl; - readVFS(std::make_unique(name), name); + readVFS(std::make_unique(path), path); } else { - std::cerr << "ERROR: \"" << name << "\" is not a nif file, bsa file, or directory!" << std::endl; + std::cerr << "ERROR: \"" << path << "\" is not a nif file, bsa file, or directory!" << std::endl; } } catch (std::exception& e) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index ed49c5399a..9a988991f0 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -78,8 +78,7 @@ CS::Editor::~Editor () mPidFile.close(); if(mServer && std::filesystem::exists(mPid)) - static_cast ( // silence coverity warning - remove(mPid.string().c_str())); // ignore any error + std::filesystem::remove(mPid); } boost::program_options::variables_map CS::Editor::readConfiguration() @@ -107,7 +106,7 @@ boost::program_options::variables_map CS::Editor::readConfiguration() mCfgMgr.readConfiguration(variables, desc, false); Settings::Manager::load(mCfgMgr, true); - setupLogging(mCfgMgr.getLogPath().string(), "OpenMW-CS"); + setupLogging(mCfgMgr.getLogPath(), "OpenMW-CS"); return variables; } @@ -298,7 +297,7 @@ bool CS::Editor::makeIPCServer() mPidFile.open(mPid); - mLock = boost::interprocess::file_lock(mPid.string().c_str()); + mLock = boost::interprocess::file_lock(mPid.c_str()); if(!mLock.try_lock()) { Log(Debug::Error) << "Error: OpenMW-CS is already running."; @@ -374,7 +373,7 @@ int CS::Editor::run() ESM::ESMReader fileReader; ToUTF8::Utf8Encoder encoder(ToUTF8::calculateEncoding(mEncodingName)); fileReader.setEncoder(&encoder); - fileReader.open(mFileToLoad.string()); + fileReader.open(mFileToLoad); std::vector discoveredFiles; @@ -394,7 +393,7 @@ int CS::Editor::run() } discoveredFiles.push_back(mFileToLoad); - QString extension = QString::fromStdString(mFileToLoad.extension().string()).toLower(); + QString extension = QString::fromStdString(mFileToLoad.extension().string()).toLower(); //TODO(Project579): let's hope unicode characters are never used in these extensions on windows or this will break if (extension == ".esm") { mFileToLoad.replace_extension(".omwgame"); diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index a4d47ad0f2..9a93430dc6 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -283,7 +283,7 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, : mSavePath (savePath), mContentFiles (std::move(files)), mNew (new_), mData (encoding, fsStrict, dataPaths, archives, resDir), mTools (*this, encoding), mProjectPath ((configuration.getUserDataPath() / "projects") / - (savePath.filename().string() + ".project")), + (savePath.filename().u8string() + u8".project")), mSavingOperation (*this, mProjectPath, encoding), mSaving (&mSavingOperation), mResDir(resDir), mRunner (mProjectPath), @@ -298,7 +298,7 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, std::ofstream destination(mProjectPath, std::ios::out | std::ios::binary); if (!destination.is_open()) - throw std::runtime_error("Can not create project file: " + mProjectPath.string()); + throw std::runtime_error("Can not create project file: " + mProjectPath.string()); //TODO(Project579): This will probably break in windows with unicode paths destination.exceptions(std::ios::failbit | std::ios::badbit); if (!std::filesystem::exists (filtersPath)) @@ -306,7 +306,7 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, std::ifstream source(filtersPath, std::ios::in | std::ios::binary); if (!source.is_open()) - throw std::runtime_error("Can not read filters file: " + filtersPath.string()); + throw std::runtime_error("Can not read filters file: " + filtersPath.string()); //TODO(Project579): This will probably break in windows with unicode paths source.exceptions(std::ios::failbit | std::ios::badbit); destination << source.rdbuf(); @@ -484,7 +484,7 @@ void CSMDoc::Document::startRunning (const std::string& profile, for (std::vector::const_iterator iter (mContentFiles.begin()); iter!=mContentFiles.end(); ++iter) - contentFiles.push_back (iter->filename().string()); + contentFiles.push_back (iter->filename().string()); //TODO(Project579): let's hope unicode characters are never used in these filenames on windows or this will break mRunner.configure (getData().getDebugProfiles().getRecord (profile).get(), contentFiles, startupInstruction); diff --git a/apps/opencs/model/doc/loader.cpp b/apps/opencs/model/doc/loader.cpp index 4563757020..70d114c47e 100644 --- a/apps/opencs/model/doc/loader.cpp +++ b/apps/opencs/model/doc/loader.cpp @@ -93,7 +93,7 @@ void CSMDoc::Loader::load() iter->second.mRecordsLeft = true; iter->second.mRecordsLoaded = 0; - emit nextStage (document, path.filename().string(), steps); + emit nextStage (document, path.filename().string(), steps); //TODO(Project579): let's hope unicode characters are never used in these filenames on windows or this will break } else if (iter->second.mFile==size) // start loading the last (project) file { diff --git a/apps/opencs/model/doc/runner.cpp b/apps/opencs/model/doc/runner.cpp index 55a8be2ae7..c1db116a52 100644 --- a/apps/opencs/model/doc/runner.cpp +++ b/apps/opencs/model/doc/runner.cpp @@ -83,7 +83,7 @@ void CSMDoc::Runner::start (bool delayed) arguments << ("--script-run="+mStartup->fileName()); arguments << - QString::fromUtf8 (("--data=\""+mProjectPath.parent_path().string()+"\"").c_str()); + QString::fromUtf8 (("--data=\""+mProjectPath.parent_path().string()+"\"").c_str()); //TODO(Project579): This will probably break in windows with unicode paths arguments << "--replace=content"; @@ -94,7 +94,7 @@ void CSMDoc::Runner::start (bool delayed) } arguments - << QString::fromUtf8 (("--content="+mProjectPath.filename().string()).c_str()); + << QString::fromUtf8 (("--content="+mProjectPath.filename().string()).c_str()); //TODO(Project579): let's hope unicode characters are never used in these filenames on windows or this will break mProcess.start (path, arguments); } diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index 7059188bac..20f3ca4ba6 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -72,7 +72,7 @@ void CSMDoc::WriteHeaderStage::perform (int stage, Messages& messages) for (std::vector::const_iterator iter (dependencies.begin()); iter!=end; ++iter) { - std::string name = iter->filename().string(); + std::string name = iter->filename().string(); //TODO(Project579): let's hope unicode characters are never used in these filenames on windows or this will break uint64_t size = std::filesystem::file_size (*iter); mState.getWriter().addMaster (name, size); diff --git a/apps/opencs/model/doc/savingstate.cpp b/apps/opencs/model/doc/savingstate.cpp index 8e6730d22c..e9a2b55385 100644 --- a/apps/opencs/model/doc/savingstate.cpp +++ b/apps/opencs/model/doc/savingstate.cpp @@ -34,7 +34,7 @@ void CSMDoc::SavingState::start (Document& document, bool project) else mPath = document.getSavePath(); - std::filesystem::path file (mPath.filename().string() + ".tmp"); + std::filesystem::path file (mPath.filename().u8string() + u8".tmp"); mTmpPath = mPath.parent_path(); diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index 673839d47c..ae2c94b11a 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -649,7 +649,7 @@ CSMPrefs::State::~State() void CSMPrefs::State::save() { std::filesystem::path user = mConfigurationManager.getUserConfigPath() / mConfigFile; - Settings::Manager::saveUser (user.string()); + Settings::Manager::saveUser (user); } CSMPrefs::State::Iterator CSMPrefs::State::begin() diff --git a/apps/opencs/model/tools/mergestages.cpp b/apps/opencs/model/tools/mergestages.cpp index 8a7541c0db..09a0db4078 100644 --- a/apps/opencs/model/tools/mergestages.cpp +++ b/apps/opencs/model/tools/mergestages.cpp @@ -44,7 +44,7 @@ void CSMTools::FinishMergedDocumentStage::perform (int stage, CSMDoc::Messages& ESM::ESMReader reader; reader.setEncoder (&mEncoder); - reader.open (path.string()); + reader.open (path); CSMWorld::MetaData source; source.mId = "sys::meta"; diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index f03aac0837..4fd3939883 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -88,7 +88,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, bool fsStrict, const Files::Pat defines[define.first] = define.second; mResourceSystem->getSceneManager()->getShaderManager().setGlobalDefines(defines); - mResourceSystem->getSceneManager()->setShaderPath((resDir / "shaders").string()); + mResourceSystem->getSceneManager()->setShaderPath(resDir / "shaders"); int index = 0; @@ -969,7 +969,7 @@ int CSMWorld::Data::getTotalRecords (const std::vector& f if (!std::filesystem::exists(files[i])) continue; - reader->open(files[i].string()); + reader->open(files[i]); records += reader->getRecordCount(); reader->close(); } @@ -989,9 +989,9 @@ int CSMWorld::Data::startLoading (const std::filesystem::path& path, bool base, mReader = new ESM::ESMReader; mReader->setEncoder (&mEncoder); mReader->setIndex((project || !base) ? 0 : mReaderIndex++); - mReader->open (path.string()); + mReader->open (path); - mContentFileNames.insert(std::make_pair(path.filename().string(), mReader->getIndex())); + mContentFileNames.insert(std::make_pair(path.filename().string(), mReader->getIndex())); //TODO(Project579): let's hope unicode characters are never used in these filenames on windows or this will break mBase = base; mProject = project; diff --git a/apps/opencs/view/doc/adjusterwidget.cpp b/apps/opencs/view/doc/adjusterwidget.cpp index 9ff2da125e..0e6ae73fe6 100644 --- a/apps/opencs/view/doc/adjusterwidget.cpp +++ b/apps/opencs/view/doc/adjusterwidget.cpp @@ -68,14 +68,14 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) } else { - std::filesystem::path path (name.toUtf8().data()); + std::filesystem::path path (name.toUtf8().data()); //TODO(Project579): Replace with char8_t in C++20 - std::string extension = Misc::StringUtils::lowerCase(path.extension().string()); + std::string extension = Misc::StringUtils::lowerCase(path.extension().string()); //TODO(Project579): let's hope unicode characters are never used in these extensions on windows or this will break bool isLegacyPath = (extension == ".esm" || extension == ".esp"); - bool isFilePathChanged = (path.parent_path().string() != mLocalData.string()); + bool isFilePathChanged = (path.parent_path() != mLocalData); if (isLegacyPath) path.replace_extension (addon ? ".omwaddon" : ".omwgame"); @@ -85,7 +85,7 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) if (!isFilePathChanged && !isLegacyPath) { // path already points to the local data directory - message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str()); + message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str()); //TODO(Project579): This is probably broken on windows with unicode paths mResultPath = path; } //in all other cases, ensure the path points to data-local and do an existing file check @@ -95,7 +95,7 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) if (isFilePathChanged) path = mLocalData / path.filename(); - message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str()); + message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str()); //TODO(Project579): This is probably broken on windows with unicode paths mResultPath = path; if (std::filesystem::exists (path)) diff --git a/apps/opencs/view/doc/loader.cpp b/apps/opencs/view/doc/loader.cpp index a33aa900fe..188827db2f 100644 --- a/apps/opencs/view/doc/loader.cpp +++ b/apps/opencs/view/doc/loader.cpp @@ -19,7 +19,7 @@ void CSVDoc::LoadingDocument::closeEvent (QCloseEvent *event) CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) : mDocument (document), mTotalRecordsLabel (0), mRecordsLabel (0), mAborted (false), mMessages (nullptr), mRecords(0) { - setWindowTitle (QString::fromUtf8((std::string("Opening ") + document->getSavePath().filename().string()).c_str())); + setWindowTitle (QString::fromUtf8((std::string("Opening ") + document->getSavePath().filename().string()).c_str())); //TODO(Project579): let's hope unicode characters are never used in these filenames on windows or this will break setMinimumWidth (400); diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index ca32e5fc79..eaeb6d3957 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -387,7 +387,7 @@ void CSVDoc::View::updateTitle() { std::ostringstream stream; - stream << mDocument->getSavePath().filename().string(); + stream << mDocument->getSavePath().filename().string(); //TODO(Project579): let's hope unicode characters are never used in these filenames on windows or this will break if (mDocument->getState() & CSMDoc::State_Modified) stream << " *"; @@ -747,7 +747,7 @@ void CSVDoc::View::tutorial() void CSVDoc::View::infoAbout() { // Get current OpenMW version - QString versionInfo = (Version::getOpenmwVersionDescription(mDocument->getResourceDir().string())+ + QString versionInfo = (Version::getOpenmwVersionDescription(mDocument->getResourceDir())+ #if defined(__x86_64__) || defined(_M_X64) " (64-bit)").c_str(); #else diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index c1fd21d246..92144ca668 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -261,7 +261,7 @@ bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (CSVDoc::View *view) QMessageBox messageBox(view); CSMDoc::Document *document = view->getDocument(); - messageBox.setWindowTitle (QString::fromUtf8(document->getSavePath().filename().string().c_str())); + messageBox.setWindowTitle (QString::fromUtf8(document->getSavePath().filename().string().c_str())); //TODO(Project579): let's hope unicode characters are never used in these filenames on windows or this will break messageBox.setText ("The document has been modified."); messageBox.setInformativeText ("Do you want to save your changes?"); messageBox.setStandardButtons (QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); diff --git a/apps/opencs/view/tools/merge.cpp b/apps/opencs/view/tools/merge.cpp index e8b963f235..0efce2aec3 100644 --- a/apps/opencs/view/tools/merge.cpp +++ b/apps/opencs/view/tools/merge.cpp @@ -102,7 +102,7 @@ void CSVTools::Merge::configure (CSMDoc::Document *document) for (std::vector::const_iterator iter (files.begin()); iter!=files.end(); ++iter) - mFiles->addItem (QString::fromUtf8 (iter->filename().string().c_str())); + mFiles->addItem (QString::fromUtf8 (iter->filename().string().c_str())); //TODO(Project579): let's hope unicode characters are never used in these filenames on windows or this will break } void CSVTools::Merge::setLocalData (const std::filesystem::path& localData) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 07f5f77e98..22cd339b36 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -528,7 +528,7 @@ void OMW::Engine::enableFSStrict(bool fsStrict) void OMW::Engine::setDataDirs (const Files::PathContainer& dataDirs) { mDataDirs = dataDirs; - mDataDirs.insert(mDataDirs.begin(), (mResDir / "vfs")); + mDataDirs.insert(mDataDirs.begin(), mResDir / "vfs"); mFileCollections = Files::Collections (mDataDirs, !mFSStrict); } @@ -708,10 +708,10 @@ void OMW::Engine::createWindow() void OMW::Engine::setWindowIcon() { std::ifstream windowIconStream; - std::string windowIcon = (mResDir / "openmw.png").string(); + const auto windowIcon = mResDir / "openmw.png"; windowIconStream.open(windowIcon, std::ios_base::in | std::ios_base::binary); if (windowIconStream.fail()) - Log(Debug::Error) << "Error: Failed to open " << windowIcon; + Log(Debug::Error) << "Error: Failed to open " << windowIcon; //TODO(Project579): This will probably break in windows with unicode paths osgDB::ReaderWriter* reader = osgDB::Registry::instance()->getReaderWriterForExtension("png"); if (!reader) { @@ -720,7 +720,7 @@ void OMW::Engine::setWindowIcon() } osgDB::ReaderWriter::ReadResult result = reader->readImage(windowIconStream); if (!result.success()) - Log(Debug::Error) << "Error: Failed to read " << windowIcon << ": " << result.message() << " code " << result.status(); + Log(Debug::Error) << "Error: Failed to read " << windowIcon << ": " << result.message() << " code " << result.status(); //TODO(Project579): This will probably break in windows with unicode paths else { osg::ref_ptr image = result.getImage(); @@ -765,7 +765,7 @@ void OMW::Engine::prepareEngine() mScreenCaptureOperation = new SceneUtil::AsyncScreenCaptureOperation( mWorkQueue, new SceneUtil::WriteScreenshotToFileOperation( - mCfgMgr.getScreenshotPath().string(), + mCfgMgr.getScreenshotPath(), Settings::Manager::getString("screenshot format", "General"), Settings::Manager::getBool("notify on saved screenshot", "General") ? std::function(ScheduleNonDialogMessageBox {}) @@ -777,35 +777,34 @@ void OMW::Engine::prepareEngine() mViewer->addEventHandler(mScreenCaptureHandler); - mLuaManager = std::make_unique(mVFS.get(), (mResDir / "lua_libs").string()); + mLuaManager = std::make_unique(mVFS.get(), mResDir / "lua_libs"); mEnvironment.setLuaManager(*mLuaManager); // Create input and UI first to set up a bootstrapping environment for // showing a loading screen and keeping the window responsive while doing so - std::string keybinderUser = (mCfgMgr.getUserConfigPath() / "input_v3.xml").string(); + const auto keybinderUser = mCfgMgr.getUserConfigPath() / "input_v3.xml"; bool keybinderUserExists = std::filesystem::exists(keybinderUser); if(!keybinderUserExists) { - std::string input2 = (mCfgMgr.getUserConfigPath() / "input_v2.xml").string(); + const auto input2 = (mCfgMgr.getUserConfigPath() / "input_v2.xml"); if(std::filesystem::exists(input2)) { - std::filesystem::copy_file(input2, keybinderUser); - keybinderUserExists = std::filesystem::exists(keybinderUser); - Log(Debug::Info) << "Loading keybindings file: " << keybinderUser; + keybinderUserExists = std::filesystem::copy_file(input2, keybinderUser); + Log(Debug::Info) << "Loading keybindings file: " << keybinderUser; //TODO(Project579): This will probably break in windows with unicode paths } } else - Log(Debug::Info) << "Loading keybindings file: " << keybinderUser; + Log(Debug::Info) << "Loading keybindings file: " << keybinderUser; //TODO(Project579): This will probably break in windows with unicode paths - const std::string userdefault = mCfgMgr.getUserConfigPath().string() + "/gamecontrollerdb.txt"; - const std::string localdefault = mCfgMgr.getLocalPath().string() + "/gamecontrollerdb.txt"; - const std::string globaldefault = mCfgMgr.getGlobalPath().string() + "/gamecontrollerdb.txt"; + const auto userdefault = mCfgMgr.getUserConfigPath() / "gamecontrollerdb.txt"; + const auto localdefault = mCfgMgr.getLocalPath() / "gamecontrollerdb.txt"; + const auto globaldefault = mCfgMgr.getGlobalPath() / "gamecontrollerdb.txt"; - std::string userGameControllerdb; + std::filesystem::path userGameControllerdb; if (std::filesystem::exists(userdefault)) userGameControllerdb = userdefault; - std::string gameControllerdb; + std::filesystem::path gameControllerdb; if (std::filesystem::exists(localdefault)) gameControllerdb = localdefault; else if (std::filesystem::exists(globaldefault)) @@ -813,7 +812,7 @@ void OMW::Engine::prepareEngine() //else if it doesn't exist, pass in an empty string // gui needs our shaders path before everything else - mResourceSystem->getSceneManager()->setShaderPath((mResDir / "shaders").string()); + mResourceSystem->getSceneManager()->setShaderPath(mResDir / "shaders"); osg::ref_ptr exts = osg::GLExtensions::Get(0, false); bool shadersSupported = exts && (exts->glslLanguageVersion >= 1.2f); @@ -831,9 +830,9 @@ void OMW::Engine::prepareEngine() rootNode->addChild(guiRoot); mWindowManager = std::make_unique(mWindow, mViewer, guiRoot, mResourceSystem.get(), mWorkQueue.get(), - mCfgMgr.getLogPath().string() + std::string("/"), + mCfgMgr.getLogPath(), mScriptConsoleMode, mTranslationDataStorage, mEncoding, - Version::getOpenmwVersionDescription(mResDir.string()), shadersSupported); + Version::getOpenmwVersionDescription(mResDir), shadersSupported); mEnvironment.setWindowManager(*mWindowManager); mInputManager = std::make_unique(mWindow, mViewer, mScreenCaptureHandler, @@ -854,7 +853,7 @@ void OMW::Engine::prepareEngine() // Create the world mWorld = std::make_unique(mViewer, rootNode, mResourceSystem.get(), mWorkQueue.get(), *mUnrefQueue, mFileCollections, mContentFiles, mGroundcoverFiles, mEncoder.get(), mActivationDistanceOverride, mCellName, - mStartupScript, mResDir.string(), mCfgMgr.getUserDataPath().string()); + mStartupScript, mResDir, mCfgMgr.getUserDataPath()); mWorld->setupPlayer(); mWorld->setRandomSeed(mRandomSeed); mEnvironment.setWorld(*mWorld); @@ -865,8 +864,8 @@ void OMW::Engine::prepareEngine() //Load translation data mTranslationDataStorage.setEncoder(mEncoder.get()); - for (size_t i = 0; i < mContentFiles.size(); i++) - mTranslationDataStorage.loadTranslationData(mFileCollections, mContentFiles[i]); + for (auto & mContentFile : mContentFiles) + mTranslationDataStorage.loadTranslationData(mFileCollections, mContentFile); Compiler::registerExtensions (mExtensions); @@ -910,7 +909,7 @@ void OMW::Engine::prepareEngine() } mLuaManager->init(); - mLuaManager->loadPermanentStorage(mCfgMgr.getUserConfigPath().string()); + mLuaManager->loadPermanentStorage(mCfgMgr.getUserConfigPath()); } class OMW::Engine::LuaWorker @@ -1014,7 +1013,7 @@ void OMW::Engine::go() Misc::Rng::init(mRandomSeed); - Settings::ShaderManager::get().load((mCfgMgr.getUserConfigPath() / "shaders.yaml").string()); + Settings::ShaderManager::get().load(mCfgMgr.getUserConfigPath() / "shaders.yaml"); MWClass::registerClasses(); @@ -1033,13 +1032,13 @@ void OMW::Engine::go() prepareEngine(); std::ofstream stats; - if (const auto path = std::getenv("OPENMW_OSG_STATS_FILE")) + if (const auto path = std::getenv("OPENMW_OSG_STATS_FILE")) //TODO(Project579): This will probably break in windows with unicode paths { - stats.open(path, std::ios_base::out); + stats.open(path, std::ios_base::out); //TODO(Project579): This will probably break in windows with unicode paths if (stats.is_open()) - Log(Debug::Info) << "Stats will be written to: " << path; + Log(Debug::Info) << "Stats will be written to: " << path; //TODO(Project579): This will probably break in windows with unicode paths else - Log(Debug::Warning) << "Failed to open file for stats: " << path; + Log(Debug::Warning) << "Failed to open file for stats: " << path; //TODO(Project579): This will probably break in windows with unicode paths } // Setup profiler @@ -1136,9 +1135,9 @@ void OMW::Engine::go() luaWorker.join(); // Save user settings - Settings::Manager::saveUser((mCfgMgr.getUserConfigPath() / "settings.cfg").string()); + Settings::Manager::saveUser(mCfgMgr.getUserConfigPath() / "settings.cfg"); Settings::ShaderManager::get().save(); - mLuaManager->savePermanentStorage(mCfgMgr.getUserConfigPath().string()); + mLuaManager->savePermanentStorage(mCfgMgr.getUserConfigPath()); Log(Debug::Info) << "Quitting peacefully."; } @@ -1193,7 +1192,7 @@ void OMW::Engine::setScriptBlacklistUse (bool use) mScriptBlacklistUse = use; } -void OMW::Engine::setSaveGameFile(const std::string &savegame) +void OMW::Engine::setSaveGameFile(const std::filesystem::path &savegame) { mSaveGameFile = savegame; } diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index cc3f92cdd2..98d667dc43 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -158,7 +158,7 @@ namespace OMW bool mScriptConsoleMode; std::string mStartupScript; int mActivationDistanceOverride; - std::string mSaveGameFile; + std::filesystem::path mSaveGameFile; // Grab mouse? bool mGrab; @@ -256,7 +256,7 @@ namespace OMW void setScriptBlacklistUse (bool use); /// Set the save game file to load after initialising the engine. - void setSaveGameFile(const std::string& savegame); + void setSaveGameFile(const std::filesystem::path &savegame); void setRandomSeed(unsigned int seed); diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index f13d1b39b5..c327683bee 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -61,7 +61,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat { cfgMgr.readConfiguration(variables, desc, true); - Version::Version v = Version::getOpenmwVersion(variables["resources"].as().string()); + Version::Version v = Version::getOpenmwVersion(variables["resources"].as()); getRawStdout() << v.describe() << std::endl; return false; } @@ -69,10 +69,10 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat cfgMgr.readConfiguration(variables, desc); Settings::Manager::load(cfgMgr); - setupLogging(cfgMgr.getLogPath().string(), "OpenMW"); + setupLogging(cfgMgr.getLogPath(), "OpenMW"); MWGui::DebugWindow::startLogRecording(); - Version::Version v = Version::getOpenmwVersion(variables["resources"].as().string()); + Version::Version v = Version::getOpenmwVersion(variables["resources"].as()); Log(Debug::Info) << v.describe(); engine.setGrabMouse(!variables["no-grab"].as()); @@ -150,7 +150,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat engine.setWarningsMode (variables["script-warn"].as()); engine.setScriptBlacklist (variables["script-blacklist"].as()); engine.setScriptBlacklistUse (variables["script-blacklist-use"].as()); - engine.setSaveGameFile (variables["load-savegame"].as().string()); + engine.setSaveGameFile (variables["load-savegame"].as()); // other settings Fallback::Map::init(variables["fallback"].as().mMap); diff --git a/apps/openmw/mwbase/statemanager.hpp b/apps/openmw/mwbase/statemanager.hpp index c18db4190d..df4df0943d 100644 --- a/apps/openmw/mwbase/statemanager.hpp +++ b/apps/openmw/mwbase/statemanager.hpp @@ -62,12 +62,12 @@ namespace MWBase /// /// \note Slot must belong to the current character. - virtual void loadGame (const std::string& filepath) = 0; + virtual void loadGame (const std::filesystem::path &filepath) = 0; ///< Load a saved game directly from the given file path. This will search the CharacterManager /// for a Character containing this save file, and set this Character current if one was found. /// Otherwise, a new Character will be created. - virtual void loadGame (const MWState::Character *character, const std::string& filepath) = 0; + virtual void loadGame (const MWState::Character *character, const std::filesystem::path &filepath) = 0; ///< Load a saved game file belonging to the given character. ///Simple saver, writes over the file if already existing diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index e463c812c2..a99adb771e 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -639,7 +639,7 @@ namespace MWBase /// Export scene graph to a file and return the filename. /// \param ptr object to export scene graph for (if empty, export entire scene graph) - virtual std::string exportSceneGraph(const MWWorld::Ptr& ptr) = 0; + virtual std::filesystem::path exportSceneGraph(const MWWorld::Ptr& ptr) = 0; /// Preload VFX associated with this effect list virtual void preloadEffects(const ESM::EffectList* effectList) = 0; diff --git a/apps/openmw/mwgui/savegamedialog.cpp b/apps/openmw/mwgui/savegamedialog.cpp index 413e677917..69082bd6bb 100644 --- a/apps/openmw/mwgui/savegamedialog.cpp +++ b/apps/openmw/mwgui/savegamedialog.cpp @@ -200,7 +200,7 @@ namespace MWGui if (mCurrentCharacter == &*it || (!mCurrentCharacter && !mSaving && directory==Misc::StringUtils::lowerCase ( - it->begin()->mPath.parent_path().filename().string()))) + it->begin()->mPath.parent_path().filename().string()))) //TODO(Project579): let's hope unicode characters are never used in these filenames on windows or this will break { mCurrentCharacter = &*it; selectedIndex = mCharacterSelection->getItemCount()-1; @@ -303,7 +303,7 @@ namespace MWGui else { assert (mCurrentCharacter && mCurrentSlot); - MWBase::Environment::get().getStateManager()->loadGame (mCurrentCharacter, mCurrentSlot->mPath.string()); + MWBase::Environment::get().getStateManager()->loadGame (mCurrentCharacter, mCurrentSlot->mPath); } } diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 51867fc322..8889c970c1 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -120,7 +120,7 @@ namespace MWGui { WindowManager::WindowManager( SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, - const std::string& logpath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, + const std::filesystem::path& logpath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, ToUTF8::FromType encoding, const std::string& versionDescription, bool useShaders) : mOldUpdateMask(0) , mOldCullMask(0) @@ -180,7 +180,7 @@ namespace MWGui mScalingFactor = std::clamp(Settings::Manager::getFloat("scaling factor", "GUI"), 0.5f, 8.f); mGuiPlatform = std::make_unique(viewer, guiRoot, resourceSystem->getImageManager(), resourceSystem->getVFS(), mScalingFactor, "mygui", - (std::filesystem::path(logpath) / "MyGUI.log").generic_string()); + logpath / "MyGUI.log"); mGui = std::make_unique(); mGui->initialise(""); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 107bfdeb75..162f3403aa 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -37,6 +37,7 @@ #include #include #include +#include namespace MyGUI { @@ -124,7 +125,7 @@ namespace MWGui typedef std::vector FactionList; WindowManager(SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, - const std::string& logpath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, + const std::filesystem::path& logpath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, ToUTF8::FromType encoding, const std::string& versionDescription, bool useShaders); virtual ~WindowManager(); diff --git a/apps/openmw/mwinput/bindingsmanager.cpp b/apps/openmw/mwinput/bindingsmanager.cpp index a1b4845250..376a8a145f 100644 --- a/apps/openmw/mwinput/bindingsmanager.cpp +++ b/apps/openmw/mwinput/bindingsmanager.cpp @@ -43,8 +43,8 @@ namespace MWInput class InputControlSystem : public ICS::InputControlSystem { public: - InputControlSystem(const std::string& bindingsFile) - : ICS::InputControlSystem(bindingsFile, true, nullptr, nullptr, A_Last) + InputControlSystem(const std::filesystem::path &bindingsFile) + : ICS::InputControlSystem(bindingsFile.string(), true, nullptr, nullptr, A_Last) //TODO(Project579): This is probably broken on windows with unicode paths { } }; @@ -167,11 +167,11 @@ namespace MWInput bool mDetectingKeyboard; }; - BindingsManager::BindingsManager(const std::string& userFile, bool userFileExists) + BindingsManager::BindingsManager(const std::filesystem::path &userFile, bool userFileExists) : mUserFile(userFile) , mDragDrop(false) { - std::string file = userFileExists ? userFile : ""; + const auto file = userFileExists ? userFile : std::filesystem::path(); mInputBinder = std::make_unique(file); mListener = std::make_unique(mInputBinder.get(), this); mInputBinder->setDetectingBindingListener(mListener.get()); @@ -192,7 +192,7 @@ namespace MWInput BindingsManager::~BindingsManager() { - mInputBinder->save(mUserFile); + mInputBinder->save(mUserFile.string()); //TODO(Project579): This will probably break in windows with unicode paths } void BindingsManager::update(float dt) diff --git a/apps/openmw/mwinput/bindingsmanager.hpp b/apps/openmw/mwinput/bindingsmanager.hpp index 3808a21dfd..a3b3825b99 100644 --- a/apps/openmw/mwinput/bindingsmanager.hpp +++ b/apps/openmw/mwinput/bindingsmanager.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -15,7 +16,7 @@ namespace MWInput class BindingsManager { public: - BindingsManager(const std::string& userFile, bool userFileExists); + BindingsManager(const std::filesystem::path &userFile, bool userFileExists); virtual ~BindingsManager(); @@ -70,7 +71,7 @@ namespace MWInput std::unique_ptr mInputBinder; std::unique_ptr mListener; - std::string mUserFile; + std::filesystem::path mUserFile; bool mDragDrop; }; diff --git a/apps/openmw/mwinput/controllermanager.cpp b/apps/openmw/mwinput/controllermanager.cpp index adc62a80c5..c95a924280 100644 --- a/apps/openmw/mwinput/controllermanager.cpp +++ b/apps/openmw/mwinput/controllermanager.cpp @@ -27,8 +27,8 @@ namespace MWInput ControllerManager::ControllerManager(BindingsManager* bindingsManager, ActionManager* actionManager, MouseManager* mouseManager, - const std::string& userControllerBindingsFile, - const std::string& controllerBindingsFile) + const std::filesystem::path &userControllerBindingsFile, + const std::filesystem::path &controllerBindingsFile) : mBindingsManager(bindingsManager) , mActionManager(actionManager) , mMouseManager(mouseManager) @@ -43,12 +43,12 @@ namespace MWInput { if (!controllerBindingsFile.empty()) { - SDL_GameControllerAddMappingsFromFile(controllerBindingsFile.c_str()); + SDL_GameControllerAddMappingsFromFile(controllerBindingsFile.string().c_str()); //TODO(Project579): This will probably break in windows with unicode paths } if (!userControllerBindingsFile.empty()) { - SDL_GameControllerAddMappingsFromFile(userControllerBindingsFile.c_str()); + SDL_GameControllerAddMappingsFromFile(userControllerBindingsFile.string().c_str()); //TODO(Project579): This will probably break in windows with unicode paths } // Open all presently connected sticks diff --git a/apps/openmw/mwinput/controllermanager.hpp b/apps/openmw/mwinput/controllermanager.hpp index 2472128c26..ea89c8aec3 100644 --- a/apps/openmw/mwinput/controllermanager.hpp +++ b/apps/openmw/mwinput/controllermanager.hpp @@ -5,6 +5,7 @@ #include #include +#include namespace MWInput { @@ -18,8 +19,8 @@ namespace MWInput ControllerManager(BindingsManager* bindingsManager, ActionManager* actionManager, MouseManager* mouseManager, - const std::string& userControllerBindingsFile, - const std::string& controllerBindingsFile); + const std::filesystem::path &userControllerBindingsFile, + const std::filesystem::path &controllerBindingsFile); virtual ~ControllerManager() = default; diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 9a7b84722a..abe9996e01 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -28,8 +28,8 @@ namespace MWInput osg::ref_ptr viewer, osg::ref_ptr screenCaptureHandler, osgViewer::ScreenCaptureHandler::CaptureOperation *screenCaptureOperation, - const std::string& userFile, bool userFileExists, const std::string& userControllerBindingsFile, - const std::string& controllerBindingsFile, bool grab) + const std::filesystem::path &userFile, bool userFileExists, const std::filesystem::path &userControllerBindingsFile, + const std::filesystem::path &controllerBindingsFile, bool grab) : mControlsDisabled(false) , mInputWrapper(std::make_unique(window, viewer, grab)) , mBindingsManager(std::make_unique(userFile, userFileExists)) diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 738ff98bdf..d31aeff51b 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -8,6 +8,7 @@ #include #include +#include #include "../mwbase/inputmanager.hpp" @@ -52,9 +53,9 @@ namespace MWInput osg::ref_ptr viewer, osg::ref_ptr screenCaptureHandler, osgViewer::ScreenCaptureHandler::CaptureOperation *screenCaptureOperation, - const std::string& userFile, bool userFileExists, - const std::string& userControllerBindingsFile, - const std::string& controllerBindingsFile, bool grab); + const std::filesystem::path &userFile, bool userFileExists, + const std::filesystem::path &userControllerBindingsFile, + const std::filesystem::path &controllerBindingsFile, bool grab); ~InputManager() final; diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index 2864f3c6dd..2c8754375c 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -31,7 +31,7 @@ namespace MWLua { - LuaManager::LuaManager(const VFS::Manager* vfs, const std::string& libsDir) + LuaManager::LuaManager(const VFS::Manager* vfs, const std::filesystem::path &libsDir) : mLua(vfs, &mConfiguration) , mUiResourceManager(vfs) , mL10n(vfs, &mLua) @@ -110,21 +110,20 @@ namespace MWLua return mL10n.translate(contextName, key); } - void LuaManager::loadPermanentStorage(const std::string& userConfigPath) + void LuaManager::loadPermanentStorage(const std::filesystem::path &userConfigPath) { - auto globalPath = std::filesystem::path(userConfigPath) / "global_storage.bin"; - auto playerPath = std::filesystem::path(userConfigPath) / "player_storage.bin"; + const auto globalPath = userConfigPath / "global_storage.bin"; + const auto playerPath = userConfigPath / "player_storage.bin"; if (std::filesystem::exists(globalPath)) - mGlobalStorage.load(globalPath.string()); + mGlobalStorage.load(globalPath); if (std::filesystem::exists(playerPath)) - mPlayerStorage.load(playerPath.string()); + mPlayerStorage.load(playerPath); } - void LuaManager::savePermanentStorage(const std::string& userConfigPath) + void LuaManager::savePermanentStorage(const std::filesystem::path &userConfigPath) { - std::filesystem::path confDir(userConfigPath); - mGlobalStorage.save((confDir / "global_storage.bin").string()); - mPlayerStorage.save((confDir / "player_storage.bin").string()); + mGlobalStorage.save(userConfigPath / "global_storage.bin"); + mPlayerStorage.save(userConfigPath / "player_storage.bin"); } void LuaManager::update() diff --git a/apps/openmw/mwlua/luamanagerimp.hpp b/apps/openmw/mwlua/luamanagerimp.hpp index 40829e8958..8c4c6f4d95 100644 --- a/apps/openmw/mwlua/luamanagerimp.hpp +++ b/apps/openmw/mwlua/luamanagerimp.hpp @@ -11,6 +11,7 @@ #include #include +#include #include "../mwbase/luamanager.hpp" @@ -26,7 +27,7 @@ namespace MWLua class LuaManager : public MWBase::LuaManager { public: - LuaManager(const VFS::Manager* vfs, const std::string& libsDir); + LuaManager(const VFS::Manager* vfs, const std::filesystem::path &libsDir); // Called by engine.cpp before UI setup. void initL10n(); @@ -34,8 +35,8 @@ namespace MWLua // Called by engine.cpp when the environment is fully initialized. void init(); - void loadPermanentStorage(const std::string& userConfigPath); - void savePermanentStorage(const std::string& userConfigPath); + void loadPermanentStorage(const std::filesystem::path &userConfigPath); + void savePermanentStorage(const std::filesystem::path &userConfigPath); // Called by engine.cpp every frame. For performance reasons it works in a separate // thread (in parallel with osg Cull). Can not use scene graph. diff --git a/apps/openmw/mwrender/postprocessor.cpp b/apps/openmw/mwrender/postprocessor.cpp index 82cfb50a71..be84d8fdff 100644 --- a/apps/openmw/mwrender/postprocessor.cpp +++ b/apps/openmw/mwrender/postprocessor.cpp @@ -218,11 +218,11 @@ namespace MWRender for (const auto& name : mVFS->getRecursiveDirectoryIterator(fx::Technique::sSubdir)) { std::filesystem::path path = name; - std::string fileExt = Misc::StringUtils::lowerCase(path.extension().string()); + std::string fileExt = Misc::StringUtils::lowerCase(path.extension().string()); //TODO(Project579): let's hope unicode characters are never used in these extensions on windows or this will break if (!path.parent_path().has_parent_path() && fileExt == fx::Technique::sExt) { - auto absolutePath = std::filesystem::path(mVFS->getAbsoluteFileName(name)); - mTechniqueFileMap[absolutePath.stem().string()] = absolutePath; + const auto absolutePath = mVFS->getAbsoluteFileName(name); //TODO(Project579): let's hope unicode characters are never used in these filenames on windows or this will break + mTechniqueFileMap[absolutePath.stem().string()] = absolutePath; //TODO(Project579): This will probably break in windows with unicode paths } } } @@ -387,7 +387,7 @@ namespace MWRender std::this_thread::sleep_for(std::chrono::milliseconds(5)); if (technique->compile()) - Log(Debug::Info) << "Reloaded technique : " << mTechniqueFileMap[technique->getName()].string(); + Log(Debug::Info) << "Reloaded technique : " << mTechniqueFileMap[technique->getName()].string(); //TODO(Project579): This will probably break in windows with unicode paths mReload = technique->isValid(); } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 4dbbb5dc91..3662e13283 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -369,7 +369,7 @@ namespace MWRender }; RenderingManager::RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr rootNode, - Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::string& resourcePath, + Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::filesystem::path& resourcePath, DetourNavigator::Navigator& navigator, const MWWorld::GroundcoverStore& groundcoverStore, SceneUtil::UnrefQueue& unrefQueue) : mSkyBlending(Settings::Manager::getBool("sky blending", "Fog")) @@ -1526,7 +1526,7 @@ namespace MWRender updateProjectionMatrix(); } } - void RenderingManager::exportSceneGraph(const MWWorld::Ptr &ptr, const std::string &filename, const std::string &format) + void RenderingManager::exportSceneGraph(const MWWorld::Ptr &ptr, const std::filesystem::path& filename, const std::string &format) { osg::Node* node = mViewer->getSceneData(); if (!ptr.isEmpty()) diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 68a77c39f3..2f7a1f0a51 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -102,7 +102,7 @@ namespace MWRender { public: RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr rootNode, - Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::string& resourcePath, + Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::filesystem::path& resourcePath, DetourNavigator::Navigator& navigator, const MWWorld::GroundcoverStore& groundcoverStore, SceneUtil::UnrefQueue& unrefQueue); ~RenderingManager(); @@ -232,7 +232,7 @@ namespace MWRender osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& object) const; - void exportSceneGraph(const MWWorld::Ptr& ptr, const std::string& filename, const std::string& format); + void exportSceneGraph(const MWWorld::Ptr& ptr, const std::filesystem::path& filename, const std::string& format); LandManager* getLandManager() const; diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 8de9191868..8ad7997c2e 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -238,21 +238,21 @@ private: float mRainIntensity; }; -osg::ref_ptr readPngImage (const std::string& file) +osg::ref_ptr readPngImage (const std::filesystem::path& file) { std::ifstream inStream; inStream.open(file, std::ios_base::in | std::ios_base::binary); if (inStream.fail()) - Log(Debug::Error) << "Error: Failed to open " << file; + Log(Debug::Error) << "Error: Failed to open " << file; //TODO(Project579): This will probably break in windows with unicode paths osgDB::ReaderWriter* reader = osgDB::Registry::instance()->getReaderWriterForExtension("png"); if (!reader) { - Log(Debug::Error) << "Error: Failed to read " << file << ", no png readerwriter found"; + Log(Debug::Error) << "Error: Failed to read " << file << ", no png readerwriter found"; //TODO(Project579): This will probably break in windows with unicode paths return osg::ref_ptr(); } osgDB::ReaderWriter::ReadResult result = reader->readImage(inStream); if (!result.success()) - Log(Debug::Error) << "Error: Failed to read " << file << ": " << result.message() << " code " << result.status(); + Log(Debug::Error) << "Error: Failed to read " << file << ": " << result.message() << " code " << result.status(); //TODO(Project579): This will probably break in windows with unicode paths return result.getImage(); } @@ -444,7 +444,7 @@ public: }; Water::Water(osg::Group *parent, osg::Group* sceneRoot, Resource::ResourceSystem *resourceSystem, - osgUtil::IncrementalCompileOperation *ico, const std::string& resourcePath) + osgUtil::IncrementalCompileOperation *ico, const std::filesystem::path& resourcePath) : mRainIntensityUpdater(nullptr) , mParent(parent) , mSceneRoot(sceneRoot) @@ -695,7 +695,7 @@ void Water::createShaderWaterStateSet(osg::Node* node, Reflection* reflection, R osg::ref_ptr fragmentShader(shaderMgr.getShader("water_fragment.glsl", defineMap, osg::Shader::FRAGMENT)); osg::ref_ptr program = shaderMgr.getProgram(vertexShader, fragmentShader); - osg::ref_ptr normalMap(new osg::Texture2D(readPngImage(mResourcePath + "/shaders/water_nm.png"))); + osg::ref_ptr normalMap(new osg::Texture2D(readPngImage(mResourcePath / "shaders" / "water_nm.png"))); if (normalMap->getImage()) normalMap->getImage()->flipVertical(); diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index c7acbf708f..8309566031 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -65,7 +65,7 @@ namespace MWRender osg::ref_ptr mRefraction; osg::ref_ptr mReflection; - const std::string mResourcePath; + const std::filesystem::path mResourcePath; bool mEnabled; bool mToggled; @@ -90,7 +90,7 @@ namespace MWRender public: Water(osg::Group* parent, osg::Group* sceneRoot, Resource::ResourceSystem* resourceSystem, osgUtil::IncrementalCompileOperation* ico, - const std::string& resourcePath); + const std::filesystem::path& resourcePath); ~Water(); void setCullCallback(osg::Callback* callback); diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index a005594490..eb82eb9d2e 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -1527,8 +1527,8 @@ namespace MWScript runtime.getContext().report("Exporting the entire scene graph will result in a large file. Confirm this action using 'showscenegraph 1' or select an object instead."); else { - const std::string& filename = MWBase::Environment::get().getWorld()->exportSceneGraph(ptr); - runtime.getContext().report("Wrote '" + filename + "'"); + const auto filename = MWBase::Environment::get().getWorld()->exportSceneGraph(ptr); + runtime.getContext().report("Wrote '" + filename.string() + "'"); //TODO(Project579): This will probably break in windows with unicode paths } } }; diff --git a/apps/openmw/mwstate/character.cpp b/apps/openmw/mwstate/character.cpp index 0d90ab121a..136adfec89 100644 --- a/apps/openmw/mwstate/character.cpp +++ b/apps/openmw/mwstate/character.cpp @@ -33,7 +33,7 @@ void MWState::Character::addSlot (const std::filesystem::path& path, const std:: slot.mTimeStamp = std::filesystem::last_write_time (path); ESM::ESMReader reader; - reader.open (slot.mPath.string()); + reader.open (slot.mPath); if (reader.getRecName()!=ESM::REC_SAVE) return; // invalid save file -> ignore @@ -91,13 +91,11 @@ MWState::Character::Character (std::filesystem::path saves, const std::string& g } else { - for (std::filesystem::directory_iterator iter (mPath); iter!=std::filesystem::directory_iterator(); ++iter) + for (const auto& iter : std::filesystem::directory_iterator (mPath)) { - std::filesystem::path slotPath = *iter; - try { - addSlot (slotPath, game); + addSlot (iter, game); } catch (...) {} // ignoring bad saved game files for now } diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index 2b80063265..3142b495a4 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -305,7 +305,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot throw std::runtime_error("Write operation failed (file stream)"); Settings::Manager::setString ("character", "Saves", - slot->mPath.parent_path().filename().string()); + slot->mPath.parent_path().filename().string()); //TODO(Project579): let's hope unicode characters are never used in these filenames on windows or this will break const auto finish = std::chrono::steady_clock::now(); @@ -364,15 +364,15 @@ void MWState::StateManager::quickSave (std::string name) saveGame(name, saveFinder.getNextQuickSaveSlot()); } -void MWState::StateManager::loadGame(const std::string& filepath) +void MWState::StateManager::loadGame(const std::filesystem::path &filepath) { for (const auto& character : mCharacterManager) { for (const auto& slot : character) { - if (slot.mPath == std::filesystem::path(filepath)) + if (slot.mPath == filepath) { - loadGame(&character, slot.mPath.string()); + loadGame(&character, slot.mPath); return; } } @@ -382,13 +382,13 @@ void MWState::StateManager::loadGame(const std::string& filepath) loadGame(character, filepath); } -void MWState::StateManager::loadGame (const Character *character, const std::string& filepath) +void MWState::StateManager::loadGame (const Character *character, const std::filesystem::path &filepath) { try { cleanup(); - Log(Debug::Info) << "Reading save file " << std::filesystem::path(filepath).filename().string(); + Log(Debug::Info) << "Reading save file " << filepath.filename(); //TODO(Project579): This will probably break in windows with unicode paths ESM::ESMReader reader; reader.open (filepath); @@ -521,7 +521,7 @@ void MWState::StateManager::loadGame (const Character *character, const std::str if (character) Settings::Manager::setString ("character", "Saves", - character->getPath().filename().string()); + character->getPath().filename().string()); //TODO(Project579): let's hope unicode characters are never used in these filenames on windows or this will break MWBase::Environment::get().getWindowManager()->setNewGame(false); MWBase::Environment::get().getWorld()->saveLoaded(); @@ -593,7 +593,7 @@ void MWState::StateManager::quickLoad() { if (currentCharacter->begin() == currentCharacter->end()) return; - loadGame (currentCharacter, currentCharacter->begin()->mPath.string()); //Get newest save + loadGame (currentCharacter, currentCharacter->begin()->mPath); //Get newest save } } @@ -632,7 +632,7 @@ void MWState::StateManager::update (float duration) //Load last saved game for current character MWState::Slot lastSave = *curCharacter->begin(); - loadGame(curCharacter, lastSave.mPath.string()); + loadGame(curCharacter, lastSave.mPath); } else if(iButton==1) { diff --git a/apps/openmw/mwstate/statemanagerimp.hpp b/apps/openmw/mwstate/statemanagerimp.hpp index ae1b592cfe..0097a9c490 100644 --- a/apps/openmw/mwstate/statemanagerimp.hpp +++ b/apps/openmw/mwstate/statemanagerimp.hpp @@ -66,12 +66,12 @@ namespace MWState /** Used for quickload **/ void quickLoad() override; - void loadGame (const std::string& filepath) override; + void loadGame (const std::filesystem::path &filepath) override; ///< Load a saved game directly from the given file path. This will search the CharacterManager /// for a Character containing this save file, and set this Character current if one was found. /// Otherwise, a new Character will be created. - void loadGame (const Character *character, const std::string &filepath) override; + void loadGame (const Character *character, const std::filesystem::path &filepath) override; ///< Load a saved game file belonging to the given character. Character *getCurrentCharacter () override; diff --git a/apps/openmw/mwworld/esmloader.cpp b/apps/openmw/mwworld/esmloader.cpp index 4fe1df72f8..861401d60e 100644 --- a/apps/openmw/mwworld/esmloader.cpp +++ b/apps/openmw/mwworld/esmloader.cpp @@ -22,13 +22,13 @@ void EsmLoader::load(const std::filesystem::path& filepath, int& index, Loading: reader->setEncoder(mEncoder); reader->setIndex(index); - reader->open(filepath.string()); + reader->open(filepath); reader->resolveParentFileIndices(mReaders); assert(reader->getGameFiles().size() == reader->getParentFileIndices().size()); for (std::size_t i = 0, n = reader->getParentFileIndices().size(); i < n; ++i) if (i == static_cast(reader->getIndex())) - throw std::runtime_error("File " + reader->getName() + " asks for parent file " + throw std::runtime_error("File " + reader->getName().string() + " asks for parent file " //TODO(Project579): This will probably break in windows with unicode paths + reader->getGameFiles()[i].name + ", but it is not available or has been loaded in the wrong order. " "Please run the launcher to fix this issue."); @@ -36,8 +36,8 @@ void EsmLoader::load(const std::filesystem::path& filepath, int& index, Loading: mESMVersions[index] = reader->getVer(); mStore.load(*reader, listener, mDialogue); - if (!mMasterFileFormat.has_value() && (Misc::StringUtils::ciEndsWith(reader->getName(), ".esm") - || Misc::StringUtils::ciEndsWith(reader->getName(), ".omwgame"))) + if (!mMasterFileFormat.has_value() && (Misc::StringUtils::ciEndsWith(reader->getName().string(), ".esm") //TODO(Project579): This will probably break in windows with unicode paths + || Misc::StringUtils::ciEndsWith(reader->getName().string(), ".omwgame"))) //TODO(Project579): This will probably break in windows with unicode paths mMasterFileFormat = reader->getFormat(); } diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index 9316dd6c40..d133efd2ac 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -321,13 +321,13 @@ ESM::LuaScriptsCfg ESMStore::getLuaScriptsCfg() const ESM::LuaScriptsCfg cfg; for (const LuaContent& c : mLuaContent) { - if (std::holds_alternative(c)) + if (std::holds_alternative(c)) { // *.omwscripts are intentionally reloaded every time when `getLuaScriptsCfg` is called. // It is important for the `reloadlua` console command. try { - auto file = std::ifstream(std::get(c)); + auto file = std::ifstream(std::get(c)); std::string fileContent(std::istreambuf_iterator(file), {}); LuaUtil::parseOMWScripts(cfg, fileContent); } diff --git a/apps/openmw/mwworld/esmstore.hpp b/apps/openmw/mwworld/esmstore.hpp index a4fcf80303..c5a860a823 100644 --- a/apps/openmw/mwworld/esmstore.hpp +++ b/apps/openmw/mwworld/esmstore.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -159,11 +160,11 @@ namespace MWWorld using LuaContent = std::variant< ESM::LuaScriptsCfg, // data from an omwaddon - std::string>; // path to an omwscripts file + std::filesystem::path>; // path to an omwscripts file std::vector mLuaContent; public: - void addOMWScripts(std::string filePath) { mLuaContent.push_back(std::move(filePath)); } + void addOMWScripts(std::filesystem::path filePath) { mLuaContent.push_back(std::move(filePath)); } ESM::LuaScriptsCfg getLuaScriptsCfg() const; /// \todo replace with SharedIterator diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 1a10a53954..b0828fd69a 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -104,10 +104,10 @@ namespace MWWorld void load(const std::filesystem::path& filepath, int& index, Loading::Listener* listener) override { - const auto it = mLoaders.find(Misc::StringUtils::lowerCase(filepath.extension().string())); + const auto it = mLoaders.find(Misc::StringUtils::lowerCase(filepath.extension().string())); //TODO(Project579): let's hope unicode characters are never used in these extensions on windows or this will break if (it != mLoaders.end()) { - const std::string filename = filepath.filename().string(); + const std::string filename = filepath.filename().string(); //TODO(Project579): let's hope unicode characters are never used in these filenames on windows or this will break Log(Debug::Info) << "Loading content file " << filename; if (listener != nullptr) listener->setLabel(MyGUI::TextIterator::toTagsString(filename)); @@ -116,7 +116,7 @@ namespace MWWorld else { std::string msg("Cannot load file: "); - msg += filepath.string(); + msg += filepath.string(); //TODO(Project579): This will probably break in windows with unicode paths throw std::runtime_error(msg.c_str()); } } @@ -131,7 +131,7 @@ namespace MWWorld OMWScriptsLoader(ESMStore& store) : mStore(store) {} void load(const std::filesystem::path& filepath, int& /*index*/, Loading::Listener* /*listener*/) override { - mStore.addOMWScripts(filepath.string()); + mStore.addOMWScripts(filepath); } }; @@ -156,7 +156,7 @@ namespace MWWorld const std::vector& groundcoverFiles, ToUTF8::Utf8Encoder* encoder, int activationDistanceOverride, const std::string& startCell, const std::string& startupScript, - const std::string& resourcePath, const std::string& userDataPath) + const std::filesystem::path& resourcePath, const std::filesystem::path& userDataPath) : mResourceSystem(resourceSystem), mLocalScripts(mStore), mCells(mStore, mReaders), mSky(true), mGodMode(false), mScriptsEnabled(true), mDiscardMovements(true), mContentFiles (contentFiles), @@ -2964,7 +2964,7 @@ namespace MWWorld for (const std::string &file : content) { std::filesystem::path filename(file); - const Files::MultiDirCollection& col = fileCollections.getCollection(filename.extension().string()); + const Files::MultiDirCollection& col = fileCollections.getCollection(filename.extension().string()); //TODO(Project579): let's hope unicode characters are never used in these extensions on windows or this will break if (col.doesExist(file)) { gameContentLoader.load(col.getPath(file), idx, listener); @@ -3694,9 +3694,9 @@ namespace MWWorld return mPhysics->getHalfExtents(object); } - std::string World::exportSceneGraph(const Ptr &ptr) + std::filesystem::path World::exportSceneGraph(const Ptr& ptr) { - std::string file = mUserDataPath + "/openmw.osgt"; + auto file = mUserDataPath / "openmw.osgt"; if (!ptr.isEmpty()) { mRendering->pagingBlacklistObject(mStore.find(ptr.getCellRef().getRefId()), ptr); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index e6085b7f79..c6bde113f4 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -109,7 +109,7 @@ namespace MWWorld bool mDiscardMovements; std::vector mContentFiles; - std::string mUserDataPath; + std::filesystem::path mUserDataPath; osg::Vec3f mDefaultHalfExtents; DetourNavigator::CollisionShapeType mDefaultActorCollisionShapeType; @@ -203,7 +203,7 @@ namespace MWWorld const std::vector& groundcoverFiles, ToUTF8::Utf8Encoder* encoder, int activationDistanceOverride, const std::string& startCell, const std::string& startupScript, - const std::string& resourcePath, const std::string& userDataPath); + const std::filesystem::path& resourcePath, const std::filesystem::path& userDataPath); virtual ~World(); @@ -730,7 +730,7 @@ namespace MWWorld /// Export scene graph to a file and return the filename. /// \param ptr object to export scene graph for (if empty, export entire scene graph) - std::string exportSceneGraph(const MWWorld::Ptr& ptr) override; + std::filesystem::path exportSceneGraph(const MWWorld::Ptr& ptr) override; /// Preload VFX associated with this effect list void preloadEffects(const ESM::EffectList* effectList) override; diff --git a/apps/openmw_test_suite/esm3/readerscache.cpp b/apps/openmw_test_suite/esm3/readerscache.cpp index 720b66a04f..826b803b8f 100644 --- a/apps/openmw_test_suite/esm3/readerscache.cpp +++ b/apps/openmw_test_suite/esm3/readerscache.cpp @@ -42,7 +42,7 @@ namespace const Files::PathContainer mDataDirs {{std::string(OPENMW_DATA_DIR)}}; const Files::Collections mFileCollections {mDataDirs, true}; const std::string mContentFile = "template.omwgame"; - const std::string mContentFilePath = mFileCollections.getCollection(".omwgame").getPath(mContentFile).string(); + const std::filesystem::path mContentFilePath = mFileCollections.getCollection(".omwgame").getPath(mContentFile); }; TEST_F(ESM3ReadersCacheWithContentFile, shouldKeepOpenReleasedOpenReader) diff --git a/apps/openmw_test_suite/files/hash.cpp b/apps/openmw_test_suite/files/hash.cpp index f8303ac1f3..dcace6b34e 100644 --- a/apps/openmw_test_suite/files/hash.cpp +++ b/apps/openmw_test_suite/files/hash.cpp @@ -27,7 +27,7 @@ namespace TEST(FilesGetHash, shouldClearErrors) { - const std::string fileName = temporaryFilePath("fileName"); + const auto fileName = temporaryFilePath("fileName"); std::string content; std::fill_n(std::back_inserter(content), 1, 'a'); std::istringstream stream(content); @@ -37,7 +37,7 @@ namespace TEST_P(FilesGetHash, shouldReturnHashForStringStream) { - const std::string fileName = temporaryFilePath("fileName"); + const auto fileName = temporaryFilePath("fileName"); std::string content; std::fill_n(std::back_inserter(content), GetParam().mSize, 'a'); std::istringstream stream(content); @@ -50,10 +50,10 @@ namespace std::replace(fileName.begin(), fileName.end(), '/', '_'); std::string content; std::fill_n(std::back_inserter(content), GetParam().mSize, 'a'); - fileName = outputFilePath(fileName); + fileName = outputFilePath(fileName).string(); //TODO(Project579): This will probably break in windows with unicode paths std::fstream(fileName, std::ios_base::out | std::ios_base::binary) .write(content.data(), static_cast(content.size())); - const auto stream = Files::openConstrainedFileStream(fileName, 0, content.size()); + const auto stream = Files::openConstrainedFileStream(fileName, 0, content.size()); //TODO(Project579): This will probably break in windows with unicode paths EXPECT_EQ(getHash(fileName, *stream), GetParam().mHash); } diff --git a/apps/openmw_test_suite/lua/test_storage.cpp b/apps/openmw_test_suite/lua/test_storage.cpp index c1d8cc4c4f..364cb9d3f6 100644 --- a/apps/openmw_test_suite/lua/test_storage.cpp +++ b/apps/openmw_test_suite/lua/test_storage.cpp @@ -88,7 +88,7 @@ namespace mLua.safe_script("permanent:set('x', 1)"); mLua.safe_script("temporary:set('y', 2)"); - std::string tmpFile = (std::filesystem::temp_directory_path() / "test_storage.bin").string(); + const auto tmpFile = std::filesystem::temp_directory_path() / "test_storage.bin"; storage.save(tmpFile); EXPECT_EQ(get(mLua, "permanent:get('x')"), 1); EXPECT_EQ(get(mLua, "temporary:get('y')"), 2); diff --git a/apps/openmw_test_suite/mwworld/test_store.cpp b/apps/openmw_test_suite/mwworld/test_store.cpp index edba8b3d3a..b5fbf5a291 100644 --- a/apps/openmw_test_suite/mwworld/test_store.cpp +++ b/apps/openmw_test_suite/mwworld/test_store.cpp @@ -41,7 +41,7 @@ struct ContentFileTest : public ::testing::Test ESM::ESMReader lEsm; lEsm.setEncoder(nullptr); lEsm.setIndex(index); - lEsm.open(mContentFile.string()); + lEsm.open(mContentFile); mEsmStore.load(lEsm, &dummyListener, dialogue); ++index; @@ -109,7 +109,7 @@ TEST_F(ContentFileTest, dialogue_merging_test) return; } - const std::string file = TestingOpenMW::outputFilePath("test_dialogue_merging.txt"); + const auto file = TestingOpenMW::outputFilePath("test_dialogue_merging.txt"); std::ofstream stream(file); const MWWorld::Store& dialStore = mEsmStore.get(); @@ -124,7 +124,7 @@ TEST_F(ContentFileTest, dialogue_merging_test) stream << std::endl; } - std::cout << "dialogue_merging_test successful, results printed to " << file << std::endl; + std::cout << "dialogue_merging_test successful, results printed to " << file << std::endl; //TODO(Project579): This will probably break in windows with unicode paths } // Note: here we don't test records that don't use string names (e.g. Land, Pathgrid, Cell) @@ -189,12 +189,12 @@ TEST_F(ContentFileTest, content_diagnostics_test) return; } - const std::string file = TestingOpenMW::outputFilePath("test_content_diagnostics.txt"); + const auto file = TestingOpenMW::outputFilePath("test_content_diagnostics.txt"); std::ofstream stream(file); RUN_TEST_FOR_TYPES(printRecords, mEsmStore, stream); - std::cout << "diagnostics_test successful, results printed to " << file << std::endl; + std::cout << "diagnostics_test successful, results printed to " << file << std::endl; //TODO(Project579): This will probably break in windows with unicode paths } // TODO: diff --git a/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp b/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp index 5c368b4e7e..b2570f7704 100644 --- a/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp +++ b/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp @@ -353,7 +353,7 @@ namespace MOCK_METHOD(std::string, getString, (uint32_t), (const, override)); MOCK_METHOD(void, setUseSkinning, (bool), (override)); MOCK_METHOD(bool, getUseSkinning, (), (const, override)); - MOCK_METHOD(std::string, getFilename, (), (const, override)); + MOCK_METHOD(std::filesystem::path, getFilename, (), (const, override)); MOCK_METHOD(std::string, getHash, (), (const, override)); MOCK_METHOD(unsigned int, getVersion, (), (const, override)); MOCK_METHOD(unsigned int, getUserVersion, (), (const, override)); diff --git a/apps/openmw_test_suite/settings/parser.cpp b/apps/openmw_test_suite/settings/parser.cpp index 7e250b43aa..33d6b24ded 100644 --- a/apps/openmw_test_suite/settings/parser.cpp +++ b/apps/openmw_test_suite/settings/parser.cpp @@ -19,7 +19,7 @@ namespace template void withSettingsFile( const std::string& content, F&& f) { - std::string path = TestingOpenMW::outputFilePath( + auto path = TestingOpenMW::outputFilePath( std::string(UnitTest::GetInstance()->current_test_info()->name()) + ".cfg"); { diff --git a/apps/openmw_test_suite/settings/shadermanager.cpp b/apps/openmw_test_suite/settings/shadermanager.cpp index e4f40aaa03..1ed3e7a48c 100644 --- a/apps/openmw_test_suite/settings/shadermanager.cpp +++ b/apps/openmw_test_suite/settings/shadermanager.cpp @@ -17,7 +17,7 @@ namespace template void withSettingsFile( const std::string& content, F&& f) { - std::string path = TestingOpenMW::outputFilePath( + auto path = TestingOpenMW::outputFilePath( std::string(UnitTest::GetInstance()->current_test_info()->name()) + ".yaml"); { @@ -69,4 +69,4 @@ config: EXPECT_FALSE(ShaderManager::get().save()); }); } -} \ No newline at end of file +} diff --git a/apps/openmw_test_suite/shader/shadermanager.cpp b/apps/openmw_test_suite/shader/shadermanager.cpp index 58ca3b6f3f..9e4808b073 100644 --- a/apps/openmw_test_suite/shader/shadermanager.cpp +++ b/apps/openmw_test_suite/shader/shadermanager.cpp @@ -30,7 +30,7 @@ namespace template void withShaderFile(const std::string& suffix, const std::string& content, F&& f) { - std::string path = TestingOpenMW::outputFilePath( + auto path = TestingOpenMW::outputFilePath( std::string(UnitTest::GetInstance()->current_test_info()->name()) + suffix + ".glsl"); { @@ -47,8 +47,8 @@ namespace { const std::string content; - withShaderFile(content, [this] (const std::string& templateName) { - EXPECT_TRUE(mManager.getShader(templateName, {}, osg::Shader::VERTEX)); + withShaderFile(content, [this] (const std::filesystem::path& templateName) { + EXPECT_TRUE(mManager.getShader(templateName.string(), {}, osg::Shader::VERTEX)); //TODO(Project579): This will probably break in windows with unicode paths }); } @@ -58,8 +58,8 @@ namespace "#version 120\n" "void main() {}\n"; - withShaderFile(content, [&] (const std::string& templateName) { - const auto shader = mManager.getShader(templateName, mDefines, osg::Shader::VERTEX); + withShaderFile(content, [&] (const std::filesystem::path& templateName) { + const auto shader = mManager.getShader(templateName.string(), mDefines, osg::Shader::VERTEX); //TODO(Project579): This will probably break in windows with unicode paths ASSERT_TRUE(shader); EXPECT_EQ(shader->getShaderSource(), content); }); @@ -70,19 +70,19 @@ namespace const std::string content0 = "void foo() {}\n"; - withShaderFile("_0", content0, [&] (const std::string& templateName0) { + withShaderFile("_0", content0, [&] (const std::filesystem::path& templateName0) { const std::string content1 = - "#include \"" + templateName0 + "\"\n" + "#include \"" + templateName0.string() + "\"\n" //TODO(Project579): This will probably break in windows with unicode paths "void bar() { foo() }\n"; - withShaderFile("_1", content1, [&] (const std::string& templateName1) { + withShaderFile("_1", content1, [&] (const std::filesystem::path& templateName1) { const std::string content2 = "#version 120\n" - "#include \"" + templateName1 + "\"\n" + "#include \"" + templateName1.string() + "\"\n" //TODO(Project579): This will probably break in windows with unicode paths "void main() { bar() }\n"; - withShaderFile(content2, [&] (const std::string& templateName2) { - const auto shader = mManager.getShader(templateName2, mDefines, osg::Shader::VERTEX); + withShaderFile(content2, [&] (const std::filesystem::path& templateName2) { + const auto shader = mManager.getShader(templateName2.string(), mDefines, osg::Shader::VERTEX); //TODO(Project579): This will probably break in windows with unicode paths ASSERT_TRUE(shader); const std::string expected = "#version 120\n" @@ -111,9 +111,9 @@ namespace "void main() {}\n" ; - withShaderFile(content, [&] (const std::string& templateName) { + withShaderFile(content, [&] (const std::filesystem::path& templateName) { mDefines["flag"] = "1"; - const auto shader = mManager.getShader(templateName, mDefines, osg::Shader::VERTEX); + const auto shader = mManager.getShader(templateName.string(), mDefines, osg::Shader::VERTEX); //TODO(Project579): This will probably break in windows with unicode paths ASSERT_TRUE(shader); const std::string expected = "#version 120\n" @@ -133,9 +133,9 @@ namespace "void main() {}\n" ; - withShaderFile(content, [&] (const std::string& templateName) { + withShaderFile(content, [&] (const std::filesystem::path& templateName) { mDefines["list"] = "1,2,3"; - const auto shader = mManager.getShader(templateName, mDefines, osg::Shader::VERTEX); + const auto shader = mManager.getShader(templateName.string(), mDefines, osg::Shader::VERTEX); //TODO(Project579): This will probably break in windows with unicode paths ASSERT_TRUE(shader); const std::string expected = "#version 120\n" @@ -174,9 +174,9 @@ namespace "}\n" ; - withShaderFile(content, [&] (const std::string& templateName) { + withShaderFile(content, [&] (const std::filesystem::path& templateName) { mDefines["list"] = "1,2,3"; - const auto shader = mManager.getShader(templateName, mDefines, osg::Shader::VERTEX); + const auto shader = mManager.getShader(templateName.string(), mDefines, osg::Shader::VERTEX); //TODO(Project579): This will probably break in windows with unicode paths ASSERT_TRUE(shader); const std::string expected = "#version 120\n" @@ -222,8 +222,8 @@ namespace "void main() {}\n" ; - withShaderFile(content, [&] (const std::string& templateName) { - EXPECT_FALSE(mManager.getShader(templateName, mDefines, osg::Shader::VERTEX)); + withShaderFile(content, [&] (const std::filesystem::path& templateName) { + EXPECT_FALSE(mManager.getShader(templateName.string(), mDefines, osg::Shader::VERTEX)); //TODO(Project579): This will probably break in windows with unicode paths }); } @@ -235,8 +235,8 @@ namespace "void main() {}\n" ; - withShaderFile(content, [&] (const std::string& templateName) { - EXPECT_FALSE(mManager.getShader(templateName, mDefines, osg::Shader::VERTEX)); + withShaderFile(content, [&] (const std::filesystem::path& templateName) { + EXPECT_FALSE(mManager.getShader(templateName.string(), mDefines, osg::Shader::VERTEX)); //TODO(Project579): This will probably break in windows with unicode paths }); } } diff --git a/apps/openmw_test_suite/testing_util.hpp b/apps/openmw_test_suite/testing_util.hpp index 125d2505ed..7b6b008501 100644 --- a/apps/openmw_test_suite/testing_util.hpp +++ b/apps/openmw_test_suite/testing_util.hpp @@ -10,16 +10,16 @@ namespace TestingOpenMW { - inline std::string outputFilePath(const std::string name) + inline std::filesystem::path outputFilePath(const std::string name) { std::filesystem::path dir("tests_output"); std::filesystem::create_directory(dir); - return (dir / name).string(); + return dir / name; } - inline std::string temporaryFilePath(const std::string name) + inline std::filesystem::path temporaryFilePath(const std::string name) { - return (std::filesystem::temp_directory_path() / name).string(); + return std::filesystem::temp_directory_path() / name; } class VFSTestFile : public VFS::File @@ -32,7 +32,7 @@ namespace TestingOpenMW return std::make_unique(mContent, std::ios_base::in); } - std::string getPath() override + std::filesystem::path getPath() override { return "TestFile"; } diff --git a/apps/wizard/installationtargetpage.cpp b/apps/wizard/installationtargetpage.cpp index f55794ccaf..0a41d57f14 100644 --- a/apps/wizard/installationtargetpage.cpp +++ b/apps/wizard/installationtargetpage.cpp @@ -19,7 +19,7 @@ Wizard::InstallationTargetPage::InstallationTargetPage(QWidget *parent, const Fi void Wizard::InstallationTargetPage::initializePage() { - QString path(QFile::decodeName(mCfgMgr.getUserDataPath().string().c_str())); + QString path(QFile::decodeName(mCfgMgr.getUserDataPath().string().c_str())); //TODO(Project579): This will probably break in windows with unicode paths path.append(QDir::separator() + QLatin1String("basedata")); QDir dir(path); diff --git a/apps/wizard/mainwizard.cpp b/apps/wizard/mainwizard.cpp index 9544ccfbee..a597b11df8 100644 --- a/apps/wizard/mainwizard.cpp +++ b/apps/wizard/mainwizard.cpp @@ -471,5 +471,5 @@ bool Wizard::MainWizard::findFiles(const QString &name, const QString &path) QString Wizard::MainWizard::toQString(const std::filesystem::path& path) { - return QString::fromUtf8(path.string().c_str()); + return QString::fromUtf8(path.string().c_str()); //TODO(Project579): This will probably break in windows with unicode paths } diff --git a/components/bsa/bsa_file.cpp b/components/bsa/bsa_file.cpp index 9fc6448c2b..65d184cf75 100644 --- a/components/bsa/bsa_file.cpp +++ b/components/bsa/bsa_file.cpp @@ -37,7 +37,7 @@ using namespace Bsa; /// Error handling [[noreturn]] void BSAFile::fail(const std::string &msg) { - throw std::runtime_error("BSA Error: " + msg + "\nArchive: " + mFilename); + throw std::runtime_error("BSA Error: " + msg + "\nArchive: " + mFilepath.string()); //TODO(Project579): This will probably break in windows with unicode paths } //the getHash code is from bsapack from ghostwheel @@ -100,7 +100,7 @@ void BSAFile::readHeader() */ assert(!mIsLoaded); - std::ifstream input(std::filesystem::path(mFilename), std::ios_base::binary); + std::ifstream input(mFilepath, std::ios_base::binary); // Total archive size std::streamoff fsize = 0; @@ -196,7 +196,7 @@ void BSAFile::readHeader() /// Write header information to the output sink void Bsa::BSAFile::writeHeader() { - std::fstream output(mFilename, std::ios::binary | std::ios::in | std::ios::out); + std::fstream output(mFilepath, std::ios::binary | std::ios::in | std::ios::out); uint32_t head[3]; head[0] = 0x100; @@ -231,17 +231,17 @@ void Bsa::BSAFile::writeHeader() } /// Open an archive file. -void BSAFile::open(const std::string &file) +void BSAFile::open(const std::filesystem::path &file) { if (mIsLoaded) close(); - mFilename = file; + mFilepath = file; if(std::filesystem::exists(file)) readHeader(); else { - { std::fstream(mFilename, std::ios::binary | std::ios::out); } + { std::fstream(mFilepath, std::ios::binary | std::ios::out); } writeHeader(); mIsLoaded = true; } @@ -270,9 +270,9 @@ void Bsa::BSAFile::addFile(const std::string& filename, std::istream& file) auto newStartOfDataBuffer = 12 + (12 + 8) * (mFiles.size() + 1) + mStringBuf.size() + filename.size() + 1; if (mFiles.empty()) - std::filesystem::resize_file(mFilename, newStartOfDataBuffer); + std::filesystem::resize_file(mFilepath, newStartOfDataBuffer); - std::fstream stream(mFilename, std::ios::binary | std::ios::in | std::ios::out); + std::fstream stream(mFilepath, std::ios::binary | std::ios::in | std::ios::out); FileStruct newFile; file.seekg(0, std::ios::end); diff --git a/components/bsa/bsa_file.hpp b/components/bsa/bsa_file.hpp index f6af2e3269..d01fb6d421 100644 --- a/components/bsa/bsa_file.hpp +++ b/components/bsa/bsa_file.hpp @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -85,7 +86,7 @@ protected: bool mIsLoaded; /// Used for error messages - std::string mFilename; + std::filesystem::path mFilepath; /// Error handling [[noreturn]] void fail(const std::string &msg); @@ -110,7 +111,7 @@ public: } /// Open an archive file. - void open(const std::string &file); + void open(const std::filesystem::path &file); void close(); @@ -131,9 +132,9 @@ public: const FileList &getList() const { return mFiles; } - const std::string& getFilename() const + std::string getFilename() const { - return mFilename; + return mFilepath.string(); //TODO(Project579): This will probably break in windows with unicode paths } }; diff --git a/components/bsa/compressedbsafile.cpp b/components/bsa/compressedbsafile.cpp index 2d553b0986..337570cad1 100644 --- a/components/bsa/compressedbsafile.cpp +++ b/components/bsa/compressedbsafile.cpp @@ -119,7 +119,7 @@ void CompressedBSAFile::readHeader() { assert(!mIsLoaded); - std::ifstream input(std::filesystem::path(mFilename), std::ios_base::binary); + std::ifstream input(mFilepath, std::ios_base::binary); // Total archive size std::streamoff fsize = 0; @@ -299,17 +299,22 @@ void CompressedBSAFile::readHeader() CompressedBSAFile::FileRecord CompressedBSAFile::getFileRecord(const std::string& str) const { - // Force-convert the path into something both Windows and UNIX can handle first - // to make sure Boost doesn't think the entire path is the filename on Linux +#ifdef _WIN32 + const auto& path = str; +#else + // Force-convert the path into something UNIX can handle first + // to make sure std::filesystem::path doesn't think the entire path is the filename on Linux // and subsequently purge it to determine the file folder. std::string path = str; std::replace(path.begin(), path.end(), '\\', '/'); +#endif std::filesystem::path p(path); std::string stem = p.stem().string(); std::string ext = p.extension().string(); - - std::string folder = p.parent_path().string(); + p.remove_filename(); + + std::string folder = p.string(); std::uint64_t folderHash = generateHash(folder, std::string()); auto it = mFolders.find(folderHash); diff --git a/components/bsa/compressedbsafile.hpp b/components/bsa/compressedbsafile.hpp index 2c0b3c0aac..53dcf8f522 100644 --- a/components/bsa/compressedbsafile.hpp +++ b/components/bsa/compressedbsafile.hpp @@ -29,6 +29,7 @@ #include #include +#include namespace Bsa { @@ -82,7 +83,7 @@ namespace Bsa //mFiles used by OpenMW will contain uncompressed file sizes void convertCompressedSizesToUncompressed(); /// \brief Normalizes given filename or folder and generates format-compatible hash. See https://en.uesp.net/wiki/Tes4Mod:Hash_Calculation. - static std::uint64_t generateHash(std::string stem, std::string extension) ; + static std::uint64_t generateHash(std::filesystem::path stem, std::string extension) ; Files::IStreamPtr getFile(const FileRecord& fileRecord); public: using BSAFile::open; @@ -93,7 +94,7 @@ namespace Bsa virtual ~CompressedBSAFile(); //checks version of BSA from file header - static BsaVersion detectVersion(const std::string& filePath); + static BsaVersion detectVersion(const std::filesystem::path &filePath); /// Read header information from the input source void readHeader() override; diff --git a/components/config/gamesettings.cpp b/components/config/gamesettings.cpp index aa63c3191e..0fe36720f5 100644 --- a/components/config/gamesettings.cpp +++ b/components/config/gamesettings.cpp @@ -32,7 +32,7 @@ void Config::GameSettings::validatePaths() mDataDirs.clear(); for (auto & dataDir : dataDirs) { - QString path = QString::fromUtf8(dataDir.string().c_str()); + QString path = QString::fromUtf8(dataDir.string().c_str()); //TODO(Project579): This will probably break in windows with unicode paths QDir dir(path); if (dir.exists()) @@ -57,7 +57,7 @@ void Config::GameSettings::validatePaths() mCfgMgr.processPaths(dataDirs, /*basePath=*/""); if (!dataDirs.empty()) { - QString path = QString::fromUtf8(dataDirs.front().string().c_str()); + QString path = QString::fromUtf8(dataDirs.front().string().c_str()); //TODO(Project579): This will probably break in windows with unicode paths QDir dir(path); if (dir.exists()) @@ -65,11 +65,11 @@ void Config::GameSettings::validatePaths() } } -std::string Config::GameSettings::getGlobalDataDir() const +std::filesystem::path Config::GameSettings::getGlobalDataDir() const { // global data dir may not exists if OpenMW is not installed (ie if run from build directory) if (std::filesystem::exists(mCfgMgr.getGlobalDataPath())) - return std::filesystem::canonical(mCfgMgr.getGlobalDataPath()).string(); + return std::filesystem::canonical(mCfgMgr.getGlobalDataPath()); return {}; } diff --git a/components/config/gamesettings.hpp b/components/config/gamesettings.hpp index 961af7657b..c40cc92617 100644 --- a/components/config/gamesettings.hpp +++ b/components/config/gamesettings.hpp @@ -54,7 +54,7 @@ namespace Config } QStringList getDataDirs() const; - std::string getGlobalDataDir() const; + std::filesystem::path getGlobalDataDir() const; inline void removeDataDir(const QString &dir) { if(!dir.isEmpty()) mDataDirs.removeAll(dir); } inline void addDataDir(const QString &dir) { if(!dir.isEmpty()) mDataDirs.append(dir); } diff --git a/components/config/launchersettings.cpp b/components/config/launchersettings.cpp index 11ced3c145..129d04dcc1 100644 --- a/components/config/launchersettings.cpp +++ b/components/config/launchersettings.cpp @@ -119,7 +119,7 @@ void Config::LauncherSettings::setContentList(const GameSettings& gameSettings) } // global and local data directories are not part of any profile - const auto globalDataDir = QString(gameSettings.getGlobalDataDir().c_str()); + const auto globalDataDir = QString(gameSettings.getGlobalDataDir().string().c_str()); //TODO(Project579): This will probably break in windows with unicode paths const auto dataLocal = gameSettings.getDataLocal(); dirs.removeAll(globalDataDir); dirs.removeAll(dataLocal); diff --git a/components/crashcatcher/crashcatcher.cpp b/components/crashcatcher/crashcatcher.cpp index 65924a0d62..fa45fc259b 100644 --- a/components/crashcatcher/crashcatcher.cpp +++ b/components/crashcatcher/crashcatcher.cpp @@ -559,7 +559,7 @@ static bool is_debugger_present() #endif } -void crashCatcherInstall(int argc, char **argv, const std::string &crashLogPath) +void crashCatcherInstall(int argc, char **argv, const std::filesystem::path &crashLogPath) { if ((argc == 2 && strcmp(argv[1], crash_switch) == 0) || !is_debugger_present()) { diff --git a/components/crashcatcher/crashcatcher.hpp b/components/crashcatcher/crashcatcher.hpp index b693ccae43..b029c5460b 100644 --- a/components/crashcatcher/crashcatcher.hpp +++ b/components/crashcatcher/crashcatcher.hpp @@ -12,7 +12,7 @@ constexpr char crash_switch[] = "--cc-handle-crash"; #if USE_CRASH_CATCHER -extern void crashCatcherInstall(int argc, char **argv, const std::string &crashLogPath); +extern void crashCatcherInstall(int argc, char **argv, const std::filesystem::path &crashLogPath); #else inline void crashCatcherInstall(int, char **, const std::string &crashLogPath) { diff --git a/components/crashcatcher/windows_crashcatcher.cpp b/components/crashcatcher/windows_crashcatcher.cpp index d31fdac578..c62a066c59 100644 --- a/components/crashcatcher/windows_crashcatcher.cpp +++ b/components/crashcatcher/windows_crashcatcher.cpp @@ -9,6 +9,8 @@ #include "windows_crashshm.hpp" #include +#include + namespace Crash { @@ -26,7 +28,7 @@ namespace Crash CrashCatcher* CrashCatcher::sInstance = nullptr; - CrashCatcher::CrashCatcher(int argc, char **argv, const std::string& crashLogPath) + CrashCatcher::CrashCatcher(int argc, char **argv, const std::filesystem::path& crashLogPath) { assert(sInstance == nullptr); // don't allow two instances @@ -124,7 +126,7 @@ namespace Crash SetUnhandledExceptionFilter(vectoredExceptionHandler); } - void CrashCatcher::startMonitorProcess(const std::string& crashLogPath) + void CrashCatcher::startMonitorProcess(const std::filesystem::path& crashLogPath) { std::wstring executablePath; DWORD copied = 0; @@ -135,9 +137,10 @@ namespace Crash executablePath.resize(copied); memset(mShm->mStartup.mLogFilePath, 0, sizeof(mShm->mStartup.mLogFilePath)); - size_t length = crashLogPath.length(); + const auto str = crashLogPath.u8string(); + size_t length = str.length(); if (length >= MAX_LONG_PATH) length = MAX_LONG_PATH - 1; - strncpy(mShm->mStartup.mLogFilePath, crashLogPath.c_str(), length); + strncpy_s(mShm->mStartup.mLogFilePath, sizeof mShm->mStartup.mLogFilePath, Misc::StringUtils::char8_to_char(str.c_str()), length); //TODO(Project579): This will probably break in windows with unicode paths mShm->mStartup.mLogFilePath[length] = '\0'; // note that we don't need to lock the SHM here, the other process has not started yet diff --git a/components/crashcatcher/windows_crashcatcher.hpp b/components/crashcatcher/windows_crashcatcher.hpp index 1133afe69c..4379b34d71 100644 --- a/components/crashcatcher/windows_crashcatcher.hpp +++ b/components/crashcatcher/windows_crashcatcher.hpp @@ -1,7 +1,7 @@ #ifndef WINDOWS_CRASHCATCHER_HPP #define WINDOWS_CRASHCATCHER_HPP -#include +#include #include #include @@ -28,7 +28,7 @@ namespace Crash { public: - CrashCatcher(int argc, char **argv, const std::string& crashLogPath); + CrashCatcher(int argc, char **argv, const std::filesystem::path& crashLogPath); ~CrashCatcher(); private: @@ -56,7 +56,7 @@ namespace Crash void shmUnlock(); - void startMonitorProcess(const std::string& crashLogPath); + void startMonitorProcess(const std::filesystem::path& crashLogPath); void waitMonitor(); diff --git a/components/debug/debugging.cpp b/components/debug/debugging.cpp index 01dcde7bcc..e6f159bf81 100644 --- a/components/debug/debugging.cpp +++ b/components/debug/debugging.cpp @@ -269,7 +269,7 @@ Misc::Locked getLockedRawStderr() } // Redirect cout and cerr to the log file -void setupLogging(const std::string& logDir, const std::string& appName, std::ios_base::openmode mode) +void setupLogging(const std::filesystem::path &logDir, const std::string& appName, std::ios_base::openmode mode) { #if defined(_WIN32) && defined(_DEBUG) // Redirect cout and cerr to VS debug output when running in debug mode @@ -278,7 +278,7 @@ void setupLogging(const std::string& logDir, const std::string& appName, std::io std::cerr.rdbuf(&sb); #else const std::string logName = Misc::StringUtils::lowerCase(appName) + ".log"; - logfile.open(std::filesystem::path(logDir) / logName, mode); + logfile.open(logDir / logName, mode); coutsb.open(Debug::Tee(logfile, *rawStdout)); cerrsb.open(Debug::Tee(logfile, *rawStderr)); @@ -311,7 +311,7 @@ int wrapApplication(int (*innerApplication)(int argc, char *argv[]), int argc, c if (argc == 2 && strcmp(argv[1], crash_switch) == 0) mode |= std::ios::app; - setupLogging(cfgMgr.getLogPath().string(), appName, mode); + setupLogging(cfgMgr.getLogPath(), appName, mode); } if (const auto env = std::getenv("OPENMW_DISABLE_CRASH_CATCHER"); env == nullptr || std::atol(env) == 0) diff --git a/components/debug/debugging.hpp b/components/debug/debugging.hpp index a250c5d837..c144000d3f 100644 --- a/components/debug/debugging.hpp +++ b/components/debug/debugging.hpp @@ -34,7 +34,7 @@ std::ostream& getRawStderr(); Misc::Locked getLockedRawStderr(); -void setupLogging(const std::string& logDir, const std::string& appName, std::ios_base::openmode = std::ios::out); +void setupLogging(const std::filesystem::path &logDir, const std::string& appName, std::ios_base::openmode mode = std::ios::out); int wrapApplication(int (*innerApplication)(int argc, char *argv[]), int argc, char *argv[], const std::string& appName, bool autoSetupLogging = true); diff --git a/components/detournavigator/navigator.cpp b/components/detournavigator/navigator.cpp index d40f330771..200582216d 100644 --- a/components/detournavigator/navigator.cpp +++ b/components/detournavigator/navigator.cpp @@ -7,7 +7,7 @@ namespace DetourNavigator { - std::unique_ptr makeNavigator(const Settings& settings, const std::string& userDataPath) + std::unique_ptr makeNavigator(const Settings& settings, const std::filesystem::path& userDataPath) { DetourNavigator::RecastGlobalAllocator::init(); @@ -16,7 +16,7 @@ namespace DetourNavigator { try { - db = std::make_unique(userDataPath + "/navmesh.db", settings.mMaxDbFileSize); + db = std::make_unique((userDataPath / "navmesh.db").string(), settings.mMaxDbFileSize); //TODO(Project579): This will probably break in windows with unicode paths } catch (const std::exception& e) { diff --git a/components/detournavigator/navigator.hpp b/components/detournavigator/navigator.hpp index f78ce30c2b..f561f38cda 100644 --- a/components/detournavigator/navigator.hpp +++ b/components/detournavigator/navigator.hpp @@ -1,6 +1,8 @@ #ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVIGATOR_H #define OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVIGATOR_H +#include + #include "objectid.hpp" #include "sharednavmeshcacheitem.hpp" #include "recastmeshtiles.hpp" @@ -10,7 +12,6 @@ #include -#include namespace ESM { @@ -195,7 +196,7 @@ namespace DetourNavigator virtual float getMaxNavmeshAreaRealRadius() const = 0; }; - std::unique_ptr makeNavigator(const Settings& settings, const std::string& userDataPath); + std::unique_ptr makeNavigator(const Settings& settings, const std::filesystem::path& userDataPath); std::unique_ptr makeNavigatorStub(); } diff --git a/components/esm/esmcommon.hpp b/components/esm/esmcommon.hpp index 35c659fb7e..9d57a7304d 100644 --- a/components/esm/esmcommon.hpp +++ b/components/esm/esmcommon.hpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace ESM { @@ -187,7 +188,7 @@ static_assert(sizeof(NAME64) == 64); */ struct ESM_Context { - std::string filename; + std::filesystem::path filename; uint32_t leftRec, leftSub; size_t leftFile; NAME recName, subName; diff --git a/components/esm3/esmreader.cpp b/components/esm3/esmreader.cpp index 84acd193f9..5877951d43 100644 --- a/components/esm3/esmreader.cpp +++ b/components/esm3/esmreader.cpp @@ -73,8 +73,7 @@ void ESMReader::resolveParentFileIndices(ReadersCache& readers) const ESM::ReadersCache::BusyItem reader = readers.get(static_cast(i)); if (reader->getFileSize() == 0) continue; // Content file in non-ESM format - const std::string& candidate = reader->getName(); - std::string fnamecandidate = std::filesystem::path(candidate).filename().string(); + std::string fnamecandidate = reader->getName().filename().string(); //TODO(Project579): let's hope unicode characters are never used in these filenames on windows or this will break if (Misc::StringUtils::ciEqual(fname, fnamecandidate)) { index = i; @@ -85,7 +84,7 @@ void ESMReader::resolveParentFileIndices(ReadersCache& readers) } } -void ESMReader::openRaw(std::unique_ptr&& stream, std::string_view name) +void ESMReader::openRaw(std::unique_ptr&& stream, const std::filesystem::path &name) { close(); mEsm = std::move(stream); @@ -95,12 +94,12 @@ void ESMReader::openRaw(std::unique_ptr&& stream, std::string_view mEsm->seekg(0, mEsm->beg); } -void ESMReader::openRaw(std::string_view filename) +void ESMReader::openRaw(const std::filesystem::path &filename) { - openRaw(Files::openBinaryInputFileStream(std::string(filename)), filename); + openRaw(Files::openBinaryInputFileStream(filename), filename); } -void ESMReader::open(std::unique_ptr&& stream, const std::string &name) +void ESMReader::open(std::unique_ptr&& stream, const std::filesystem::path &name) { openRaw(std::move(stream), name); @@ -112,7 +111,7 @@ void ESMReader::open(std::unique_ptr&& stream, const std::string & mHeader.load (*this); } -void ESMReader::open(const std::string &file) +void ESMReader::open(const std::filesystem::path &file) { open(Files::openBinaryInputFileStream(file), file); } @@ -360,7 +359,7 @@ std::string ESMReader::getString(int size) std::stringstream ss; ss << "ESM Error: " << msg; - ss << "\n File: " << mCtx.filename; + ss << "\n File: " << mCtx.filename; //TODO(Project579): This will probably break in windows with unicode paths ss << "\n Record: " << mCtx.recName.toStringView(); ss << "\n Subrecord: " << mCtx.subName.toStringView(); if (mEsm.get()) diff --git a/components/esm3/esmreader.hpp b/components/esm3/esmreader.hpp index 5a58e9d165..521c1fc75d 100644 --- a/components/esm3/esmreader.hpp +++ b/components/esm3/esmreader.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -38,7 +39,7 @@ public: int getFormat() const { return mHeader.mFormat; }; const NAME &retSubName() const { return mCtx.subName; } uint32_t getSubSize() const { return mCtx.leftSub; } - const std::string& getName() const { return mCtx.filename; }; + const std::filesystem::path& getName() const { return mCtx.filename; }; bool isOpen() const { return mEsm != nullptr; } /************************************************************************* @@ -62,15 +63,15 @@ public: /// Raw opening. Opens the file and sets everything up but doesn't /// parse the header. - void openRaw(std::unique_ptr&& stream, std::string_view name); + void openRaw(std::unique_ptr&& stream, const std::filesystem::path &name); /// Load ES file from a new stream, parses the header. Closes the /// currently open file first, if any. - void open(std::unique_ptr&& stream, const std::string &name); + void open(std::unique_ptr&& stream, const std::filesystem::path &name); - void open(const std::string &file); + void open(const std::filesystem::path &file); - void openRaw(std::string_view filename); + void openRaw(const std::filesystem::path &filename); /// Get the current position in the file. Make sure that the file has been opened! size_t getFileOffset() const { return mEsm->tellg(); }; diff --git a/components/esm3/loadcell.cpp b/components/esm3/loadcell.cpp index dc32ee6a43..2d92bf561e 100644 --- a/components/esm3/loadcell.cpp +++ b/components/esm3/loadcell.cpp @@ -131,7 +131,7 @@ namespace ESM { if(!overriding) mWater = std::numeric_limits::max(); - Log(Debug::Warning) << "Warning: Encountered invalid water level in cell " << mName << " defined in " << esm.getContext().filename; + Log(Debug::Warning) << "Warning: Encountered invalid water level in cell " << mName << " defined in " << esm.getContext().filename; //TODO(Project579): This will probably break in windows with unicode paths } else mWater = waterLevel; diff --git a/components/esm3/readerscache.hpp b/components/esm3/readerscache.hpp index 16511efdd7..df14bb6a8a 100644 --- a/components/esm3/readerscache.hpp +++ b/components/esm3/readerscache.hpp @@ -25,7 +25,7 @@ namespace ESM { State mState = State::Busy; ESMReader mReader; - std::optional mName; + std::optional mName; Item() = default; }; diff --git a/components/esm4/reader.cpp b/components/esm4/reader.cpp index b7179ef125..4a8e908913 100644 --- a/components/esm4/reader.cpp +++ b/components/esm4/reader.cpp @@ -67,7 +67,7 @@ ReaderContext::ReaderContext() : modIndex(0), recHeaderSize(sizeof(RecordHeader) subRecordHeader.dataSize = 0; } -Reader::Reader(Files::IStreamPtr&& esmStream, const std::string& filename) +Reader::Reader(Files::IStreamPtr&& esmStream, const std::filesystem::path &filename) : mEncoder(nullptr), mFileSize(0), mStream(std::move(esmStream)) { // used by ESMReader only? @@ -150,7 +150,7 @@ void Reader::close() //mHeader.blank(); } -void Reader::openRaw(Files::IStreamPtr&& stream, const std::string& filename) +void Reader::openRaw(Files::IStreamPtr&& stream, const std::filesystem::path &filename) { close(); @@ -163,7 +163,7 @@ void Reader::openRaw(Files::IStreamPtr&& stream, const std::string& filename) } -void Reader::open(Files::IStreamPtr&& stream, const std::string &filename) +void Reader::open(Files::IStreamPtr&& stream, const std::filesystem::path &filename) { openRaw(std::move(stream), filename); @@ -199,21 +199,20 @@ void Reader::setRecHeaderSize(const std::size_t size) mCtx.recHeaderSize = size; } -// FIXME: only "English" strings supported for now void Reader::buildLStringIndex() { if ((mHeader.mFlags & Rec_ESM) == 0 || (mHeader.mFlags & Rec_Localized) == 0) return; - std::filesystem::path p(mCtx.filename); - std::string filename = p.stem().filename().string(); + const auto filename = mCtx.filename.stem().filename().u8string(); - buildLStringIndex("Strings/" + filename + "_English.STRINGS", Type_Strings); - buildLStringIndex("Strings/" + filename + "_English.ILSTRINGS", Type_ILStrings); - buildLStringIndex("Strings/" + filename + "_English.DLSTRINGS", Type_DLStrings); + static const std::filesystem::path s("Strings"); + buildLStringIndex(s / (filename + u8"_English.STRINGS"), Type_Strings); + buildLStringIndex(s / (filename + u8"_English.ILSTRINGS"), Type_ILStrings); + buildLStringIndex(s / (filename + u8"_English.DLSTRINGS"), Type_DLStrings); } -void Reader::buildLStringIndex(const std::string& stringFile, LocalizedStringType stringType) +void Reader::buildLStringIndex(const std::filesystem::path &stringFile, LocalizedStringType stringType) { std::uint32_t numEntries; std::uint32_t dataSize; @@ -638,7 +637,7 @@ void Reader::adjustGRUPFormId() std::stringstream ss; ss << "ESM Error: " << msg; - ss << "\n File: " << mCtx.filename; + ss << "\n File: " << mCtx.filename.string(); //TODO(Project579): This will probably break in windows with unicode paths ss << "\n Record: " << ESM::printName(mCtx.recordHeader.record.typeId); ss << "\n Subrecord: " << ESM::printName(mCtx.subRecordHeader.typeId); if (mStream.get()) diff --git a/components/esm4/reader.hpp b/components/esm4/reader.hpp index e620cae932..dea7360e3c 100644 --- a/components/esm4/reader.hpp +++ b/components/esm4/reader.hpp @@ -47,7 +47,7 @@ namespace ESM4 { struct ReaderContext { - std::string filename; // in case we need to reopen to restore the context + std::filesystem::path filename; // in case we need to reopen to restore the context std::uint32_t modIndex; // the sequential position of this file in the load order: // 0x00 reserved, 0xFF in-game (see notes below) @@ -113,7 +113,7 @@ namespace ESM4 { std::vector* mGlobalReaderList = nullptr; - void buildLStringIndex(const std::string& stringFile, LocalizedStringType stringType); + void buildLStringIndex(const std::filesystem::path& stringFile, LocalizedStringType stringType); inline bool hasLocalizedStrings() const { return (mHeader.mFlags & Rec_Localized) != 0; } @@ -124,11 +124,11 @@ namespace ESM4 { //void close(); // Raw opening. Opens the file and sets everything up but doesn't parse the header. - void openRaw(Files::IStreamPtr&& stream, const std::string& filename); + void openRaw(Files::IStreamPtr&& stream, const std::filesystem::path& filename); // Load ES file from a new stream, parses the header. // Closes the currently open file first, if any. - void open(Files::IStreamPtr&& stream, const std::string& filename); + void open(Files::IStreamPtr&& stream, const std::filesystem::path& filename); Reader() = default; @@ -137,13 +137,12 @@ namespace ESM4 { public: - Reader(Files::IStreamPtr&& esmStream, const std::string& filename); + Reader(Files::IStreamPtr&& esmStream, const std::filesystem::path& filename); ~Reader(); - // FIXME: should be private but ESMTool uses it - void openRaw(const std::string& filename); - void open(const std::string& filename); + + void open(const std::filesystem::path& filename); void close(); @@ -158,7 +157,7 @@ namespace ESM4 { inline int getFormat() const { return 0; }; // prob. not relevant for ESM4 inline const std::string getDesc() const { return mHeader.mDesc; } - inline std::string getFileName() const { return mCtx.filename; }; // not used + inline std::filesystem::path getFileName() const { return mCtx.filename; }; // not used inline bool hasMoreRecs() const { return (mFileSize - mCtx.fileRead) > 0; } diff --git a/components/esmloader/load.cpp b/components/esmloader/load.cpp index 8d407515f2..99d8159f04 100644 --- a/components/esmloader/load.cpp +++ b/components/esmloader/load.cpp @@ -228,7 +228,7 @@ namespace EsmLoader for (std::size_t i = 0; i < contentFiles.size(); ++i) { const std::string &file = contentFiles[i]; - const std::string extension = Misc::StringUtils::lowerCase(std::filesystem::path(file).extension().string()); + const std::string extension = Misc::StringUtils::lowerCase(std::filesystem::path(file).extension().string()); //TODO(Project579): let's hope unicode characters are never used in these extensions on windows or this will break if (supportedFormats.find(extension) == supportedFormats.end()) { @@ -247,7 +247,7 @@ namespace EsmLoader const ESM::ReadersCache::BusyItem reader = readers.get(i); reader->setEncoder(encoder); reader->setIndex(static_cast(i)); - reader->open(collection.getPath(file).string()); + reader->open(collection.getPath(file)); if (query.mLoadCells) reader->resolveParentFileIndices(readers); diff --git a/components/files/collections.cpp b/components/files/collections.cpp index 6146da3347..0929336075 100644 --- a/components/files/collections.cpp +++ b/components/files/collections.cpp @@ -36,21 +36,19 @@ namespace Files std::filesystem::path Collections::getPath(const std::string& file) const { - for (Files::PathContainer::const_iterator iter = mDirectories.begin(); - iter != mDirectories.end(); ++iter) + for (const auto & mDirectorie : mDirectories) { - for (std::filesystem::directory_iterator iter2 (*iter); - iter2!=std::filesystem::directory_iterator(); ++iter2) + for (const auto& iter2 : + std::filesystem::directory_iterator (mDirectorie)) { - std::filesystem::path path = *iter2; - + const auto& path = iter2.path(); if (mFoldCase) { - if (Misc::StringUtils::ciEqual(file, path.filename().string())) - return path.string(); + if (Misc::StringUtils::ciEqual(file, path.filename().string())) //TODO(Project579): This will probably break in windows with unicode paths + return path; } - else if (path.filename().string() == file) - return path.string(); + else if (path.filename().string() == file) //TODO(Project579): This will probably break in windows with unicode paths + return path; } } @@ -59,20 +57,19 @@ namespace Files bool Collections::doesExist(const std::string& file) const { - for (Files::PathContainer::const_iterator iter = mDirectories.begin(); - iter != mDirectories.end(); ++iter) + for (const auto & mDirectorie : mDirectories) { - for (std::filesystem::directory_iterator iter2 (*iter); - iter2!=std::filesystem::directory_iterator(); ++iter2) + for (const auto& iter2 : + std::filesystem::directory_iterator (mDirectorie)) { - std::filesystem::path path = *iter2; + const auto& path = iter2.path(); if (mFoldCase) { - if (Misc::StringUtils::ciEqual(file, path.filename().string())) + if (Misc::StringUtils::ciEqual(file, path.filename().string())) //TODO(Project579): This will probably break in windows with unicode paths return true; } - else if (path.filename().string() == file) + else if (path.filename().string() == file) //TODO(Project579): This will probably break in windows with unicode paths return true; } } diff --git a/components/files/collections.hpp b/components/files/collections.hpp index 000160bae7..69ae7d0d84 100644 --- a/components/files/collections.hpp +++ b/components/files/collections.hpp @@ -19,14 +19,14 @@ namespace Files /// leading dot and must be all lower-case. const MultiDirCollection& getCollection(const std::string& extension) const; - std::filesystem::path getPath(const std::string& file) const; + std::filesystem::path getPath(const std::string& file) const; //TODO(Project579): let's hope unicode characters are never used in these filenames on windows or this will break ///< Return full path (including filename) of \a file. /// /// If the file does not exist in any of the collection's /// directories, an exception is thrown. \a file must include the /// extension. - bool doesExist(const std::string& file) const; + bool doesExist(const std::string& file) const; //TODO(Project579): let's hope unicode characters are never used in these filenames on windows or this will break ///< \return Does a file with the given name exist? const Files::PathContainer& getPaths() const; diff --git a/components/files/configurationmanager.cpp b/components/files/configurationmanager.cpp index 900c341edc..0fc228abee 100644 --- a/components/files/configurationmanager.cpp +++ b/components/files/configurationmanager.cpp @@ -155,9 +155,9 @@ void ConfigurationManager::readConfiguration(bpo::variables_map& variables, if (!quiet) { - Log(Debug::Info) << "Logs dir: " << getUserConfigPath().string(); - Log(Debug::Info) << "User data dir: " << mUserDataPath.string(); - Log(Debug::Info) << "Screenshots dir: " << mScreenshotPath.string(); + Log(Debug::Info) << "Logs dir: " << getUserConfigPath().string(); //TODO(Project579): This will probably break in windows with unicode paths + Log(Debug::Info) << "User data dir: " << mUserDataPath.string(); //TODO(Project579): This will probably break in windows with unicode paths + Log(Debug::Info) << "Screenshots dir: " << mScreenshotPath.string(); //TODO(Project579): This will probably break in windows with unicode paths } mSilent = silent; @@ -270,7 +270,7 @@ void mergeComposingVariables(bpo::variables_map& first, bpo::variables_map& seco void ConfigurationManager::processPath(std::filesystem::path& path, const std::filesystem::path& basePath) const { - std::string str = path.string(); + std::string str = path.string(); //TODO(Project579): This will probably break in windows with unicode paths if (str.empty() || str[0] != '?') { @@ -285,7 +285,7 @@ void ConfigurationManager::processPath(std::filesystem::path& path, const std::f auto tokenIt = mTokensMapping.find(str.substr(0, pos + 1)); if (tokenIt != mTokensMapping.end()) { - std::filesystem::path tempPath(((mFixedPath).*(tokenIt->second))()); + std::filesystem::path tempPath(((mFixedPath).*(tokenIt->second))()); //TODO(Project579): This will probably break in windows with unicode paths if (pos < str.length() - 1) { // There is something after the token, so we should @@ -293,7 +293,7 @@ void ConfigurationManager::processPath(std::filesystem::path& path, const std::f tempPath /= str.substr(pos + 1, str.length() - pos); } - path = tempPath; + path = tempPath; //TODO(Project579): This will probably break in windows with unicode paths } else { @@ -351,7 +351,7 @@ std::optional ConfigurationManager::loadConfig( if (std::filesystem::is_regular_file(cfgFile)) { if (!mSilent) - Log(Debug::Info) << "Loading config file: " << cfgFile.string(); + Log(Debug::Info) << "Loading config file: " << cfgFile.string(); //TODO(Project579): This will probably break in windows with unicode paths std::ifstream configFileStream(cfgFile); @@ -438,7 +438,7 @@ std::istream& operator>> (std::istream& istream, MaybeQuotedPath& MaybeQuotedPat if (istream && !istream.eof() && istream.peek() != EOF) { std::string remainder{std::istreambuf_iterator(istream), {}}; - Log(Debug::Warning) << "Trailing data in path setting. Used '" << MaybeQuotedPath.string() << "' but '" << remainder << "' remained"; + Log(Debug::Warning) << "Trailing data in path setting. Used '" << MaybeQuotedPath.string() << "' but '" << remainder << "' remained"; //TODO(Project579): This will probably break in windows with unicode paths } } else diff --git a/components/files/constrainedfilestream.cpp b/components/files/constrainedfilestream.cpp index a56ae01aa0..4ac0453139 100644 --- a/components/files/constrainedfilestream.cpp +++ b/components/files/constrainedfilestream.cpp @@ -1,8 +1,10 @@ +#include + #include "constrainedfilestream.hpp" namespace Files { - IStreamPtr openConstrainedFileStream(const std::string& filename, std::size_t start, std::size_t length) + IStreamPtr openConstrainedFileStream(const std::filesystem::path &filename, std::size_t start, std::size_t length) { return std::make_unique(std::make_unique(filename, start, length)); } diff --git a/components/files/constrainedfilestream.hpp b/components/files/constrainedfilestream.hpp index f00bd3a488..fd239b2832 100644 --- a/components/files/constrainedfilestream.hpp +++ b/components/files/constrainedfilestream.hpp @@ -14,7 +14,7 @@ namespace Files /// A file stream constrained to a specific region in the file, specified by the 'start' and 'length' parameters. using ConstrainedFileStream = StreamWithBuffer; -IStreamPtr openConstrainedFileStream(const std::string& filename, std::size_t start = 0, +IStreamPtr openConstrainedFileStream(const std::filesystem::path &filename, std::size_t start = 0, std::size_t length = std::numeric_limits::max()); } diff --git a/components/files/constrainedfilestreambuf.cpp b/components/files/constrainedfilestreambuf.cpp index f5fd8ac394..24c0a9b4d8 100644 --- a/components/files/constrainedfilestreambuf.cpp +++ b/components/files/constrainedfilestreambuf.cpp @@ -2,12 +2,13 @@ #include #include +#include namespace Files { namespace File = Platform::File; - - ConstrainedFileStreamBuf::ConstrainedFileStreamBuf(const std::string& fname, std::size_t start, std::size_t length) + + ConstrainedFileStreamBuf::ConstrainedFileStreamBuf(const std::filesystem::path& fname, std::size_t start, std::size_t length) : mOrigin(start) { mFile = File::open(fname.c_str()); diff --git a/components/files/constrainedfilestreambuf.hpp b/components/files/constrainedfilestreambuf.hpp index bb9d6ca89e..7ee18f082a 100644 --- a/components/files/constrainedfilestreambuf.hpp +++ b/components/files/constrainedfilestreambuf.hpp @@ -11,7 +11,7 @@ namespace Files class ConstrainedFileStreamBuf final : public std::streambuf { public: - ConstrainedFileStreamBuf(const std::string& fname, std::size_t start, std::size_t length); + ConstrainedFileStreamBuf(const std::filesystem::path &fname, std::size_t start, std::size_t length); int_type underflow() final; diff --git a/components/files/hash.cpp b/components/files/hash.cpp index b11ecbf838..e8d4c2a3b0 100644 --- a/components/files/hash.cpp +++ b/components/files/hash.cpp @@ -9,7 +9,7 @@ namespace Files { - std::array getHash(const std::string& fileName, std::istream& stream) + std::array getHash(const std::filesystem::path& fileName, std::istream& stream) { std::array hash {0, 0}; try @@ -34,7 +34,7 @@ namespace Files } catch (const std::exception& e) { - throw std::runtime_error("Error while reading \"" + fileName + "\" to get hash: " + std::string(e.what())); + throw std::runtime_error("Error while reading \"" + fileName.string() + "\" to get hash: " + std::string(e.what())); //TODO(Project579): This will probably break in windows with unicode paths } return hash; } diff --git a/components/files/hash.hpp b/components/files/hash.hpp index a39961e4d5..2f525c3222 100644 --- a/components/files/hash.hpp +++ b/components/files/hash.hpp @@ -4,11 +4,11 @@ #include #include #include -#include +#include namespace Files { - std::array getHash(const std::string& fileName, std::istream& stream); + std::array getHash(const std::filesystem::path& fileName, std::istream& stream); } #endif diff --git a/components/files/linuxpath.cpp b/components/files/linuxpath.cpp index b6833fd025..94f02f8f7c 100644 --- a/components/files/linuxpath.cpp +++ b/components/files/linuxpath.cpp @@ -51,9 +51,12 @@ namespace Files LinuxPath::LinuxPath(const std::string& application_name) : mName(application_name) { - std::filesystem::path localPath = getLocalPath(); - if (chdir(localPath.string().c_str()) != 0) - Log(Debug::Warning) << "Error " << errno << " when changing current directory"; + std::error_code ec; + current_path(getLocalPath(), ec); + const auto err = ec.value(); + if (err != 0) { + Log(Debug::Warning) << "Error " << err << " " << std::strerror(err) << " when changing current directory"; + } } std::filesystem::path LinuxPath::getUserConfigPath() const @@ -79,18 +82,16 @@ std::filesystem::path LinuxPath::getGlobalConfigPath() const std::filesystem::path LinuxPath::getLocalPath() const { - std::filesystem::path localPath("./"); - const char *statusPaths[] = {"/proc/self/exe", "/proc/self/file", "/proc/curproc/exe", "/proc/curproc/file"}; + auto localPath = std::filesystem::current_path(); + static const std::filesystem::path statusPaths[] = {"/proc/self/exe", "/proc/self/file", "/proc/curproc/exe", "/proc/curproc/file"}; - for(const char *path : statusPaths) + for(const auto& path : statusPaths) { - std::filesystem::path statusPath(path); - if (!std::filesystem::exists(statusPath)) continue; - - statusPath = std::filesystem::read_symlink(statusPath); - if (!std::filesystem::is_empty(statusPath)) + std::error_code ec; + const auto binPath = read_symlink(path, ec); + if (ec.value() != -1) { - localPath = statusPath.parent_path() / "/"; + localPath = binPath.parent_path(); break; } } diff --git a/components/files/multidircollection.cpp b/components/files/multidircollection.cpp index 50cddcdecf..ad7b54b463 100644 --- a/components/files/multidircollection.cpp +++ b/components/files/multidircollection.cpp @@ -30,7 +30,7 @@ namespace Files { if (!std::filesystem::is_directory(directory)) { - Log(Debug::Info) << "Skipping invalid directory: " << directory.string(); + Log(Debug::Info) << "Skipping invalid directory: " << directory.string(); //TODO(Project579): This will probably break in windows with unicode paths continue; } @@ -39,10 +39,10 @@ namespace Files { std::filesystem::path path = *dirIter; - if (!equal (extension, path.extension().string())) + if (!equal (extension, path.extension().string())) //TODO(Project579): let's hope unicode characters are never used in these extensions on windows or this will break continue; - std::string filename = path.filename().string(); + std::string filename = path.filename().string(); //TODO(Project579): let's hope unicode characters are never used in these filenames on windows or this will break TIter result = mFiles.find (filename); diff --git a/components/files/openfile.cpp b/components/files/openfile.cpp index 54b0b28058..2ab4409017 100644 --- a/components/files/openfile.cpp +++ b/components/files/openfile.cpp @@ -9,7 +9,7 @@ namespace Files { - std::unique_ptr openBinaryInputFileStream(const std::string& path) + std::unique_ptr openBinaryInputFileStream(const std::filesystem::path &path) { #if defined(_WIN32) || defined(__WINDOWS__) std::wstring wpath = boost::locale::conv::utf_to_utf(path); @@ -18,7 +18,7 @@ namespace Files auto stream = std::make_unique(path, std::ios::binary); #endif if (!stream->is_open()) - throw std::runtime_error("Failed to open '" + path + "' for reading: " + std::strerror(errno)); + throw std::runtime_error("Failed to open '" + path.string() + "' for reading: " + std::strerror(errno)); //TODO(Project579): This will probably break in windows with unicode paths stream->exceptions(std::ios::badbit); return stream; } diff --git a/components/files/openfile.hpp b/components/files/openfile.hpp index 3cecf7bac1..a65f0a8b18 100644 --- a/components/files/openfile.hpp +++ b/components/files/openfile.hpp @@ -4,10 +4,11 @@ #include #include #include +#include namespace Files { - std::unique_ptr openBinaryInputFileStream(const std::string& path); + std::unique_ptr openBinaryInputFileStream(const std::filesystem::path &path); } #endif diff --git a/components/files/windowspath.cpp b/components/files/windowspath.cpp index da26e773f6..c6a03f4263 100644 --- a/components/files/windowspath.cpp +++ b/components/files/windowspath.cpp @@ -19,11 +19,6 @@ namespace bconv = boost::locale::conv; #include -/** - * FIXME: Someone with Windows system should check this and correct if necessary - * FIXME: MAX_PATH is irrelevant for extended-length paths, i.e. \\?\... - */ - /** * \namespace Files */ @@ -33,31 +28,21 @@ namespace Files WindowsPath::WindowsPath(const std::string& application_name) : mName(application_name) { - /* Since on Windows boost::path.string() returns string of narrow - characters in local encoding, it is required to path::imbue() - with UTF-8 encoding (generated for empty name from boost::locale) - to handle Unicode in platform-agnostic way using std::string. - - See boost::filesystem and boost::locale reference for details. - */ - // TODO(Project579): Temporarly disabled until a good solution is found (no solution might actually be needed) - //boost::filesystem::path::imbue(boost::locale::generator().generate("")); - - std::filesystem::path localPath = getLocalPath(); - if (!SetCurrentDirectoryA(localPath.string().c_str())) - Log(Debug::Warning) << "Error " << GetLastError() << " when changing current directory"; + std::error_code ec; + current_path(getLocalPath(), ec); + if (ec.value() != 0) + Log(Debug::Warning) << "Error " << ec.value() << " when changing current directory"; } std::filesystem::path WindowsPath::getUserConfigPath() const { - std::filesystem::path userPath("."); + std::filesystem::path userPath = std::filesystem::current_path(); - WCHAR path[MAX_PATH + 1]; - memset(path, 0, sizeof(path)); + WCHAR path[MAX_PATH + 1] = {}; if(SUCCEEDED(SHGetFolderPathW(nullptr, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, nullptr, 0, path))) { - userPath = std::filesystem::path(bconv::utf_to_utf(path)); + userPath = std::filesystem::path(path); } return userPath / "My Games" / mName; @@ -71,14 +56,13 @@ std::filesystem::path WindowsPath::getUserDataPath() const std::filesystem::path WindowsPath::getGlobalConfigPath() const { - std::filesystem::path globalPath("."); + std::filesystem::path globalPath = std::filesystem::current_path(); - WCHAR path[MAX_PATH + 1]; - memset(path, 0, sizeof(path)); + WCHAR path[MAX_PATH + 1] = {}; if(SUCCEEDED(SHGetFolderPathW(nullptr, CSIDL_PROGRAM_FILES | CSIDL_FLAG_CREATE, nullptr, 0, path))) { - globalPath = std::filesystem::path(bconv::utf_to_utf(path)); + globalPath = std::filesystem::path(path); } return globalPath / mName; @@ -86,13 +70,13 @@ std::filesystem::path WindowsPath::getGlobalConfigPath() const std::filesystem::path WindowsPath::getLocalPath() const { - std::filesystem::path localPath("./"); - WCHAR path[MAX_PATH + 1]; - memset(path, 0, sizeof(path)); + std::filesystem::path localPath = std::filesystem::current_path(); + + WCHAR path[MAX_PATH + 1] = {}; if (GetModuleFileNameW(nullptr, path, MAX_PATH + 1) > 0) { - localPath = std::filesystem::path(bconv::utf_to_utf(path)).parent_path().string() + "/"; + localPath = std::filesystem::path(path).parent_path(); } // lookup exe path @@ -111,20 +95,17 @@ std::filesystem::path WindowsPath::getCachePath() const std::filesystem::path WindowsPath::getInstallPath() const { - std::filesystem::path installPath(); - - HKEY hKey; + std::filesystem::path installPath{}; - LPCTSTR regkey = TEXT("SOFTWARE\\Bethesda Softworks\\Morrowind"); - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, regkey, 0, KEY_READ | KEY_WOW64_32KEY, &hKey) == ERROR_SUCCESS) + if (HKEY hKey; RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Bethesda Softworks\\Morrowind", 0, KEY_READ | KEY_WOW64_32KEY, &hKey) == ERROR_SUCCESS) { //Key existed, let's try to read the install dir - std::vector buf(512); - int len = 512; + std::array buf{}; + DWORD len = buf.size() * sizeof(wchar_t); - if (RegQueryValueEx(hKey, TEXT("Installed Path"), nullptr, nullptr, (LPBYTE)buf.data(), (LPDWORD)&len) == ERROR_SUCCESS) + if (RegQueryValueExW(hKey, L"Installed Path", nullptr, nullptr, reinterpret_cast(buf.data()), &len) == ERROR_SUCCESS) { - installPath = buf.data(); + installPath = std::filesystem::path (buf.data()); } RegCloseKey(hKey); } diff --git a/components/fontloader/fontloader.cpp b/components/fontloader/fontloader.cpp index a06429ed4b..4e5525d3a5 100644 --- a/components/fontloader/fontloader.cpp +++ b/components/fontloader/fontloader.cpp @@ -251,7 +251,7 @@ namespace Gui MyGUI::IntSize bookSize = getBookSize(layersStream.get()); float bookScale = osgMyGUI::ScalingLayer::getScaleFactor(bookSize); - std::string oldDataPath = dataManager->getDataPath(""); + const auto oldDataPath = dataManager->getDataPath(""); dataManager->setResourcePath("fonts"); std::unique_ptr dataStream(dataManager->getData(fileName)); diff --git a/components/fx/technique.cpp b/components/fx/technique.cpp index 20042bb9ae..357d8448d1 100644 --- a/components/fx/technique.cpp +++ b/components/fx/technique.cpp @@ -39,7 +39,7 @@ namespace fx { Technique::Technique(const VFS::Manager& vfs, Resource::ImageManager& imageManager, const std::string& name, int width, int height, bool ubo, bool supportsNormals) : mName(name) - , mFileName((std::filesystem::path(Technique::sSubdir) / (mName + Technique::sExt)).string()) + , mFileName((std::filesystem::path(Technique::sSubdir) / (mName + Technique::sExt)).string()) //TODO(Project579): let's hope unicode characters are never used in these filenames on windows or this will break , mLastModificationTime(std::filesystem::file_time_type()) , mWidth(width) , mHeight(height) diff --git a/components/lua/luastate.cpp b/components/lua/luastate.cpp index dbdfde5100..a78eea6dde 100644 --- a/components/lua/luastate.cpp +++ b/components/lua/luastate.cpp @@ -26,21 +26,20 @@ namespace LuaUtil throw std::runtime_error("module not found: " + std::string(packageName)); } - static std::string packageNameToPath(std::string_view packageName, const std::vector& searchDirs) + static std::filesystem::path packageNameToPath(std::string_view packageName, const std::vector &searchDirs) { std::string path(packageName); std::replace(path.begin(), path.end(), '.', '/'); std::string pathWithInit = path + "/init.lua"; path.append(".lua"); - for (const std::string& dir : searchDirs) + for (const auto& base : searchDirs) { - std::filesystem::path base(dir); std::filesystem::path p1 = base / path; if (std::filesystem::exists(p1)) - return p1.string(); + return p1; std::filesystem::path p2 = base / pathWithInit; if (std::filesystem::exists(p2)) - return p2.string(); + return p2; } throw std::runtime_error("module not found: " + std::string(packageName)); } @@ -270,8 +269,8 @@ namespace LuaUtil sol::function LuaState::loadInternalLib(std::string_view libName) { - std::string path = packageNameToPath(libName, mLibSearchPaths); - sol::load_result res = mLua.load_file(path, sol::load_mode::text); + const auto path = packageNameToPath(libName, mLibSearchPaths); + sol::load_result res = mLua.load_file(path.string(), sol::load_mode::text); //TODO(Project579): This will probably break in windows with unicode paths if (!res.valid()) throw std::runtime_error("Lua error: " + res.get()); return res; diff --git a/components/lua/luastate.hpp b/components/lua/luastate.hpp index 3bd27f2250..48d302d44b 100644 --- a/components/lua/luastate.hpp +++ b/components/lua/luastate.hpp @@ -5,6 +5,8 @@ #include +#include + #include "configuration.hpp" namespace VFS @@ -80,7 +82,7 @@ namespace LuaUtil const ScriptsConfiguration& getConfiguration() const { return *mConf; } // Load internal Lua library. All libraries are loaded in one sandbox and shouldn't be exposed to scripts directly. - void addInternalLibSearchPath(const std::string& path) { mLibSearchPaths.push_back(path); } + void addInternalLibSearchPath(const std::filesystem::path &path) { mLibSearchPaths.push_back(path); } sol::function loadInternalLib(std::string_view libName); sol::function loadFromVFS(const std::string& path); sol::environment newInternalLibEnvironment(); @@ -98,7 +100,7 @@ namespace LuaUtil std::map mCompiledScripts; std::map mCommonPackages; const VFS::Manager* mVFS; - std::vector mLibSearchPaths; + std::vector mLibSearchPaths; }; // Should be used for every call of every Lua function. diff --git a/components/lua/storage.cpp b/components/lua/storage.cpp index bff978b633..ffb4f8af82 100644 --- a/components/lua/storage.cpp +++ b/components/lua/storage.cpp @@ -155,12 +155,12 @@ namespace LuaUtil } } - void LuaStorage::load(const std::string& path) + void LuaStorage::load(const std::filesystem::path &path) { assert(mData.empty()); // Shouldn't be used before loading try { - Log(Debug::Info) << "Loading Lua storage \"" << path << "\" (" << std::filesystem::file_size(path) << " bytes)"; + Log(Debug::Info) << "Loading Lua storage \"" << path << "\" (" << std::filesystem::file_size(path) << " bytes)"; //TODO(Project579): This will probably break in windows with unicode paths std::ifstream fin(path, std::fstream::binary); std::string serializedData((std::istreambuf_iterator(fin)), std::istreambuf_iterator()); sol::table data = deserialize(mLua, serializedData); @@ -177,7 +177,7 @@ namespace LuaUtil } } - void LuaStorage::save(const std::string& path) const + void LuaStorage::save(const std::filesystem::path &path) const { sol::table data(mLua, sol::create); for (const auto& [sectionName, section] : mData) @@ -186,7 +186,7 @@ namespace LuaUtil data[sectionName] = section->asTable(); } std::string serializedData = serialize(data); - Log(Debug::Info) << "Saving Lua storage \"" << path << "\" (" << serializedData.size() << " bytes)"; + Log(Debug::Info) << "Saving Lua storage \"" << path << "\" (" << serializedData.size() << " bytes)"; //TODO(Project579): This will probably break in windows with unicode paths std::ofstream fout(path, std::fstream::binary); fout.write(serializedData.data(), serializedData.size()); fout.close(); diff --git a/components/lua/storage.hpp b/components/lua/storage.hpp index 8ae944c5ab..f4047bd2ee 100644 --- a/components/lua/storage.hpp +++ b/components/lua/storage.hpp @@ -18,8 +18,8 @@ namespace LuaUtil explicit LuaStorage(lua_State* lua) : mLua(lua) {} void clearTemporaryAndRemoveCallbacks(); - void load(const std::string& path); - void save(const std::string& path) const; + void load(const std::filesystem::path &path); + void save(const std::filesystem::path &path) const; sol::object getSection(std::string_view sectionName, bool readOnly); sol::object getMutableSection(std::string_view sectionName) { return getSection(sectionName, false); } diff --git a/components/myguiplatform/myguidatamanager.cpp b/components/myguiplatform/myguidatamanager.cpp index 80b7a096bc..3078650a47 100644 --- a/components/myguiplatform/myguidatamanager.cpp +++ b/components/myguiplatform/myguidatamanager.cpp @@ -26,7 +26,7 @@ namespace namespace osgMyGUI { -void DataManager::setResourcePath(const std::string &path) +void DataManager::setResourcePath(const std::filesystem::path &path) { mResourcePath = path; } @@ -39,7 +39,7 @@ DataManager::DataManager(const std::string& resourcePath, const VFS::Manager* vf MyGUI::IDataStream *DataManager::getData(const std::string &name) const { - return new DataStream(mVfs->get(mResourcePath + "/" + name)); + return new DataStream(mVfs->get(mResourcePath / name)); } void DataManager::freeData(MyGUI::IDataStream *data) @@ -49,7 +49,7 @@ void DataManager::freeData(MyGUI::IDataStream *data) bool DataManager::isDataExist(const std::string &name) const { - return mVfs->exists(mResourcePath + "/" + name); + return mVfs->exists(mResourcePath / name); } const MyGUI::VectorString &DataManager::getDataListNames(const std::string &pattern) const @@ -68,7 +68,7 @@ const std::string &DataManager::getDataPath(const std::string &name) const if (!isDataExist(name)) return result; - result = mResourcePath + "/" + name; + result = (mResourcePath / name).string(); //TODO(Project579): This is broken on windows with unicode paths return result; } diff --git a/components/myguiplatform/myguidatamanager.hpp b/components/myguiplatform/myguidatamanager.hpp index 000c3ca1dd..09a427fdac 100644 --- a/components/myguiplatform/myguidatamanager.hpp +++ b/components/myguiplatform/myguidatamanager.hpp @@ -4,6 +4,7 @@ #include #include +#include namespace VFS { @@ -18,7 +19,7 @@ class DataManager : public MyGUI::DataManager public: explicit DataManager(const std::string& path, const VFS::Manager* vfs); - void setResourcePath(const std::string& path); + void setResourcePath(const std::filesystem::path &path); /** Get data stream from specified resource name. @param _name Resource name (usually file name). @@ -47,7 +48,7 @@ public: const std::string& getDataPath(const std::string& _name) const override; private: - std::string mResourcePath; + std::filesystem::path mResourcePath; const VFS::Manager* mVfs; }; diff --git a/components/myguiplatform/myguiloglistener.cpp b/components/myguiplatform/myguiloglistener.cpp index ab5537b6b2..e22b96680a 100644 --- a/components/myguiplatform/myguiloglistener.cpp +++ b/components/myguiplatform/myguiloglistener.cpp @@ -8,9 +8,9 @@ namespace osgMyGUI { void CustomLogListener::open() { - mStream.open(std::filesystem::path(mFileName), std::ios_base::out); + mStream.open(mFileName, std::ios_base::out); if (!mStream.is_open()) - Log(Debug::Error) << "Unable to create MyGUI log with path " << mFileName; + Log(Debug::Error) << "Unable to create MyGUI log with path " << mFileName; //TODO(Project579): This is broken on windows with unicode paths } void CustomLogListener::close() diff --git a/components/myguiplatform/myguiloglistener.hpp b/components/myguiplatform/myguiloglistener.hpp index c22b5afb02..4d6072a1d6 100644 --- a/components/myguiplatform/myguiloglistener.hpp +++ b/components/myguiplatform/myguiloglistener.hpp @@ -19,7 +19,7 @@ namespace osgMyGUI class CustomLogListener : public MyGUI::ILogListener { public: - CustomLogListener(const std::string &name) + CustomLogListener(const std::filesystem::path &name) : mFileName(name) {} @@ -31,11 +31,9 @@ namespace osgMyGUI void log(const std::string& _section, MyGUI::LogLevel _level, const struct tm* _time, const std::string& _message, const char* _file, int _line) override; - const std::string& getFileName() const { return mFileName; } - private: std::ofstream mStream; - std::string mFileName; + std::filesystem::path mFileName; }; /// \brief Helper class holding data that required during @@ -49,7 +47,7 @@ namespace osgMyGUI public: - LogFacility(const std::string &output, bool console) + LogFacility(const std::filesystem::path &output, bool console) : mFile(output) { mConsole.setEnabled(console); diff --git a/components/myguiplatform/myguiplatform.cpp b/components/myguiplatform/myguiplatform.cpp index 203de195f4..5425ddd31d 100644 --- a/components/myguiplatform/myguiplatform.cpp +++ b/components/myguiplatform/myguiplatform.cpp @@ -8,7 +8,7 @@ namespace osgMyGUI { Platform::Platform(osgViewer::Viewer *viewer, osg::Group* guiRoot, Resource::ImageManager* imageManager, - const VFS::Manager* vfs, float uiScalingFactor, const std::string& resourcePath, const std::string& logName) + const VFS::Manager* vfs, float uiScalingFactor, const std::filesystem::path& resourcePath, const std::filesystem::path& logName) : mLogFacility(logName.empty() ? nullptr : std::make_unique(logName, false)) , mLogManager(std::make_unique()) , mDataManager(std::make_unique(resourcePath, vfs)) diff --git a/components/myguiplatform/myguiplatform.hpp b/components/myguiplatform/myguiplatform.hpp index 666dde8a84..a4812cc0b9 100644 --- a/components/myguiplatform/myguiplatform.hpp +++ b/components/myguiplatform/myguiplatform.hpp @@ -3,6 +3,7 @@ #include #include +#include namespace osgViewer { @@ -36,8 +37,8 @@ namespace osgMyGUI { public: Platform(osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ImageManager* imageManager, - const VFS::Manager* vfs, float uiScalingFactor, const std::string& resourcePath, - const std::string& logName = "MyGUI.log"); + const VFS::Manager* vfs, float uiScalingFactor, const std::filesystem::path& resourcePath, + const std::filesystem::path& logName = "MyGUI.log"); ~Platform(); diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index 574ba8bc2b..08d80b0f67 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -22,7 +22,7 @@ namespace Nif { /// Open a NIF stream. The name is used for error messages. -NIFFile::NIFFile(Files::IStreamPtr&& stream, const std::string &name) +NIFFile::NIFFile(Files::IStreamPtr&& stream, const std::filesystem::path &name) : filename(name) { parse(std::move(stream)); @@ -316,7 +316,7 @@ void NIFFile::parse(Files::IStreamPtr&& stream) r = entry->second(); if (!supportedVersion) - Log(Debug::Verbose) << "NIF Debug: Reading record of type " << rec << ", index " << i << " (" << filename << ")"; + Log(Debug::Verbose) << "NIF Debug: Reading record of type " << rec << ", index " << i << " (" << filename << ")"; //TODO(Project579): This will probably break in windows with unicode paths assert(r != nullptr); assert(r->recType != RC_MISSING); diff --git a/components/nif/niffile.hpp b/components/nif/niffile.hpp index 6b217df6e1..5b14ad2e46 100644 --- a/components/nif/niffile.hpp +++ b/components/nif/niffile.hpp @@ -31,7 +31,7 @@ struct File virtual bool getUseSkinning() const = 0; - virtual std::string getFilename() const = 0; + virtual std::filesystem::path getFilename() const = 0; virtual std::string getHash() const = 0; @@ -50,7 +50,7 @@ class NIFFile final : public File unsigned int bethVer = 0; /// File name, used for error messages and opening the file - std::string filename; + std::filesystem::path filename; std::string hash; /// Record list @@ -100,7 +100,7 @@ public: void warn(const std::string &msg) const; /// Open a NIF stream. The name is used for error messages. - NIFFile(Files::IStreamPtr&& stream, const std::string &name); + NIFFile(Files::IStreamPtr&& stream, const std::filesystem::path &name); /// Get a given record Record *getRecord(size_t index) const override @@ -129,7 +129,7 @@ public: bool getUseSkinning() const override; /// Get the name of the file - std::string getFilename() const override { return filename; } + std::filesystem::path getFilename() const override { return filename; } std::string getHash() const override { return hash; } diff --git a/components/nifbullet/bulletnifloader.cpp b/components/nifbullet/bulletnifloader.cpp index 427d33000a..aeaf57c5f4 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -187,7 +187,7 @@ osg::ref_ptr BulletNifLoader::load(const Nif::File& nif) if (node) roots.emplace_back(node); } - const std::string filename = nif.getFilename(); + const std::string filename = nif.getFilename().string(); //TODO(Project579): This will probably break in windows with unicode paths mShape->mFileName = filename; if (roots.empty()) { diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 19a83175a3..39ccafdceb 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -225,12 +225,12 @@ namespace NifOsg { public: /// @param filename used for warning messages. - LoaderImpl(const std::string& filename, unsigned int ver, unsigned int userver, unsigned int bethver) + LoaderImpl(const std::filesystem::path& filename, unsigned int ver, unsigned int userver, unsigned int bethver) : mFilename(filename), mVersion(ver), mUserVersion(userver), mBethVersion(bethver) { } - std::string mFilename; + std::filesystem::path mFilename; unsigned int mVersion, mUserVersion, mBethVersion; size_t mFirstRootTextureIndex{~0u}; @@ -299,7 +299,7 @@ namespace NifOsg setupController(key, callback, /*animflags*/0); if (!target.mKeyframeControllers.emplace(strdata->string, callback).second) - Log(Debug::Verbose) << "Controller " << strdata->string << " present more than once in " << nif->getFilename() << ", ignoring later version"; + Log(Debug::Verbose) << "Controller " << strdata->string << " present more than once in " << nif->getFilename() << ", ignoring later version"; //TODO(Project579): This will probably break in windows with unicode paths } } @@ -485,20 +485,20 @@ namespace NifOsg { if (nifNode->recType != Nif::RC_NiTextureEffect) { - Log(Debug::Info) << "Unhandled effect " << nifNode->recName << " in " << mFilename; + Log(Debug::Info) << "Unhandled effect " << nifNode->recName << " in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths return; } const Nif::NiTextureEffect* textureEffect = static_cast(nifNode); if (textureEffect->textureType != Nif::NiTextureEffect::Environment_Map) { - Log(Debug::Info) << "Unhandled NiTextureEffect type " << textureEffect->textureType << " in " << mFilename; + Log(Debug::Info) << "Unhandled NiTextureEffect type " << textureEffect->textureType << " in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths return; } if (textureEffect->texture.empty()) { - Log(Debug::Info) << "NiTextureEffect missing source texture in " << mFilename; + Log(Debug::Info) << "NiTextureEffect missing source texture in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths return; } @@ -515,7 +515,7 @@ namespace NifOsg texGen->setMode(osg::TexGen::SPHERE_MAP); break; default: - Log(Debug::Info) << "Unhandled NiTextureEffect coordGenType " << textureEffect->coordGenType << " in " << mFilename; + Log(Debug::Info) << "Unhandled NiTextureEffect coordGenType " << textureEffect->coordGenType << " in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths return; } @@ -875,7 +875,7 @@ namespace NifOsg // These controllers are handled elsewhere } else - Log(Debug::Info) << "Unhandled controller " << ctrl->recName << " on node " << nifNode->recIndex << " in " << mFilename; + Log(Debug::Info) << "Unhandled controller " << ctrl->recName << " on node " << nifNode->recIndex << " in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths } } @@ -915,7 +915,7 @@ namespace NifOsg composite->addController(osgctrl); } else - Log(Debug::Info) << "Unexpected material controller " << ctrl->recType << " in " << mFilename; + Log(Debug::Info) << "Unexpected material controller " << ctrl->recType << " in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths } } @@ -959,7 +959,7 @@ namespace NifOsg composite->addController(callback); } else - Log(Debug::Info) << "Unexpected texture controller " << ctrl->recName << " in " << mFilename; + Log(Debug::Info) << "Unexpected texture controller " << ctrl->recName << " in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths } } @@ -994,7 +994,7 @@ namespace NifOsg // unused } else - Log(Debug::Info) << "Unhandled particle modifier " << affectors->recName << " in " << mFilename; + Log(Debug::Info) << "Unhandled particle modifier " << affectors->recName << " in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths } for (; !colliders.empty(); colliders = colliders->next) { @@ -1009,7 +1009,7 @@ namespace NifOsg program->addOperator(new SphericalCollider(sphericalcollider)); } else - Log(Debug::Info) << "Unhandled particle collider " << colliders->recName << " in " << mFilename; + Log(Debug::Info) << "Unhandled particle collider " << colliders->recName << " in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths } } @@ -1152,7 +1152,7 @@ namespace NifOsg } if (!partctrl) { - Log(Debug::Info) << "No particle controller found in " << mFilename; + Log(Debug::Info) << "No particle controller found in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths return; } @@ -1247,7 +1247,7 @@ namespace NifOsg unsigned int uvSet = *it; if (uvSet >= uvlist.size()) { - Log(Debug::Verbose) << "Out of bounds UV set " << uvSet << " on shape \"" << name << "\" in " << mFilename; + Log(Debug::Verbose) << "Out of bounds UV set " << uvSet << " on shape \"" << name << "\" in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths if (uvlist.empty()) continue; uvSet = 0; @@ -1419,7 +1419,7 @@ namespace NifOsg case 9: return osg::BlendFunc::ONE_MINUS_DST_ALPHA; case 10: return osg::BlendFunc::SRC_ALPHA_SATURATE; default: - Log(Debug::Info) << "Unexpected blend mode: "<< mode << " in " << mFilename; + Log(Debug::Info) << "Unexpected blend mode: "<< mode << " in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths return osg::BlendFunc::SRC_ALPHA; } } @@ -1437,7 +1437,7 @@ namespace NifOsg case 6: return osg::AlphaFunc::GEQUAL; case 7: return osg::AlphaFunc::NEVER; default: - Log(Debug::Info) << "Unexpected blend mode: " << mode << " in " << mFilename; + Log(Debug::Info) << "Unexpected blend mode: " << mode << " in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths return osg::AlphaFunc::LEQUAL; } } @@ -1455,7 +1455,7 @@ namespace NifOsg case 6: return osg::Stencil::GEQUAL; case 7: return osg::Stencil::ALWAYS; default: - Log(Debug::Info) << "Unexpected stencil function: " << func << " in " << mFilename; + Log(Debug::Info) << "Unexpected stencil function: " << func << " in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths return osg::Stencil::NEVER; } } @@ -1471,7 +1471,7 @@ namespace NifOsg case 4: return osg::Stencil::DECR; case 5: return osg::Stencil::INVERT; default: - Log(Debug::Info) << "Unexpected stencil operation: " << op << " in " << mFilename; + Log(Debug::Info) << "Unexpected stencil operation: " << op << " in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths return osg::Stencil::KEEP; } } @@ -1514,7 +1514,7 @@ namespace NifOsg packing = 4; break; default: - Log(Debug::Info) << "Unhandled internal pixel format " << pixelData->fmt << " in " << mFilename; + Log(Debug::Info) << "Unhandled internal pixel format " << pixelData->fmt << " in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths return nullptr; } @@ -1572,7 +1572,7 @@ namespace NifOsg { if (pixelData->palette.empty() || pixelData->bpp != 8) { - Log(Debug::Info) << "Palettized texture in " << mFilename << " is invalid, ignoring"; + Log(Debug::Info) << "Palettized texture in " << mFilename << " is invalid, ignoring"; //TODO(Project579): This will probably break in windows with unicode paths return nullptr; } pixelformat = pixelData->fmt == Nif::NiPixelData::NIPXFMT_PAL8 ? GL_RGB : GL_RGBA; @@ -1644,7 +1644,7 @@ namespace NifOsg break; default: { - Log(Debug::Info) << "Unhandled texture stage " << i << " on shape \"" << nodeName << "\" in " << mFilename; + Log(Debug::Info) << "Unhandled texture stage " << i << " on shape \"" << nodeName << "\" in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths continue; } } @@ -1658,7 +1658,7 @@ namespace NifOsg if(tex.texture.empty() && texprop->controller.empty()) { if (i == 0) - Log(Debug::Warning) << "Base texture is in use but empty on shape \"" << nodeName << "\" in " << mFilename; + Log(Debug::Warning) << "Base texture is in use but empty on shape \"" << nodeName << "\" in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths continue; } @@ -1815,7 +1815,7 @@ namespace NifOsg break; default: { - Log(Debug::Info) << "Unhandled texture stage " << i << " on shape \"" << nodeName << "\" in " << mFilename; + Log(Debug::Info) << "Unhandled texture stage " << i << " on shape \"" << nodeName << "\" in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths continue; } } @@ -1859,10 +1859,10 @@ namespace NifOsg case Nif::BSShaderType::ShaderType_Water: case Nif::BSShaderType::ShaderType_Lighting30: case Nif::BSShaderType::ShaderType_Tile: - Log(Debug::Warning) << "Unhandled BSShaderType " << type << " in " << mFilename; + Log(Debug::Warning) << "Unhandled BSShaderType " << type << " in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths return std::string_view(); } - Log(Debug::Warning) << "Unknown BSShaderType " << type << " in " << mFilename; + Log(Debug::Warning) << "Unknown BSShaderType " << type << " in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths return std::string_view(); } @@ -1891,10 +1891,10 @@ namespace NifOsg case Nif::BSLightingShaderType::ShaderType_LODNoise: case Nif::BSLightingShaderType::ShaderType_MultitexLandLODBlend: case Nif::BSLightingShaderType::ShaderType_Dismemberment: - Log(Debug::Warning) << "Unhandled BSLightingShaderType " << type << " in " << mFilename; + Log(Debug::Warning) << "Unhandled BSLightingShaderType " << type << " in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths return std::string_view(); } - Log(Debug::Warning) << "Unknown BSLightingShaderType " << type << " in " << mFilename; + Log(Debug::Warning) << "Unknown BSLightingShaderType " << type << " in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths return std::string_view(); } @@ -2057,7 +2057,7 @@ namespace NifOsg break; } default: - Log(Debug::Info) << "Unhandled " << property->recName << " in " << mFilename; + Log(Debug::Info) << "Unhandled " << property->recName << " in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths break; } } @@ -2304,7 +2304,7 @@ namespace NifOsg else if (type == Nif::RC_NiClusterAccumulator) setBin_BackToFront(stateset); else - Log(Debug::Error) << "Unrecognized NiAccumulator in " << mFilename; + Log(Debug::Error) << "Unrecognized NiAccumulator in " << mFilename; //TODO(Project579): This will probably break in windows with unicode paths }; switch (mPushedSorter->mMode) diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index bbbdde68d7..ef8d1c66e3 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -477,7 +477,7 @@ namespace Resource return *mShaderManager.get(); } - void SceneManager::setShaderPath(const std::string &path) + void SceneManager::setShaderPath(const std::filesystem::path &path) { mShaderManager->setShaderPath(path); } @@ -498,14 +498,14 @@ namespace Resource osgDB::ReaderWriter::ReadResult readImage(const std::string& filename, const osgDB::Options* options) override { - std::filesystem::path filePath(filename); + std::filesystem::path filePath(filename); //TODO(Project579): This will probably break in windows with unicode paths if (filePath.is_absolute()) // It is a hack. Needed because either OSG or libcollada-dom tries to make an absolute path from // our relative VFS path by adding current working directory. filePath = std::filesystem::relative(filename, osgDB::getCurrentWorkingDirectory()); try { - return osgDB::ReaderWriter::ReadResult(mImageManager->getImage(filePath.string()), + return osgDB::ReaderWriter::ReadResult(mImageManager->getImage(filePath.string()), //TODO(Project579): This will probably break in windows with unicode paths osgDB::ReaderWriter::ReadResult::FILE_LOADED); } catch (std::exception& e) diff --git a/components/resource/scenemanager.hpp b/components/resource/scenemanager.hpp index d3ad868a99..b27b807447 100644 --- a/components/resource/scenemanager.hpp +++ b/components/resource/scenemanager.hpp @@ -14,6 +14,7 @@ #include "resourcemanager.hpp" #include +#include namespace Resource { @@ -124,7 +125,7 @@ namespace Resource void setConvertAlphaTestToAlphaToCoverage(bool convert); - void setShaderPath(const std::string& path); + void setShaderPath(const std::filesystem::path &path); /// Check if a given scene is loaded and if so, update its usage timestamp to prevent it from being unloaded bool checkLoaded(const std::string& name, double referenceTime); diff --git a/components/sceneutil/screencapture.cpp b/components/sceneutil/screencapture.cpp index 97a22e94aa..6adff9323d 100644 --- a/components/sceneutil/screencapture.cpp +++ b/components/sceneutil/screencapture.cpp @@ -61,8 +61,9 @@ namespace namespace SceneUtil { - std::string writeScreenshotToFile(const std::string& screenshotPath, const std::string& screenshotFormat, - const osg::Image& image) + std::filesystem::path writeScreenshotToFile(const std::filesystem::path& screenshotPath, + const std::string& screenshotFormat, + const osg::Image& image) { // Count screenshots. int shotCount = 0; @@ -70,7 +71,7 @@ namespace SceneUtil // Find the first unused filename with a do-while std::ostringstream stream; std::string lastFileName; - std::string lastFilePath; + std::filesystem::path lastFilePath; do { // Reset the stream @@ -80,12 +81,12 @@ namespace SceneUtil stream << "screenshot" << std::setw(3) << std::setfill('0') << shotCount++ << "." << screenshotFormat; lastFileName = stream.str(); - lastFilePath = screenshotPath + "/" + lastFileName; + lastFilePath = screenshotPath / lastFileName; } while (std::filesystem::exists(lastFilePath)); std::ofstream outStream; - outStream.open(std::filesystem::path(std::move(lastFilePath)), std::ios::binary); + outStream.open(lastFilePath, std::ios::binary); osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension(screenshotFormat); if (!readerwriter) @@ -104,7 +105,7 @@ namespace SceneUtil return lastFileName; } - WriteScreenshotToFileOperation::WriteScreenshotToFileOperation(const std::string& screenshotPath, + WriteScreenshotToFileOperation::WriteScreenshotToFileOperation(const std::filesystem::path &screenshotPath, const std::string& screenshotFormat, std::function callback) : mScreenshotPath(screenshotPath) @@ -115,7 +116,7 @@ namespace SceneUtil void WriteScreenshotToFileOperation::operator()(const osg::Image& image, const unsigned int /*context_id*/) { - std::string fileName; + std::filesystem::path fileName; try { fileName = writeScreenshotToFile(mScreenshotPath, mScreenshotFormat, image); @@ -128,7 +129,7 @@ namespace SceneUtil if (fileName.empty()) mCallback("Failed to save screenshot"); else - mCallback(fileName + " has been saved"); + mCallback(fileName.string() + " has been saved"); //TODO(Project579): This will probably break in windows with unicode paths } AsyncScreenCaptureOperation::AsyncScreenCaptureOperation(osg::ref_ptr queue, diff --git a/components/sceneutil/screencapture.hpp b/components/sceneutil/screencapture.hpp index 87e396b020..e5a8304896 100644 --- a/components/sceneutil/screencapture.hpp +++ b/components/sceneutil/screencapture.hpp @@ -8,6 +8,7 @@ #include #include +#include namespace osg { @@ -19,19 +20,20 @@ namespace SceneUtil class WorkQueue; class WorkItem; - std::string writeScreenshotToFile(const std::string& screenshotPath, const std::string& screenshotFormat, - const osg::Image& image); + std::filesystem::path writeScreenshotToFile(const std::filesystem::path& screenshotPath, + const std::string& screenshotFormat, + const osg::Image& image); class WriteScreenshotToFileOperation : public osgViewer::ScreenCaptureHandler::CaptureOperation { public: - WriteScreenshotToFileOperation(const std::string& screenshotPath, const std::string& screenshotFormat, + WriteScreenshotToFileOperation(const std::filesystem::path &screenshotPath, const std::string& screenshotFormat, std::function callback); void operator()(const osg::Image& image, const unsigned int context_id) override; private: - const std::string mScreenshotPath; + const std::filesystem::path mScreenshotPath; const std::string mScreenshotFormat; const std::function mCallback; }; diff --git a/components/sceneutil/writescene.cpp b/components/sceneutil/writescene.cpp index d243f521c0..1a605be5ae 100644 --- a/components/sceneutil/writescene.cpp +++ b/components/sceneutil/writescene.cpp @@ -8,7 +8,7 @@ #include "serialize.hpp" -void SceneUtil::writeScene(osg::Node *node, const std::string& filename, const std::string& format) +void SceneUtil::writeScene(osg::Node *node, const std::filesystem::path& filename, const std::string& format) { registerSerializers(); diff --git a/components/sceneutil/writescene.hpp b/components/sceneutil/writescene.hpp index 307251fe80..0e1701f4ad 100644 --- a/components/sceneutil/writescene.hpp +++ b/components/sceneutil/writescene.hpp @@ -1,7 +1,7 @@ #ifndef OPENMW_COMPONENTS_WRITESCENE_H #define OPENMW_COMPONENTS_WRITESCENE_H -#include +#include namespace osg { @@ -11,7 +11,7 @@ namespace osg namespace SceneUtil { - void writeScene(osg::Node* node, const std::string& filename, const std::string& format); + void writeScene(osg::Node* node, const std::filesystem::path& filename, const std::string& format); } diff --git a/components/settings/parser.cpp b/components/settings/parser.cpp index cbc51ff220..44016ad010 100644 --- a/components/settings/parser.cpp +++ b/components/settings/parser.cpp @@ -10,12 +10,12 @@ #include -void Settings::SettingsFileParser::loadSettingsFile(const std::string& file, CategorySettingValueMap& settings, +void Settings::SettingsFileParser::loadSettingsFile(const std::filesystem::path &file, CategorySettingValueMap& settings, bool base64Encoded, bool overrideExisting) { mFile = file; std::ifstream fstream; - fstream.open(std::filesystem::path(file)); + fstream.open(file); auto stream = std::ref(fstream); std::istringstream decodedStream; @@ -82,7 +82,7 @@ void Settings::SettingsFileParser::loadSettingsFile(const std::string& file, Cat } } -void Settings::SettingsFileParser::saveSettingsFile(const std::string& file, const CategorySettingValueMap& settings) +void Settings::SettingsFileParser::saveSettingsFile(const std::filesystem::path &file, const CategorySettingValueMap& settings) { using CategorySettingStatusMap = std::map; @@ -108,8 +108,7 @@ void Settings::SettingsFileParser::saveSettingsFile(const std::string& file, con // as the output file if we're copying the setting from the default settings.cfg for the // first time. A minor change in API to pass the source file might be in order here. std::ifstream istream; - std::filesystem::path ipath(file); - istream.open(ipath); + istream.open(file); // Create a new string stream to write the current settings to. It's likely that the // input file and the output file are the same, so this stream serves as a temporary file @@ -305,9 +304,9 @@ void Settings::SettingsFileParser::saveSettingsFile(const std::string& file, con // Now install the newly written file in the requested place. if (changed) { - Log(Debug::Info) << "Updating settings file: " << ipath; + Log(Debug::Info) << "Updating settings file: " << file; //TODO(Project579): This will probably break in windows with unicode paths std::ofstream ofstream; - ofstream.open(ipath); + ofstream.open(file); ofstream << ostream.rdbuf(); ofstream.close(); } diff --git a/components/settings/parser.hpp b/components/settings/parser.hpp index c934fbea07..a062a39fa2 100644 --- a/components/settings/parser.hpp +++ b/components/settings/parser.hpp @@ -4,16 +4,17 @@ #include "categories.hpp" #include +#include namespace Settings { class SettingsFileParser { public: - void loadSettingsFile(const std::string& file, CategorySettingValueMap& settings, - bool base64encoded = false, bool overrideExisting = false); + void loadSettingsFile(const std::filesystem::path &file, CategorySettingValueMap& settings, + bool base64Encoded = false, bool overrideExisting = false); - void saveSettingsFile(const std::string& file, const CategorySettingValueMap& settings); + void saveSettingsFile(const std::filesystem::path &file, const CategorySettingValueMap& settings); private: /// Increment i until it longer points to a whitespace character @@ -23,7 +24,7 @@ namespace Settings [[noreturn]] void fail(const std::string& message); - std::string mFile; + std::filesystem::path mFile; int mLine = 0; }; } diff --git a/components/settings/settings.cpp b/components/settings/settings.cpp index cd4016900b..b252af2ccf 100644 --- a/components/settings/settings.cpp +++ b/components/settings/settings.cpp @@ -21,7 +21,7 @@ void Manager::clear() mChangedSettings.clear(); } -std::string Manager::load(const Files::ConfigurationManager& cfgMgr, bool loadEditorSettings) +std::filesystem::path Manager::load(const Files::ConfigurationManager& cfgMgr, bool loadEditorSettings) { SettingsFileParser parser; const std::vector& paths = cfgMgr.getActiveConfigPaths(); @@ -44,7 +44,7 @@ std::string Manager::load(const Files::ConfigurationManager& cfgMgr, bool loadEd } // Create the settings manager and load default settings file. - const std::string defaultsBin = (paths.front() / defaultSettingsFile).string(); + const auto defaultsBin = paths.front() / defaultSettingsFile; if (!std::filesystem::exists(defaultsBin)) throw std::runtime_error ("No default settings file found! Make sure the file \"" + defaultSettingsFile + "\" was properly installed."); parser.loadSettingsFile(defaultsBin, mDefaultSettings, true, false); @@ -52,20 +52,20 @@ std::string Manager::load(const Files::ConfigurationManager& cfgMgr, bool loadEd // Load "settings.cfg" or "openmw-cs.cfg" from every config dir except the last one as additional default settings. for (int i = 0; i < static_cast(paths.size()) - 1; ++i) { - const std::string additionalDefaults = (paths[i] / userSettingsFile).string(); + const auto additionalDefaults = paths[i] / userSettingsFile; if (std::filesystem::exists(additionalDefaults)) parser.loadSettingsFile(additionalDefaults, mDefaultSettings, false, true); } // Load "settings.cfg" or "openmw-cs.cfg" from the last config dir as user settings. This path will be used to save modified settings. - std::string settingspath = (paths.back() / userSettingsFile).string(); + auto settingspath = paths.back() / userSettingsFile; if (std::filesystem::exists(settingspath)) parser.loadSettingsFile(settingspath, mUserSettings, false, false); return settingspath; } -void Manager::saveUser(const std::string &file) +void Manager::saveUser(const std::filesystem::path &file) { SettingsFileParser parser; parser.saveSettingsFile(file, mUserSettings); diff --git a/components/settings/settings.hpp b/components/settings/settings.hpp index f50449b5de..e5e841e3de 100644 --- a/components/settings/settings.hpp +++ b/components/settings/settings.hpp @@ -11,6 +11,7 @@ #include #include +#include namespace Files { @@ -41,10 +42,10 @@ namespace Settings static void clear(); ///< clears all settings and default settings - static std::string load(const Files::ConfigurationManager& cfgMgr, bool loadEditorSettings = false); + static std::filesystem::path load(const Files::ConfigurationManager& cfgMgr, bool loadEditorSettings = false); ///< load settings from all active config dirs. Returns the path of the last loaded file. - static void saveUser (const std::string& file); + static void saveUser (const std::filesystem::path &file); ///< save user settings to file static void resetPendingChanges(); diff --git a/components/settings/shadermanager.hpp b/components/settings/shadermanager.hpp index eaf10a3a34..effedf63d2 100644 --- a/components/settings/shadermanager.hpp +++ b/components/settings/shadermanager.hpp @@ -104,12 +104,12 @@ namespace Settings return std::nullopt; } - bool load(const std::string& path) + bool load(const std::filesystem::path &path) { mData = YAML::Null; - mPath = std::filesystem::path(path); + mPath = path; - Log(Debug::Info) << "Loading shader settings file: " << mPath; + Log(Debug::Info) << "Loading shader settings file: " << mPath; //TODO(Project579): This will probably break in windows with unicode paths if (!std::filesystem::exists(mPath)) { @@ -123,7 +123,7 @@ namespace Settings try { - mData = YAML::LoadFile(mPath.string()); + mData = YAML::LoadFile(mPath.string()); //TODO(Project579): This will probably break in windows with unicode paths mData.SetStyle(YAML::EmitterStyle::Block); if (!mData["config"]) @@ -153,7 +153,7 @@ namespace Settings out.SetMapFormat(YAML::Block); out << mData; - std::ofstream fout(mPath.string()); + std::ofstream fout(mPath); fout << out.c_str(); if (!fout) diff --git a/components/shader/shadermanager.cpp b/components/shader/shadermanager.cpp index 326615cc05..1e48cf337e 100644 --- a/components/shader/shadermanager.cpp +++ b/components/shader/shadermanager.cpp @@ -25,7 +25,7 @@ namespace Shader ShaderManager::~ShaderManager() = default; - void ShaderManager::setShaderPath(const std::string &path) + void ShaderManager::setShaderPath(const std::filesystem::path &path) { mPath = path; } @@ -126,7 +126,7 @@ namespace Shader includeFstream.open(includePath); if (includeFstream.fail()) { - Log(Debug::Error) << "Shader " << fileName << " error: Failed to open include " << includePath.string(); + Log(Debug::Error) << "Shader " << fileName << " error: Failed to open include " << includePath.string(); //TODO(Project579): This will probably break in windows with unicode paths return false; } int includedFileNumber = fileNumber++; @@ -467,12 +467,12 @@ namespace Shader if (templateIt == mShaderTemplates.end()) { - std::filesystem::path path = (std::filesystem::path(mPath) / templateName); + std::filesystem::path path = mPath / templateName; std::ifstream stream; stream.open(path); if (stream.fail()) { - Log(Debug::Error) << "Failed to open " << path.string(); + Log(Debug::Error) << "Failed to open " << path.string(); //TODO(Project579): This will probably break in windows with unicode paths return nullptr; } std::stringstream buffer; @@ -482,7 +482,7 @@ namespace Shader int fileNumber = 1; std::string source = buffer.str(); if (!addLineDirectivesAfterConditionalBlocks(source) - || !parseIncludes(std::filesystem::path(mPath), source, templateName, fileNumber, {}, insertedPaths)) + || !parseIncludes(mPath, source, templateName, fileNumber, {}, insertedPaths)) return nullptr; mHotReloadManager->templateIncludedFiles[templateName] = insertedPaths; templateIt = mShaderTemplates.insert(std::make_pair(templateName, source)).first; diff --git a/components/shader/shadermanager.hpp b/components/shader/shadermanager.hpp index 50c430637e..55bc1cb04a 100644 --- a/components/shader/shadermanager.hpp +++ b/components/shader/shadermanager.hpp @@ -12,6 +12,7 @@ #include #include +#include namespace osgViewer { class Viewer; @@ -29,7 +30,7 @@ namespace Shader ShaderManager(); ~ShaderManager(); - void setShaderPath(const std::string& path); + void setShaderPath(const std::filesystem::path &path); typedef std::map DefineMap; @@ -80,7 +81,7 @@ namespace Shader void getLinkedShaders(osg::ref_ptr shader, const std::vector& linkedShaderNames, const DefineMap& defines); void addLinkedShaders(osg::ref_ptr shader, osg::ref_ptr program); - std::string mPath; + std::filesystem::path mPath; DefineMap mGlobalDefines; diff --git a/components/version/version.cpp b/components/version/version.cpp index 32b8f44ae6..a280bf38d3 100644 --- a/components/version/version.cpp +++ b/components/version/version.cpp @@ -6,11 +6,9 @@ namespace Version { -Version getOpenmwVersion(const std::string &resourcePath) +Version getOpenmwVersion(const std::filesystem::path &resourcePath) { - std::filesystem::path path (resourcePath + "/version"); - - std::ifstream stream (path); + std::ifstream stream (resourcePath / "version"); Version v; std::getline(stream, v.mVersion); @@ -31,7 +29,7 @@ std::string Version::describe() return str; } -std::string getOpenmwVersionDescription(const std::string &resourcePath) +std::string getOpenmwVersionDescription(const std::filesystem::path &resourcePath) { Version v = getOpenmwVersion(resourcePath); return v.describe(); diff --git a/components/version/version.hpp b/components/version/version.hpp index 7371e786e0..0248f869a9 100644 --- a/components/version/version.hpp +++ b/components/version/version.hpp @@ -2,6 +2,7 @@ #define VERSION_HPP #include +#include namespace Version { @@ -16,10 +17,10 @@ namespace Version }; /// Read OpenMW version from the version file located in resourcePath. - Version getOpenmwVersion(const std::string& resourcePath); + Version getOpenmwVersion(const std::filesystem::path &resourcePath); /// Helper function to getOpenmwVersion and describe() it - std::string getOpenmwVersionDescription(const std::string& resourcePath); + std::string getOpenmwVersionDescription(const std::filesystem::path &resourcePath); } diff --git a/components/vfs/archive.hpp b/components/vfs/archive.hpp index 22df09e06c..26db7b8535 100644 --- a/components/vfs/archive.hpp +++ b/components/vfs/archive.hpp @@ -15,7 +15,7 @@ namespace VFS virtual Files::IStreamPtr open() = 0; - virtual std::string getPath() = 0; + virtual std::filesystem::path getPath() = 0; }; class Archive diff --git a/components/vfs/bsaarchive.cpp b/components/vfs/bsaarchive.cpp index c0db4c071c..f2c09cf848 100644 --- a/components/vfs/bsaarchive.cpp +++ b/components/vfs/bsaarchive.cpp @@ -7,7 +7,7 @@ namespace VFS { -BsaArchive::BsaArchive(const std::string &filename) +BsaArchive::BsaArchive(const std::filesystem::path &filename) { mFile = std::make_unique(); mFile->open(filename); @@ -68,7 +68,7 @@ Files::IStreamPtr BsaArchiveFile::open() return mFile->getFile(mInfo); } -CompressedBsaArchive::CompressedBsaArchive(const std::string &filename) +CompressedBsaArchive::CompressedBsaArchive(const std::filesystem::path &filename) : Archive() { mCompressedFile = std::make_unique(); diff --git a/components/vfs/bsaarchive.hpp b/components/vfs/bsaarchive.hpp index a52104efd7..23811c045b 100644 --- a/components/vfs/bsaarchive.hpp +++ b/components/vfs/bsaarchive.hpp @@ -15,7 +15,7 @@ namespace VFS Files::IStreamPtr open() override; - std::string getPath() override { return mInfo->name(); } + std::filesystem::path getPath() override { return mInfo->name(); } const Bsa::BSAFile::FileStruct* mInfo; Bsa::BSAFile* mFile; @@ -28,7 +28,7 @@ namespace VFS Files::IStreamPtr open() override; - std::string getPath() override { return mInfo->name(); } + std::filesystem::path getPath() override { return mInfo->name(); } const Bsa::BSAFile::FileStruct* mInfo; Bsa::CompressedBSAFile* mCompressedFile; @@ -38,7 +38,7 @@ namespace VFS class BsaArchive : public Archive { public: - BsaArchive(const std::string& filename); + BsaArchive(const std::filesystem::path &filename); BsaArchive(); virtual ~BsaArchive(); void listResources(std::map& out, char (*normalize_function) (char)) override; @@ -53,7 +53,7 @@ namespace VFS class CompressedBsaArchive : public Archive { public: - CompressedBsaArchive(const std::string& filename); + CompressedBsaArchive(const std::filesystem::path &filename); virtual ~CompressedBsaArchive() {} void listResources(std::map& out, char (*normalize_function) (char)) override; bool contains(const std::string& file, char (*normalize_function) (char)) const override; diff --git a/components/vfs/filesystemarchive.cpp b/components/vfs/filesystemarchive.cpp index 7b57c93944..f6b01a89c4 100644 --- a/components/vfs/filesystemarchive.cpp +++ b/components/vfs/filesystemarchive.cpp @@ -10,7 +10,7 @@ namespace VFS { - FileSystemArchive::FileSystemArchive(const std::string &path) + FileSystemArchive::FileSystemArchive(const std::filesystem::path &path) : mBuiltIndex(false) , mPath(path) { @@ -21,31 +21,30 @@ namespace VFS { if (!mBuiltIndex) { - typedef std::filesystem::recursive_directory_iterator directory_iterator; + const auto str = mPath.string(); //TODO(Project579): This will probably break in windows with unicode paths + size_t prefix = str.size (); - directory_iterator end; - - size_t prefix = mPath.size (); - - if (mPath.size () > 0 && mPath [prefix - 1] != '\\' && mPath [prefix - 1] != '/') + if (!mPath.empty() && str [prefix - 1] != '\\' && str [prefix - 1] != '/') ++prefix; - for (directory_iterator i (std::filesystem::u8path(mPath)); i != end; ++i) + for (const auto& i : + std::filesystem::recursive_directory_iterator(mPath)) { - if(std::filesystem::is_directory (*i)) + if(std::filesystem::is_directory (i)) continue; - auto proper = i->path ().u8string (); + const auto& path = i.path (); + const auto& proper = path.string (); //TODO(Project579): This will probably break in windows with unicode paths - FileSystemArchiveFile file(std::string((char*)proper.c_str(), proper.size())); + FileSystemArchiveFile file(path); std::string searchable; - std::transform(proper.begin() + prefix, proper.end(), std::back_inserter(searchable), normalize_function); + std::transform(std::next(proper.begin(), static_cast(prefix)), proper.end(), std::back_inserter(searchable), normalize_function); const auto inserted = mIndex.insert(std::make_pair(searchable, file)); if (!inserted.second) - Log(Debug::Warning) << "Warning: found duplicate file for '" << std::string((char*)proper.c_str(), proper.size()) << "', please check your file system for two files with the same name in different cases."; + Log(Debug::Warning) << "Warning: found duplicate file for '" << proper << "', please check your file system for two files with the same name in different cases."; //TODO(Project579): This will probably break in windows with unicode paths else out[inserted.first->first] = &inserted.first->second; } @@ -67,12 +66,12 @@ namespace VFS std::string FileSystemArchive::getDescription() const { - return std::string{"DIR: "} + mPath; + return std::string{"DIR: "} + mPath.string(); //TODO(Project579): This will probably break in windows with unicode paths } // ---------------------------------------------------------------------------------- - FileSystemArchiveFile::FileSystemArchiveFile(const std::string &path) + FileSystemArchiveFile::FileSystemArchiveFile(const std::filesystem::path &path) : mPath(path) { } diff --git a/components/vfs/filesystemarchive.hpp b/components/vfs/filesystemarchive.hpp index 2c50e5300b..678eb19f95 100644 --- a/components/vfs/filesystemarchive.hpp +++ b/components/vfs/filesystemarchive.hpp @@ -1,6 +1,7 @@ #ifndef OPENMW_COMPONENTS_RESOURCE_FILESYSTEMARCHIVE_H #define OPENMW_COMPONENTS_RESOURCE_FILESYSTEMARCHIVE_H +#include #include "archive.hpp" #include @@ -11,21 +12,21 @@ namespace VFS class FileSystemArchiveFile : public File { public: - FileSystemArchiveFile(const std::string& path); + FileSystemArchiveFile(const std::filesystem::path &path); Files::IStreamPtr open() override; - std::string getPath() override { return mPath; } + std::filesystem::path getPath() override { return mPath; } private: - std::string mPath; + std::filesystem::path mPath; }; class FileSystemArchive : public Archive { public: - FileSystemArchive(const std::string& path); + FileSystemArchive(const std::filesystem::path &path); void listResources(std::map& out, char (*normalize_function) (char)) override; @@ -38,7 +39,7 @@ namespace VFS index mIndex; bool mBuiltIndex; - std::string mPath; + std::filesystem::path mPath; }; diff --git a/components/vfs/manager.cpp b/components/vfs/manager.cpp index c8434fd9fd..8f3963f3f7 100644 --- a/components/vfs/manager.cpp +++ b/components/vfs/manager.cpp @@ -56,7 +56,7 @@ namespace VFS mIndex.clear(); for (const auto& archive : mArchives) - archive->listResources(mIndex, mStrict ? &strict_normalize_char : &nonstrict_normalize_char); + archive->listResources(mIndex, mStrict ? &strict_normalize_char : &nonstrict_normalize_char); //TODO(Project579): This will probably break in windows with unicode paths } Files::IStreamPtr Manager::get(std::string_view name) const @@ -102,15 +102,15 @@ namespace VFS return {}; } - std::string Manager::getAbsoluteFileName(std::string_view name) const + std::filesystem::path Manager::getAbsoluteFileName(const std::filesystem::path &name) const { - std::string normalized(name); - normalize_path(normalized, mStrict); + std::string normalized(name); //TODO(Project579): This will probably break in windows with unicode paths + normalize_path(normalized, mStrict); //TODO(Project579): This will probably break in windows with unicode paths - std::map::const_iterator found = mIndex.find(normalized); + const auto found = mIndex.find(normalized); if (found == mIndex.end()) throw std::runtime_error("Resource '" + normalized + "' not found"); - return found->second->getPath(); + return found->second->getPath();//TODO(Project579): This will probably break in windows with unicode paths } namespace diff --git a/components/vfs/manager.hpp b/components/vfs/manager.hpp index ab42a643a5..8f8f6e450f 100644 --- a/components/vfs/manager.hpp +++ b/components/vfs/manager.hpp @@ -94,7 +94,7 @@ namespace VFS /// Retrieve the absolute path to the file /// @note Throws an exception if the file can not be found. /// @note May be called from any thread once the index has been built. - std::string getAbsoluteFileName(std::string_view name) const; + std::filesystem::path getAbsoluteFileName(const std::filesystem::path &name) const; private: bool mStrict; diff --git a/components/vfs/registerarchives.cpp b/components/vfs/registerarchives.cpp index 80f4561136..dd8287818e 100644 --- a/components/vfs/registerarchives.cpp +++ b/components/vfs/registerarchives.cpp @@ -22,8 +22,8 @@ namespace VFS if (collections.doesExist(*archive)) { // Last BSA has the highest priority - const std::string archivePath = collections.getPath(*archive).string(); - Log(Debug::Info) << "Adding BSA archive " << archivePath; + const auto archivePath = collections.getPath(*archive); + Log(Debug::Info) << "Adding BSA archive " << archivePath; //TODO(Project579): This will probably break in windows with unicode paths Bsa::BsaVersion bsaVersion = Bsa::CompressedBSAFile::detectVersion(archivePath); if (bsaVersion == Bsa::BSAVER_COMPRESSED) @@ -49,7 +49,7 @@ namespace VFS vfs->addArchive(std::make_unique(dataDir)); } else - Log(Debug::Info) << "Ignoring duplicate data directory " << dataDir; + Log(Debug::Info) << "Ignoring duplicate data directory " << dataDir; //TODO(Project579): This will probably break in windows with unicode paths } }