Make sure all paths are passed as std::filesystem::path instead of std::string where possible.

crashfix_debugdraw
Project579 3 years ago
parent 35fe214588
commit e5c417c968

@ -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<std::string> >()[0];
info.filename = variables["input-file"].as< std::vector<std::string> >()[0]; //TODO(Project579): This will probably break in windows with unicode paths
// Default output to the working directory
info.outdir = ".";

@ -33,6 +33,7 @@ namespace
namespace bpo = boost::program_options;
using StringsVector = std::vector<std::string>;
using PathsVector = std::vector<std::filesystem::path>;
bpo::options_description makeOptionsDescription()
{
@ -145,7 +146,7 @@ namespace
const auto fsStrict = variables["fs-strict"].as<bool>();
const auto resDir = variables["resources"].as<Files::MaybeQuotedPath>();
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);

@ -3,7 +3,7 @@
#include <vector>
#include <optional>
#include <string>
#include <filesystem>
#include <components/esm/format.hpp>
@ -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<std::string> types;
std::string name;

@ -154,9 +154,9 @@ bool parseOptions (int argc, char** argv, Arguments &info)
return false;
}*/
info.filename = variables["input-file"].as< std::vector<std::string> >()[0];
info.filename = variables["input-file"].as< std::vector<std::filesystem::path> >()[0];
if (variables["input-file"].as< std::vector<std::string> >().size() > 1)
info.outname = variables["input-file"].as< std::vector<std::string> >()[1];
info.outname = variables["input-file"].as< std::vector<std::filesystem::path> >()[1];
if (const auto it = variables.find("raw"); it != variables.end())
info.mRawFormat = ESM::parseFormat(it->second.as<std::string>());
@ -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<std::ifstream>&& 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;
}

@ -289,7 +289,7 @@ namespace EsmTool
int loadTes4(const Arguments& info, std::unique_ptr<std::ifstream>&& 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
{

@ -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);

@ -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 = "<br><b>Error writing settings.cfg</b><br><br>" +
settingsPath + "<br><br>" + e.what();
settingsPath.string() + "<br><br>" + 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;
}

@ -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);

@ -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<std::string> 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();
}

@ -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

@ -143,7 +143,7 @@ namespace NavMeshTool
const auto fsStrict = variables["fs-strict"].as<bool>();
const auto resDir = variables["resources"].as<Files::MaybeQuotedPath>();
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<std::uint64_t>(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;

@ -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<VFS::Archive>&& anArchive, std::string archivePath = "")
void readVFS(std::unique_ptr<VFS::Archive>&& 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<VFS::BsaArchive>(archivePath + name), archivePath + name + "/");
readVFS(std::make_unique<VFS::BsaArchive>(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<std::string>& files)
"Allowed options");
desc.add_options()
("help,h", "print help message.")
("input-file", bpo::value< std::vector<std::string> >(), "input file")
("input-file", bpo::value< std::vector<std::filesystem::path> >(), "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<VFS::BsaArchive>(name));
readVFS(std::make_unique<VFS::BsaArchive>(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<VFS::FileSystemArchive>(name), name);
readVFS(std::make_unique<VFS::FileSystemArchive>(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)

@ -78,8 +78,7 @@ CS::Editor::~Editor ()
mPidFile.close();
if(mServer && std::filesystem::exists(mPid))
static_cast<void> ( // 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<std::filesystem::path> 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");

@ -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<std::filesystem::path>::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);

@ -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
{

@ -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);
}

@ -72,7 +72,7 @@ void CSMDoc::WriteHeaderStage::perform (int stage, Messages& messages)
for (std::vector<std::filesystem::path>::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);

@ -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();

@ -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()

@ -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";

@ -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<std::filesystem::path>& 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;

@ -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))

@ -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);

@ -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

@ -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);

@ -102,7 +102,7 @@ void CSVTools::Merge::configure (CSMDoc::Document *document)
for (std::vector<std::filesystem::path>::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)

