chore: parse includes and assetlists while parsing zone definition

This commit is contained in:
Jan
2025-01-01 18:13:23 +01:00
parent 9852f52a15
commit aa212e0958
74 changed files with 530 additions and 437 deletions

View File

@ -198,17 +198,7 @@ namespace
std::unique_ptr<menu::ParsingResult> ParseMenuFile(std::istream& stream, const std::string& menuFileName, const menu::MenuAssetZoneState* zoneState)
{
menu::MenuFileReader reader(stream,
menuFileName,
menu::FeatureLevel::IW4,
[this](const std::string& filename, const std::string& sourceFile) -> std::unique_ptr<std::istream>
{
auto foundFileToInclude = m_search_path.Open(filename);
if (!foundFileToInclude.IsOpen() || !foundFileToInclude.m_stream)
return nullptr;
return std::move(foundFileToInclude.m_stream);
});
menu::MenuFileReader reader(stream, menuFileName, menu::FeatureLevel::IW4, m_search_path);
reader.IncludeZoneState(zoneState);
reader.SetPermissiveMode(ObjLoading::Configuration.MenuPermissiveParsing);

View File

@ -26,16 +26,7 @@ namespace
if (!file.IsOpen())
return AssetCreationResult::NoAction();
StructuredDataDefReader reader(*file.m_stream,
assetName,
[this](const std::string& filename, const std::string& sourceFile) -> std::unique_ptr<std::istream>
{
auto foundFileToInclude = m_search_path.Open(filename);
if (!foundFileToInclude.IsOpen() || !foundFileToInclude.m_stream)
return nullptr;
return std::move(foundFileToInclude.m_stream);
});
StructuredDataDefReader reader(*file.m_stream, assetName, m_search_path);
bool readingDefsSuccessful;
const auto defs = reader.ReadStructureDataDefs(readingDefsSuccessful);

View File

@ -198,17 +198,7 @@ namespace
std::unique_ptr<menu::ParsingResult> ParseMenuFile(std::istream& stream, const std::string& menuFileName, const menu::MenuAssetZoneState* zoneState)
{
menu::MenuFileReader reader(stream,
menuFileName,
menu::FeatureLevel::IW4,
[this](const std::string& filename, const std::string& sourceFile) -> std::unique_ptr<std::istream>
{
auto foundFileToInclude = m_search_path.Open(filename);
if (!foundFileToInclude.IsOpen() || !foundFileToInclude.m_stream)
return nullptr;
return std::move(foundFileToInclude.m_stream);
});
menu::MenuFileReader reader(stream, menuFileName, menu::FeatureLevel::IW5, m_search_path);
reader.IncludeZoneState(zoneState);
reader.SetPermissiveMode(ObjLoading::Configuration.MenuPermissiveParsing);

View File

@ -11,36 +11,22 @@
using namespace menu;
MenuFileReader::MenuFileReader(std::istream& stream, std::string fileName, const FeatureLevel featureLevel, include_callback_t includeCallback)
: m_feature_level(featureLevel),
MenuFileReader::MenuFileReader(std::istream& stream, std::string fileName, const FeatureLevel featureLevel, ISearchPath& searchPath)
: SearchPathMultiInputStream(searchPath),
m_feature_level(featureLevel),
m_file_name(std::move(fileName)),
m_stream(nullptr),
m_zone_state(nullptr),
m_permissive_mode(false)
{
OpenBaseStream(stream, std::move(includeCallback));
OpenBaseStream(stream);
SetupStreamProxies();
m_stream = m_open_streams.back().get();
}
MenuFileReader::MenuFileReader(std::istream& stream, std::string fileName, const FeatureLevel featureLevel)
: m_feature_level(featureLevel),
m_file_name(std::move(fileName)),
m_stream(nullptr),
m_zone_state(nullptr),
m_permissive_mode(false)
bool MenuFileReader::OpenBaseStream(std::istream& stream)
{
OpenBaseStream(stream, nullptr);
SetupStreamProxies();
m_stream = m_open_streams.back().get();
}
bool MenuFileReader::OpenBaseStream(std::istream& stream, include_callback_t includeCallback)
{
if (includeCallback)
m_open_streams.emplace_back(std::make_unique<ParserMultiInputStream>(stream, m_file_name, std::move(includeCallback)));
else
m_open_streams.emplace_back(std::make_unique<ParserSingleInputStream>(stream, m_file_name));
m_open_streams.emplace_back(std::make_unique<ParserMultiInputStream>(stream, m_file_name, *this));
return true;
}

View File

@ -5,6 +5,8 @@
#include "MenuAssetZoneState.h"
#include "MenuFileParserState.h"
#include "Parsing/IParserLineStream.h"
#include "SearchPath/ISearchPath.h"
#include "SearchPath/SearchPathMultiInputStream.h"
#include <memory>
#include <string>
@ -12,12 +14,24 @@
namespace menu
{
class MenuFileReader
class MenuFileReader : public SearchPathMultiInputStream
{
public:
using include_callback_t = std::function<std::unique_ptr<std::istream>(const std::string& filename, const std::string& sourceFile)>;
MenuFileReader(std::istream& stream, std::string fileName, FeatureLevel featureLevel, ISearchPath& searchPath);
void IncludeZoneState(const MenuAssetZoneState* zoneState);
void SetPermissiveMode(bool usePermissiveMode);
std::unique_ptr<ParsingResult> ReadMenuFile();
private:
bool OpenBaseStream(std::istream& stream);
void SetupDefinesProxy();
void SetupStreamProxies();
bool IsValidEndState(const MenuFileParserState* state) const;
std::unique_ptr<ParsingResult> CreateParsingResult(MenuFileParserState* state) const;
const FeatureLevel m_feature_level;
const std::string m_file_name;
@ -26,21 +40,5 @@ namespace menu
const MenuAssetZoneState* m_zone_state;
bool m_permissive_mode;
bool OpenBaseStream(std::istream& stream, include_callback_t includeCallback);
void SetupDefinesProxy();
void SetupStreamProxies();
bool IsValidEndState(const MenuFileParserState* state) const;
std::unique_ptr<ParsingResult> CreateParsingResult(MenuFileParserState* state) const;
public:
MenuFileReader(std::istream& stream, std::string fileName, FeatureLevel featureLevel);
MenuFileReader(std::istream& stream, std::string fileName, FeatureLevel featureLevel, include_callback_t includeCallback);
void IncludeZoneState(const MenuAssetZoneState* zoneState);
void SetPermissiveMode(bool usePermissiveMode);
std::unique_ptr<ParsingResult> ReadMenuFile();
};
} // namespace menu

View File

@ -1,17 +0,0 @@
#include "ISearchPath.h"
bool SearchPathOpenFile::IsOpen() const
{
return m_stream != nullptr;
}
SearchPathOpenFile::SearchPathOpenFile()
: m_length(0)
{
}
SearchPathOpenFile::SearchPathOpenFile(std::unique_ptr<std::istream> stream, const int64_t length)
: m_stream(std::move(stream)),
m_length(length)
{
}

View File

@ -1,63 +0,0 @@
#pragma once
#include "SearchPathSearchOptions.h"
#include "Utils/ClassUtils.h"
#include <cstdint>
#include <functional>
#include <istream>
#include <memory>
#include <string>
class SearchPathOpenFile
{
public:
std::unique_ptr<std::istream> m_stream;
int64_t m_length;
_NODISCARD bool IsOpen() const;
SearchPathOpenFile();
SearchPathOpenFile(std::unique_ptr<std::istream> stream, int64_t length);
};
class ISearchPath
{
public:
ISearchPath() = default;
virtual ~ISearchPath() = default;
ISearchPath(const ISearchPath& other) = default;
ISearchPath(ISearchPath&& other) noexcept = default;
ISearchPath& operator=(const ISearchPath& other) = default;
ISearchPath& operator=(ISearchPath&& other) noexcept = default;
/**
* \brief Opens a file relative to the search path.
* \param fileName The relative path to the file to open.
* \return A pointer to an \c IFile object to read the found file or \c nullptr when no file could be found.
*/
virtual SearchPathOpenFile Open(const std::string& fileName) = 0;
/**
* \brief Returns the path to the search path.
* \return The path to the search path.
*/
virtual const std::string& GetPath() = 0;
/**
* \brief Iterates through all files of the search path.
* \param callback The callback to call for each found file with it's path relative to the search path.
* \param options Options that modify the search.
*/
virtual void Find(const SearchPathSearchOptions& options, const std::function<void(const std::string&)>& callback) = 0;
/**
* \brief Iterates through all files of the search path.
* \param callback The callback to call for each found file with it's path relative to the search path.
*/
void Find(const std::function<void(const std::string&)>& callback)
{
Find(SearchPathSearchOptions(), callback);
}
};

View File

@ -1,64 +0,0 @@
#include "SearchPathFilesystem.h"
#include "Utils/ObjFileStream.h"
#include <filesystem>
#include <format>
#include <fstream>
#include <iostream>
namespace fs = std::filesystem;
SearchPathFilesystem::SearchPathFilesystem(std::string path)
: m_path(std::move(path))
{
}
const std::string& SearchPathFilesystem::GetPath()
{
return m_path;
}
SearchPathOpenFile SearchPathFilesystem::Open(const std::string& fileName)
{
const auto filePath = fs::path(m_path).append(fileName);
std::ifstream file(filePath.string(), std::fstream::in | std::fstream::binary);
if (file.is_open())
return SearchPathOpenFile(std::make_unique<std::ifstream>(std::move(file)), static_cast<int64_t>(file_size(filePath)));
return SearchPathOpenFile();
}
void SearchPathFilesystem::Find(const SearchPathSearchOptions& options, const std::function<void(const std::string&)>& callback)
{
try
{
if (options.m_should_include_subdirectories)
{
std::filesystem::recursive_directory_iterator iterator(m_path);
for (const auto entry = begin(iterator); iterator != end(iterator); ++iterator)
{
auto path = entry->path();
if (options.m_filter_extensions && path.extension().string() != options.m_extension)
continue;
callback(options.m_absolute_paths ? absolute(path).string() : path.string());
}
}
else
{
std::filesystem::directory_iterator iterator(m_path);
for (const auto entry = begin(iterator); iterator != end(iterator); ++iterator)
{
auto path = entry->path();
if (options.m_filter_extensions && path.extension().string() != options.m_extension)
continue;
callback(options.m_absolute_paths ? absolute(path).string() : path.string());
}
}
}
catch (std::filesystem::filesystem_error& e)
{
std::cerr << std::format("Directory Iterator threw error when trying to find files: \"{}\"\n", e.what());
}
}

View File

@ -1,17 +0,0 @@
#pragma once
#include "ISearchPath.h"
#include <string>
class SearchPathFilesystem final : public ISearchPath
{
std::string m_path;
public:
explicit SearchPathFilesystem(std::string path);
SearchPathOpenFile Open(const std::string& fileName) override;
const std::string& GetPath() override;
void Find(const SearchPathSearchOptions& options, const std::function<void(const std::string&)>& callback) override;
};

View File

@ -1,41 +0,0 @@
#include "SearchPathSearchOptions.h"
SearchPathSearchOptions::SearchPathSearchOptions()
{
m_should_include_subdirectories = true;
m_disk_files_only = false;
m_absolute_paths = false;
m_filter_extensions = false;
}
SearchPathSearchOptions& SearchPathSearchOptions::IncludeSubdirectories(const bool value)
{
m_should_include_subdirectories = value;
return *this;
}
SearchPathSearchOptions& SearchPathSearchOptions::OnlyDiskFiles(const bool value)
{
m_disk_files_only = value;
return *this;
}
SearchPathSearchOptions& SearchPathSearchOptions::AbsolutePaths(const bool value)
{
m_absolute_paths = value;
return *this;
}
SearchPathSearchOptions& SearchPathSearchOptions::FilterExtensions(std::string extension)
{
m_extension = std::move(extension);
m_filter_extensions = true;
if (m_extension[0] != '.')
m_extension = "." + m_extension;
return *this;
}

View File

@ -1,21 +0,0 @@
#pragma once
#include <string>
class SearchPathSearchOptions
{
public:
bool m_should_include_subdirectories;
bool m_disk_files_only;
bool m_absolute_paths;
bool m_filter_extensions;
std::string m_extension;
SearchPathSearchOptions();
SearchPathSearchOptions& IncludeSubdirectories(bool value);
SearchPathSearchOptions& OnlyDiskFiles(bool value);
SearchPathSearchOptions& AbsolutePaths(bool value);
SearchPathSearchOptions& FilterExtensions(std::string extension);
};

View File

@ -1,68 +0,0 @@
#include "SearchPaths.h"
#include <cassert>
#include <filesystem>
SearchPathOpenFile SearchPaths::Open(const std::string& fileName)
{
for (auto* searchPathEntry : m_search_paths)
{
auto file = searchPathEntry->Open(fileName);
if (file.IsOpen())
{
return file;
}
}
return SearchPathOpenFile();
}
const std::string& SearchPaths::GetPath()
{
static const std::string STATIC_NAME = "SearchPaths";
return STATIC_NAME;
}
void SearchPaths::Find(const SearchPathSearchOptions& options, const std::function<void(const std::string&)>& callback)
{
for (auto* searchPathEntry : m_search_paths)
{
searchPathEntry->Find(options, callback);
}
}
void SearchPaths::CommitSearchPath(std::unique_ptr<ISearchPath> searchPath)
{
m_search_paths.push_back(searchPath.get());
m_owned_search_paths.emplace_back(std::move(searchPath));
}
void SearchPaths::IncludeSearchPath(ISearchPath* searchPath)
{
assert(searchPath);
m_search_paths.push_back(searchPath);
}
void SearchPaths::RemoveSearchPath(const ISearchPath* searchPath)
{
assert(searchPath);
for (auto i = m_search_paths.begin(); i != m_search_paths.end(); ++i)
{
if (*i == searchPath)
{
m_search_paths.erase(i);
return;
}
}
}
SearchPaths::iterator SearchPaths::begin()
{
return m_search_paths.begin();
}
SearchPaths::iterator SearchPaths::end()
{
return m_search_paths.end();
}

View File

@ -1,48 +0,0 @@
#pragma once
#include "ISearchPath.h"
#include <string>
#include <vector>
class SearchPaths final : public ISearchPath
{
std::vector<ISearchPath*> m_search_paths;
std::vector<std::unique_ptr<ISearchPath>> m_owned_search_paths;
public:
using iterator = std::vector<ISearchPath*>::iterator;
SearchPaths() = default;
~SearchPaths() override = default;
SearchPathOpenFile Open(const std::string& fileName) override;
const std::string& GetPath() override;
void Find(const SearchPathSearchOptions& options, const std::function<void(const std::string&)>& callback) override;
SearchPaths(const SearchPaths& other) = delete;
SearchPaths(SearchPaths&& other) noexcept = default;
SearchPaths& operator=(const SearchPaths& other) = delete;
SearchPaths& operator=(SearchPaths&& other) noexcept = default;
/**
* \brief Adds a search path that gets deleted upon destruction of the \c SearchPaths object.
* \param searchPath The search path to add.
*/
void CommitSearchPath(std::unique_ptr<ISearchPath> searchPath);
/**
* \brief Adds a search path that does \b NOT get deleted upon destruction of the \c SearchPaths object.
* \param searchPath The search path to add.
*/
void IncludeSearchPath(ISearchPath* searchPath);
/**
* \brief Removes a search path from the \c SearchPaths object. If the search path was committed then it will \b NOT be deleted when destructing the \c
* SearchPaths object. \param searchPath The search path to remove.
*/
void RemoveSearchPath(const ISearchPath* searchPath);
iterator begin();
iterator end();
};

View File

@ -7,28 +7,24 @@
#include "Parsing/Impl/ParserSingleInputStream.h"
#include "StructuredDataDef/Parsing/StructuredDataDefParser.h"
#include <format>
#include <iostream>
using namespace sdd;
StructuredDataDefReader::StructuredDataDefReader(std::istream& stream, std::string fileName)
: StructuredDataDefReader(stream, std::move(fileName), nullptr)
{
}
StructuredDataDefReader::StructuredDataDefReader(std::istream& stream, std::string fileName, include_callback_t includeCallback)
: m_file_name(std::move(fileName)),
StructuredDataDefReader::StructuredDataDefReader(std::istream& stream, std::string fileName, ISearchPath& searchPath)
: SearchPathMultiInputStream(searchPath),
m_file_name(std::move(fileName)),
m_stream(nullptr)
{
OpenBaseStream(stream, std::move(includeCallback));
OpenBaseStream(stream);
SetupStreamProxies();
m_stream = m_open_streams.back().get();
}
bool StructuredDataDefReader::OpenBaseStream(std::istream& stream, include_callback_t includeCallback)
bool StructuredDataDefReader::OpenBaseStream(std::istream& stream)
{
if (includeCallback)
m_open_streams.emplace_back(std::make_unique<ParserMultiInputStream>(stream, m_file_name, std::move(includeCallback)));
else
m_open_streams.emplace_back(std::make_unique<ParserSingleInputStream>(stream, m_file_name));
m_open_streams.emplace_back(std::make_unique<ParserMultiInputStream>(stream, m_file_name, *this));
return true;
}
@ -58,6 +54,7 @@ std::vector<std::unique_ptr<CommonStructuredDataDef>> StructuredDataDefReader::R
if (success)
return parser->GetDefs();
std::cout << "Parsing structured data def file \"" << m_file_name << "\" failed!\n";
std::cerr << std::format("Parsing structured data def file \"{}\" failed!\n", m_file_name);
return {};
}

View File

@ -1,28 +1,26 @@
#pragma once
#include "Parsing/IParserLineStream.h"
#include "SearchPath/ISearchPath.h"
#include "SearchPath/SearchPathMultiInputStream.h"
#include "StructuredDataDef/CommonStructuredDataDef.h"
#include <memory>
#include <string>
#include <vector>
class StructuredDataDefReader
class StructuredDataDefReader : public SearchPathMultiInputStream
{
public:
using include_callback_t = std::function<std::unique_ptr<std::istream>(const std::string& filename, const std::string& sourceFile)>;
StructuredDataDefReader(std::istream& stream, std::string fileName, ISearchPath& searchPath);
std::vector<std::unique_ptr<CommonStructuredDataDef>> ReadStructureDataDefs(bool& success);
private:
bool OpenBaseStream(std::istream& stream);
void SetupStreamProxies();
std::string m_file_name;
IParserLineStream* m_stream;
std::vector<std::unique_ptr<IParserLineStream>> m_open_streams;
bool OpenBaseStream(std::istream& stream, include_callback_t includeCallback);
void SetupStreamProxies();
public:
StructuredDataDefReader(std::istream& stream, std::string fileName);
StructuredDataDefReader(std::istream& stream, std::string fileName, include_callback_t includeCallback);
std::vector<std::unique_ptr<CommonStructuredDataDef>> ReadStructureDataDefs(bool& success);
};