1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-03-29 03:36:40 +00:00

Simplify and reduce code duplication for BSA archive creation

This commit is contained in:
elsid 2024-01-30 01:13:19 +01:00
parent a2345194c8
commit df077a2524
No known key found for this signature in database
GPG key ID: 4DE04C198CBA7625
3 changed files with 34 additions and 66 deletions

View file

@ -42,29 +42,10 @@ bool isBSA(const std::filesystem::path& filename)
return hasExtension(filename, ".bsa") || hasExtension(filename, ".ba2"); return hasExtension(filename, ".bsa") || hasExtension(filename, ".ba2");
} }
std::unique_ptr<VFS::Archive> makeBsaArchive(const std::filesystem::path& path)
{
switch (Bsa::BSAFile::detectVersion(path))
{
case Bsa::BSAVER_COMPRESSED:
return std::make_unique<VFS::ArchiveSelector<Bsa::BSAVER_COMPRESSED>::type>(path);
case Bsa::BSAVER_BA2_GNRL:
return std::make_unique<VFS::ArchiveSelector<Bsa::BSAVER_BA2_GNRL>::type>(path);
case Bsa::BSAVER_BA2_DX10:
return std::make_unique<VFS::ArchiveSelector<Bsa::BSAVER_BA2_DX10>::type>(path);
case Bsa::BSAVER_UNCOMPRESSED:
return std::make_unique<VFS::ArchiveSelector<Bsa::BSAVER_UNCOMPRESSED>::type>(path);
case Bsa::BSAVER_UNKNOWN:
default:
std::cerr << "'" << Files::pathToUnicodeString(path) << "' is not a recognized BSA archive" << std::endl;
return nullptr;
}
}
std::unique_ptr<VFS::Archive> makeArchive(const std::filesystem::path& path) std::unique_ptr<VFS::Archive> makeArchive(const std::filesystem::path& path)
{ {
if (isBSA(path)) if (isBSA(path))
return makeBsaArchive(path); return VFS::makeBsaArchive(path);
if (std::filesystem::is_directory(path)) if (std::filesystem::is_directory(path))
return std::make_unique<VFS::FileSystemArchive>(path); return std::make_unique<VFS::FileSystemArchive>(path);
return nullptr; return nullptr;
@ -124,17 +105,23 @@ void readVFS(std::unique_ptr<VFS::Archive>&& archive, const std::filesystem::pat
if (!archivePath.empty() && !isBSA(archivePath)) if (!archivePath.empty() && !isBSA(archivePath))
{ {
Files::PathContainer dataDirs = { archivePath }; const Files::Collections fileCollections({ archivePath });
const Files::Collections fileCollections = Files::Collections(dataDirs);
const Files::MultiDirCollection& bsaCol = fileCollections.getCollection(".bsa"); const Files::MultiDirCollection& bsaCol = fileCollections.getCollection(".bsa");
const Files::MultiDirCollection& ba2Col = fileCollections.getCollection(".ba2"); const Files::MultiDirCollection& ba2Col = fileCollections.getCollection(".ba2");
for (auto& file : bsaCol) for (const Files::MultiDirCollection& collection : { bsaCol, ba2Col })
{ {
readVFS(makeBsaArchive(file.second), file.second, quiet); for (auto& file : collection)
} {
for (auto& file : ba2Col) try
{ {
readVFS(makeBsaArchive(file.second), file.second, quiet); readVFS(VFS::makeBsaArchive(file.second), file.second, quiet);
}
catch (const std::exception& e)
{
std::cerr << "Failed to read archive file '" << Files::pathToUnicodeString(file.second)
<< "': " << e.what() << std::endl;
}
}
} }
} }
} }

View file

@ -11,6 +11,8 @@
#include <components/bsa/compressedbsafile.hpp> #include <components/bsa/compressedbsafile.hpp>
#include <algorithm> #include <algorithm>
#include <memory>
#include <stdexcept>
namespace VFS namespace VFS
{ {
@ -73,34 +75,24 @@ namespace VFS
std::vector<VFS::Path::Normalized> mFiles; std::vector<VFS::Path::Normalized> mFiles;
}; };
template <Bsa::BsaVersion> inline std::unique_ptr<VFS::Archive> makeBsaArchive(const std::filesystem::path& path)
struct ArchiveSelector
{ {
}; switch (Bsa::BSAFile::detectVersion(path))
{
case Bsa::BSAVER_UNKNOWN:
break;
case Bsa::BSAVER_UNCOMPRESSED:
return std::make_unique<BsaArchive<Bsa::BSAFile>>(path);
case Bsa::BSAVER_COMPRESSED:
return std::make_unique<BsaArchive<Bsa::CompressedBSAFile>>(path);
case Bsa::BSAVER_BA2_GNRL:
return std::make_unique<BsaArchive<Bsa::BA2GNRLFile>>(path);
case Bsa::BSAVER_BA2_DX10:
return std::make_unique<BsaArchive<Bsa::BA2DX10File>>(path);
}
template <> throw std::runtime_error("Unknown archive type '" + Files::pathToUnicodeString(path) + "'");
struct ArchiveSelector<Bsa::BSAVER_UNCOMPRESSED> }
{
using type = BsaArchive<Bsa::BSAFile>;
};
template <>
struct ArchiveSelector<Bsa::BSAVER_COMPRESSED>
{
using type = BsaArchive<Bsa::CompressedBSAFile>;
};
template <>
struct ArchiveSelector<Bsa::BSAVER_BA2_GNRL>
{
using type = BsaArchive<Bsa::BA2GNRLFile>;
};
template <>
struct ArchiveSelector<Bsa::BSAVER_BA2_DX10>
{
using type = BsaArchive<Bsa::BA2DX10File>;
};
} }
#endif #endif

View file

@ -25,18 +25,7 @@ namespace VFS
// Last BSA has the highest priority // Last BSA has the highest priority
const auto archivePath = collections.getPath(*archive); const auto archivePath = collections.getPath(*archive);
Log(Debug::Info) << "Adding BSA archive " << archivePath; Log(Debug::Info) << "Adding BSA archive " << archivePath;
Bsa::BsaVersion bsaVersion = Bsa::BSAFile::detectVersion(archivePath); vfs->addArchive(makeBsaArchive(archivePath));
if (bsaVersion == Bsa::BSAVER_COMPRESSED)
vfs->addArchive(std::make_unique<ArchiveSelector<Bsa::BSAVER_COMPRESSED>::type>(archivePath));
else if (bsaVersion == Bsa::BSAVER_BA2_GNRL)
vfs->addArchive(std::make_unique<ArchiveSelector<Bsa::BSAVER_BA2_GNRL>::type>(archivePath));
else if (bsaVersion == Bsa::BSAVER_BA2_DX10)
vfs->addArchive(std::make_unique<ArchiveSelector<Bsa::BSAVER_BA2_DX10>::type>(archivePath));
else if (bsaVersion == Bsa::BSAVER_UNCOMPRESSED)
vfs->addArchive(std::make_unique<ArchiveSelector<Bsa::BSAVER_UNCOMPRESSED>::type>(archivePath));
else
throw std::runtime_error("Unknown archive type '" + *archive + "'");
} }
else else
{ {