@ -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<osg::Image> 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<void (std::string)>(ScheduleNonDialogMessageBox {})
@ -777,35 +777,34 @@ void OMW::Engine::prepareEngine()
mViewer->addEventHandler(mScreenCaptureHandler);
mLuaManager = std::make_unique<MWLua::LuaManager>(mVFS.get(), (mResDir / "lua_libs").string());
mLuaManager = std::make_unique<MWLua::LuaManager>(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<osg::GLExtensions> 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<MWGui::WindowManager>(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<MWInput::InputManager>(mWindow, mViewer, mScreenCaptureHandler,
@ -854,7 +853,7 @@ void OMW::Engine::prepareEngine()
// Create the world
mWorld = std::make_unique<MWWorld::World>(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;
}

@ -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);

@ -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<Files::MaybeQuotedPath>().string());
Version::Version v = Version::getOpenmwVersion(variables["resources"].as<Files::MaybeQuotedPath>());
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<Files::MaybeQuotedPath>().string());
Version::Version v = Version::getOpenmwVersion(variables["resources"].as<Files::MaybeQuotedPath>());
Log(Debug::Info) << v.describe();
engine.setGrabMouse(!variables["no-grab"].as<bool>());
@ -150,7 +150,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
engine.setWarningsMode (variables["script-warn"].as<int>());
engine.setScriptBlacklist (variables["script-blacklist"].as<StringsVector>());
engine.setScriptBlacklistUse (variables["script-blacklist-use"].as<bool>());
engine.setSaveGameFile (variables["load-savegame"].as<Files::MaybeQuotedPath>().string());
engine.setSaveGameFile (variables["load-savegame"].as<Files::MaybeQuotedPath>());
// other settings
Fallback::Map::init(variables["fallback"].as<FallbackMap>().mMap);

@ -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

@ -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;

@ -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);
}
}

@ -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<osgMyGUI::Platform>(viewer, guiRoot, resourceSystem->getImageManager(),
resourceSystem->getVFS(), mScalingFactor, "mygui",
(std::filesystem::path(logpath) / "MyGUI.log").generic_string());
logpath / "MyGUI.log");
mGui = std::make_unique<MyGUI::Gui>();
mGui->initialise("");

@ -37,6 +37,7 @@
#include <MyGUI_Gui.h>
#include <MyGUI_KeyCode.h>
#include <MyGUI_Types.h>
#include <filesystem>
namespace MyGUI
{
@ -124,7 +125,7 @@ namespace MWGui
typedef std::vector<Faction> 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();

@ -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<InputControlSystem>(file);
mListener = std::make_unique<BindingsListener>(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)

@ -4,6 +4,7 @@
#include <memory>
#include <string>
#include <vector>
#include <filesystem>
#include <components/sdlutil/events.hpp>
@ -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<InputControlSystem> mInputBinder;
std::unique_ptr<BindingsListener> mListener;
std::string mUserFile;
std::filesystem::path mUserFile;
bool mDragDrop;
};

@ -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

@ -5,6 +5,7 @@
#include <components/settings/settings.hpp>
#include <components/sdlutil/events.hpp>
#include <filesystem>
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;

@ -28,8 +28,8 @@ namespace MWInput
osg::ref_ptr<osgViewer::Viewer> viewer,
osg::ref_ptr<osgViewer::ScreenCaptureHandler> 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<SDLUtil::InputWrapper>(window, viewer, grab))
, mBindingsManager(std::make_unique<BindingsManager>(userFile, userFileExists))

@ -8,6 +8,7 @@
#include <components/settings/settings.hpp>
#include <components/sdlutil/events.hpp>
#include <filesystem>
#include "../mwbase/inputmanager.hpp"
@ -52,9 +53,9 @@ namespace MWInput
osg::ref_ptr<osgViewer::Viewer> viewer,
osg::ref_ptr<osgViewer::ScreenCaptureHandler> 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;

@ -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()

@ -11,6 +11,7 @@
#include <components/lua_ui/resources.hpp>
#include <components/misc/color.hpp>
#include <filesystem>
#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.

@ -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();
}

@ -369,7 +369,7 @@ namespace MWRender
};
RenderingManager::RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> 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())

@ -102,7 +102,7 @@ namespace MWRender
{
public:
RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> 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;

@ -238,21 +238,21 @@ private:
float mRainIntensity;
};
osg::ref_ptr<osg::Image> readPngImage (const std::string& file)
osg::ref_ptr<osg::Image> 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<osg::Image>();
}
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<osg::Shader> fragmentShader(shaderMgr.getShader("water_fragment.glsl", defineMap, osg::Shader::FRAGMENT));
osg::ref_ptr<osg::Program> program = shaderMgr.getProgram(vertexShader, fragmentShader);
osg::ref_ptr<osg::Texture2D> normalMap(new osg::Texture2D(readPngImage(mResourcePath + "/shaders/water_nm.png")));
osg::ref_ptr<osg::Texture2D> normalMap(new osg::Texture2D(readPngImage(mResourcePath / "shaders" / "water_nm.png")));
if (normalMap->getImage())
normalMap->getImage()->flipVertical();

@ -65,7 +65,7 @@ namespace MWRender
osg::ref_ptr<Refraction> mRefraction;
osg::ref_ptr<Reflection> 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);

@ -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
}
}
};

@ -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
}

@ -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)
{

@ -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;

@ -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<std::size_t>(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();
}

@ -321,13 +321,13 @@ ESM::LuaScriptsCfg ESMStore::getLuaScriptsCfg() const
ESM::LuaScriptsCfg cfg;
for (const LuaContent& c : mLuaContent)
{
if (std::holds_alternative<std::string>(c))
if (std::holds_alternative<std::filesystem::path>(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<std::string>(c));
auto file = std::ifstream(std::get<std::filesystem::path>(c));
std::string fileContent(std::istreambuf_iterator<char>(file), {});
LuaUtil::parseOMWScripts(cfg, fileContent);
}

@ -5,6 +5,7 @@
#include <stdexcept>
#include <unordered_map>
#include <tuple>
#include <filesystem>
#include <components/esm/luascripts.hpp>
#include <components/esm3/loadgmst.hpp>
@ -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<LuaContent> 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<StoreBase>

@ -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<std::string>& 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);

@ -109,7 +109,7 @@ namespace MWWorld
bool mDiscardMovements;
std::vector<std::string> mContentFiles;
std::string mUserDataPath;
std::filesystem::path mUserDataPath;
osg::Vec3f mDefaultHalfExtents;
DetourNavigator::CollisionShapeType mDefaultActorCollisionShapeType;
@ -203,7 +203,7 @@ namespace MWWorld
const std::vector<std::string>& 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;

@ -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)

@ -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<std::streamsize>(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);
}

@ -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<int>(mLua, "permanent:get('x')"), 1);
EXPECT_EQ(get<int>(mLua, "temporary:get('y')"), 2);

@ -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<ESM::Dialogue>& dialStore = mEsmStore.get<ESM::Dialogue>();
@ -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:

@ -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));

@ -19,7 +19,7 @@ namespace
template <typename F>
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");
{

@ -17,7 +17,7 @@ namespace
template <typename F>
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());
});
}
}
}

@ -30,7 +30,7 @@ namespace
template <class F>
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
});
}
}

@ -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<std::stringstream>(mContent, std::ios_base::in);
}
std::string getPath() override
std::filesystem::path getPath() override
{
return "TestFile";
}

@ -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);

@ -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
}

@ -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);

@ -27,6 +27,7 @@
#include <cstdint>
#include <string>
#include <vector>
#include <filesystem>
#include <components/files/istreamptr.hpp>
@ -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
}
};

@ -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);

@ -29,6 +29,7 @@
#include <map>
#include <components/bsa/bsa_file.hpp>
#include <filesystem>
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;

@ -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 {};
}

@ -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); }

@ -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);

@ -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())
{

@ -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)
{

@ -9,6 +9,8 @@
#include "windows_crashshm.hpp"
#include <SDL_messagebox.h>
#include <components/misc/stringops.hpp>
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

@ -1,7 +1,7 @@
#ifndef WINDOWS_CRASHCATCHER_HPP
#define WINDOWS_CRASHCATCHER_HPP
#include <string>
#include <filesystem>
#include <components/windows.hpp>
#include <components/crashcatcher/crashcatcher.hpp>
@ -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();

@ -269,7 +269,7 @@ Misc::Locked<std::ostream&> 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)

@ -34,7 +34,7 @@ std::ostream& getRawStderr();
Misc::Locked<std::ostream&> 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);

@ -7,7 +7,7 @@
namespace DetourNavigator
{
std::unique_ptr<Navigator> makeNavigator(const Settings& settings, const std::string& userDataPath)
std::unique_ptr<Navigator> makeNavigator(const Settings& settings, const std::filesystem::path& userDataPath)
{
DetourNavigator::RecastGlobalAllocator::init();
@ -16,7 +16,7 @@ namespace DetourNavigator
{
try
{
db = std::make_unique<NavMeshDb>(userDataPath + "/navmesh.db", settings.mMaxDbFileSize);
db = std::make_unique<NavMeshDb>((userDataPath / "navmesh.db").string(), settings.mMaxDbFileSize); //TODO(Project579): This will probably break in windows with unicode paths
}
catch (const std::exception& e)
{

@ -1,6 +1,8 @@
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVIGATOR_H
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVIGATOR_H
#include <filesystem>
#include "objectid.hpp"
#include "sharednavmeshcacheitem.hpp"
#include "recastmeshtiles.hpp"
@ -10,7 +12,6 @@
#include <components/resource/bulletshape.hpp>
#include <string_view>
namespace ESM
{
@ -195,7 +196,7 @@ namespace DetourNavigator
virtual float getMaxNavmeshAreaRealRadius() const = 0;
};
std::unique_ptr<Navigator> makeNavigator(const Settings& settings, const std::string& userDataPath);
std::unique_ptr<Navigator> makeNavigator(const Settings& settings, const std::filesystem::path& userDataPath);
std::unique_ptr<Navigator> makeNavigatorStub();
}

@ -9,6 +9,7 @@
#include <cassert>
#include <limits>
#include <type_traits>
#include <filesystem>
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;

@ -73,8 +73,7 @@ void ESMReader::resolveParentFileIndices(ReadersCache& readers)
const ESM::ReadersCache::BusyItem reader = readers.get(static_cast<std::size_t>(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<std::istream>&& stream, std::string_view name)
void ESMReader::openRaw(std::unique_ptr<std::istream>&& stream, const std::filesystem::path &name)
{
close();
mEsm = std::move(stream);
@ -95,12 +94,12 @@ void ESMReader::openRaw(std::unique_ptr<std::istream>&& 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<std::istream>&& stream, const std::string &name)
void ESMReader::open(std::unique_ptr<std::istream>&& stream, const std::filesystem::path &name)
{
openRaw(std::move(stream), name);
@ -112,7 +111,7 @@ void ESMReader::open(std::unique_ptr<std::istream>&& 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())

@ -5,6 +5,7 @@
#include <vector>
#include <istream>
#include <memory>
#include <filesystem>
#include <components/to_utf8/to_utf8.hpp>
@ -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<std::istream>&& stream, std::string_view name);
void openRaw(std::unique_ptr<std::istream>&& 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<std::istream>&& stream, const std::string &name);
void open(std::unique_ptr<std::istream>&& 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(); };

@ -131,7 +131,7 @@ namespace ESM
{
if(!overriding)
mWater = std::numeric_limits<float>::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;

@ -25,7 +25,7 @@ namespace ESM
{
State mState = State::Busy;
ESMReader mReader;
std::optional<std::string> mName;
std::optional<std::filesystem::path> mName;
Item() = default;
};

@ -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())

@ -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<Reader*>* 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; }

@ -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<int>(i));
reader->open(collection.getPath(file).string());
reader->open(collection.getPath(file));
if (query.mLoadCells)
reader->resolveParentFileIndices(readers);

@ -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;
}
}

@ -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;

@ -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<bpo::variables_map> 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

@ -1,8 +1,10 @@
#include <filesystem>
#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<ConstrainedFileStream>(std::make_unique<ConstrainedFileStreamBuf>(filename, start, length));
}

@ -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<ConstrainedFileStreamBuf>;
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<std::size_t>::max());
}

@ -2,12 +2,13 @@
#include <algorithm>
#include <limits>
#include <filesystem>
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());

@ -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;

@ -9,7 +9,7 @@
namespace Files
{
std::array<std::uint64_t, 2> getHash(const std::string& fileName, std::istream& stream)
std::array<std::uint64_t, 2> getHash(const std::filesystem::path& fileName, std::istream& stream)
{
std::array<std::uint64_t, 2> 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;
}

@ -4,11 +4,11 @@
#include <array>
#include <cstdint>
#include <iosfwd>
#include <string>
#include <filesystem>
namespace Files
{
std::array<std::uint64_t, 2> getHash(const std::string& fileName, std::istream& stream);
std::array<std::uint64_t, 2> getHash(const std::filesystem::path& fileName, std::istream& stream);
}
#endif

@ -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;
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save