2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-11-17 18:52:06 +00:00

chore: pass ZoneLoading error as result

This commit is contained in:
Jan Laupetin
2025-10-11 15:28:19 +01:00
parent 098be53559
commit b27b7e77bd
9 changed files with 181 additions and 121 deletions

View File

@@ -364,14 +364,16 @@ class LinkerImpl final : public Linker
zoneDirectory = fs::current_path(); zoneDirectory = fs::current_path();
auto absoluteZoneDirectory = absolute(zoneDirectory).string(); auto absoluteZoneDirectory = absolute(zoneDirectory).string();
auto zone = ZoneLoading::LoadZone(zonePath); auto maybeZone = ZoneLoading::LoadZone(zonePath);
if (!zone) if (!maybeZone)
{ {
con::error("Failed to load zone \"{}\".", zonePath); con::error("Failed to load zone \"{}\": {}", zonePath, maybeZone.error());
return false; return false;
} }
con::debug("Load zone \"{}\"", zone->m_name); auto zone = std::move(*maybeZone);
con::debug("Loaded zone \"{}\"", zone->m_name);
m_loaded_zones.emplace_back(std::move(zone)); m_loaded_zones.emplace_back(std::move(zone));
} }

View File

@@ -2,11 +2,11 @@
#include "ZoneLoading.h" #include "ZoneLoading.h"
std::optional<Zone*> FastFileContext::LoadFastFile(const std::string& path) result::Expected<Zone*, std::string> FastFileContext::LoadFastFile(const std::string& path)
{ {
auto zone = ZoneLoading::LoadZone(path); auto zone = ZoneLoading::LoadZone(path);
if (!zone) if (!zone)
return std::nullopt; return result::Unexpected(std::move(zone.error()));
return m_loaded_zones.emplace_back(std::move(zone)).get(); return m_loaded_zones.emplace_back(std::move(*zone)).get();
} }

View File

@@ -1,14 +1,15 @@
#pragma once #pragma once
#include "Utils/Result.h"
#include "Zone/Zone.h" #include "Zone/Zone.h"
#include <memory> #include <memory>
#include <optional>
#include <vector> #include <vector>
class FastFileContext class FastFileContext
{ {
public: public:
std::optional<Zone*> LoadFastFile(const std::string& path); result::Expected<Zone*, std::string> LoadFastFile(const std::string& path);
std::vector<std::unique_ptr<Zone>> m_loaded_zones; std::vector<std::unique_ptr<Zone>> m_loaded_zones;
}; };

View File

@@ -10,7 +10,7 @@ namespace
ModManContext::Get().m_db_thread.Dispatch( ModManContext::Get().m_db_thread.Dispatch(
[&wv, id, path] [&wv, id, path]
{ {
const auto maybeZone = ModManContext::Get().m_fast_file.LoadFastFile(path); auto maybeZone = ModManContext::Get().m_fast_file.LoadFastFile(path);
if (maybeZone) if (maybeZone)
{ {
@@ -19,8 +19,8 @@ namespace
} }
else else
{ {
con::warn("Failed to load zone \"{}\"", path); con::warn("Failed to load zone \"{}\": {}", path, maybeZone.error());
ui::PromiseReject(wv, id, false); ui::PromiseReject(wv, id, std::move(maybeZone).error());
} }
}); });
} }

View File

@@ -12,8 +12,8 @@ async function onOpenFastfileClick() {
loadingFastFile.value = true; loadingFastFile.value = true;
webviewBinds.loadFastFile(lastPath.value) webviewBinds.loadFastFile(lastPath.value)
.catch((e) => { .catch((e: string) => {
console.error("Failed to load fastfile", e); console.error("Failed to load fastfile:", e);
}) })
.finally(() => { .finally(() => {
loadingFastFile.value = false; loadingFastFile.value = false;

View File

@@ -227,13 +227,15 @@ private:
auto absoluteZoneDirectory = absolute(std::filesystem::path(zonePath).remove_filename()).string(); auto absoluteZoneDirectory = absolute(std::filesystem::path(zonePath).remove_filename()).string();
auto searchPathsForZone = paths.GetSearchPathsForZone(absoluteZoneDirectory); auto searchPathsForZone = paths.GetSearchPathsForZone(absoluteZoneDirectory);
auto zone = ZoneLoading::LoadZone(zonePath); auto maybeZone = ZoneLoading::LoadZone(zonePath);
if (zone == nullptr) if (!maybeZone)
{ {
con::error("Failed to load zone \"{}\".", zonePath); con::error("Failed to load zone \"{}\": {}", zonePath, maybeZone.error());
return false; return false;
} }
auto zone = std::move(*maybeZone);
con::debug("Loaded zone \"{}\"", zone->m_name); con::debug("Loaded zone \"{}\"", zone->m_name);
if (ShouldLoadObj()) if (ShouldLoadObj())
@@ -287,16 +289,16 @@ private:
auto searchPathsForZone = paths.GetSearchPathsForZone(absoluteZoneDirectory); auto searchPathsForZone = paths.GetSearchPathsForZone(absoluteZoneDirectory);
std::string zoneName; auto maybeZone = ZoneLoading::LoadZone(zonePath);
auto zone = ZoneLoading::LoadZone(zonePath); if (!maybeZone)
if (zone == nullptr)
{ {
con::error("Failed to load zone \"{}\".", zonePath); con::error("Failed to load zone \"{}\": {}", zonePath, maybeZone.error());
return false; return false;
} }
zoneName = zone->m_name; auto zone = std::move(*maybeZone);
con::debug("Loaded zone \"{}\"", zoneName);
con::debug("Loaded zone \"{}\"", zone->m_name);
const auto* objLoader = IObjLoader::GetObjLoaderForGame(zone->m_game_id); const auto* objLoader = IObjLoader::GetObjLoaderForGame(zone->m_game_id);
if (ShouldLoadObj()) if (ShouldLoadObj())
@@ -308,6 +310,8 @@ private:
if (ShouldLoadObj()) if (ShouldLoadObj())
objLoader->UnloadContainersOfZone(*zone); objLoader->UnloadContainersOfZone(*zone);
// Copy zone name for using it after freeing the zone
std::string zoneName = zone->m_name;
zone.reset(); zone.reset();
con::debug("Unloaded zone \"{}\"", zoneName); con::debug("Unloaded zone \"{}\"", zoneName);
} }

View File

@@ -6,22 +6,81 @@
using NoResult = std::monostate; using NoResult = std::monostate;
// Can be replaced by std::expected with c++23 // Can be replaced by std::expected with c++23
template<typename TResult, typename TError> class Result namespace result
{ {
public: template<typename TError> class Unexpected
Result(TResult result) {
public:
Unexpected(TError result)
: m_data(std::move(result))
{
}
constexpr std::add_lvalue_reference_t<TError> value() &
{
return m_data;
}
constexpr std::add_const_t<std::add_lvalue_reference_t<TError>> value() const&
{
return m_data;
}
constexpr std::add_rvalue_reference_t<TError> value() &&
{
return std::move(m_data);
}
constexpr std::add_const_t<std::add_rvalue_reference_t<TError>> value() const&&
{
return std::move(m_data);
}
constexpr std::add_lvalue_reference_t<TError> operator*() &
{
return m_data;
}
constexpr std::add_const_t<std::add_lvalue_reference_t<TError>> operator*() const&
{
return m_data;
}
constexpr std::add_rvalue_reference_t<TError> operator*() &&
{
return std::move(m_data);
}
constexpr std::add_const_t<std::add_rvalue_reference_t<TError>> operator*() const&&
{
return std::move(m_data);
}
constexpr std::add_pointer_t<TError> operator->()
{
return m_data;
}
constexpr std::add_const_t<std::add_pointer_t<TError>> operator->() const
{
return m_data;
}
private:
TError m_data;
};
template<typename TResult, typename TError> class Expected
{
public:
Expected(TResult result)
: m_data(std::variant<TResult, TError>(std::in_place_index<0>, std::move(result))) : m_data(std::variant<TResult, TError>(std::in_place_index<0>, std::move(result)))
{ {
} }
static Result Ok(TResult result) Expected(Unexpected<TError> unexpected)
: m_data(std::variant<TResult, TError>(std::in_place_index<1>, std::move(*unexpected)))
{ {
return Result(std::in_place_index<0>, std::move(result));
}
static Result Bad(TError error)
{
return Result(std::in_place_index<1>, std::move(error));
} }
constexpr operator bool() const noexcept constexpr operator bool() const noexcept
@@ -36,82 +95,82 @@ public:
constexpr std::add_lvalue_reference_t<TResult> value() & constexpr std::add_lvalue_reference_t<TResult> value() &
{ {
return std::get<0, TResult>(m_data); return std::get<0>(m_data);
} }
constexpr std::add_const_t<std::add_lvalue_reference_t<TResult>> value() const& constexpr std::add_const_t<std::add_lvalue_reference_t<TResult>> value() const&
{ {
return std::get<0, TResult>(m_data); return std::get<0>(m_data);
} }
constexpr std::add_rvalue_reference_t<TResult> value() && constexpr std::add_rvalue_reference_t<TResult> value() &&
{ {
return std::move(std::get<0, TResult>(m_data)); return std::move(std::get<0>(m_data));
} }
constexpr std::add_const_t<std::add_rvalue_reference_t<TResult>> value() const&& constexpr std::add_const_t<std::add_rvalue_reference_t<TResult>> value() const&&
{ {
return std::move(std::get<0, TResult>(m_data)); return std::move(std::get<0>(m_data));
} }
constexpr std::add_lvalue_reference_t<TResult> operator*() & constexpr std::add_lvalue_reference_t<TResult> operator*() &
{ {
return std::get<0, TResult>(m_data); return std::get<0>(m_data);
} }
constexpr std::add_const_t<std::add_lvalue_reference_t<TResult>> operator*() const& constexpr std::add_const_t<std::add_lvalue_reference_t<TResult>> operator*() const&
{ {
return std::get<0, TResult>(m_data); return std::get<0>(m_data);
} }
constexpr std::add_rvalue_reference_t<TResult> operator*() && constexpr std::add_rvalue_reference_t<TResult> operator*() &&
{ {
return std::move(std::get<0, TResult>(m_data)); return std::move(std::get<0>(m_data));
} }
constexpr std::add_const_t<std::add_rvalue_reference_t<TResult>> operator*() const&& constexpr std::add_const_t<std::add_rvalue_reference_t<TResult>> operator*() const&&
{ {
return std::move(std::get<0, TResult>(m_data)); return std::move(std::get<0>(m_data));
} }
constexpr std::add_pointer_t<TResult> operator->() constexpr std::add_pointer_t<TResult> operator->()
{ {
return std::get<0, TResult>(m_data); return std::get<0>(m_data);
} }
constexpr std::add_const_t<std::add_pointer_t<TResult>> operator->() const constexpr std::add_const_t<std::add_pointer_t<TResult>> operator->() const
{ {
return std::get<0, TResult>(m_data); return std::get<0>(m_data);
} }
constexpr std::add_lvalue_reference_t<TError> error() & constexpr std::add_lvalue_reference_t<TError> error() &
{ {
return std::get<1, TError>(m_data); return std::get<1>(m_data);
} }
constexpr std::add_const_t<std::add_lvalue_reference_t<TError>> error() const& constexpr std::add_const_t<std::add_lvalue_reference_t<TError>> error() const&
{ {
return std::get<1, TError>(m_data); return std::get<1>(m_data);
} }
constexpr std::add_rvalue_reference_t<TError> error() && constexpr std::add_rvalue_reference_t<TError> error() &&
{ {
return std::move(std::get<1, TError>(m_data)); return std::move(std::get<1>(m_data));
} }
constexpr std::add_const_t<std::add_rvalue_reference_t<TError>> error() const&& constexpr std::add_const_t<std::add_rvalue_reference_t<TError>> error() const&&
{ {
return std::move(std::get<1, TError>(m_data)); return std::move(std::get<1>(m_data));
} }
private: private:
explicit Result(std::variant<TResult, TError> data) explicit Expected(std::variant<TResult, TError> data)
: m_data(std::move(data)) : m_data(std::move(data))
{ {
} }
std::variant<TResult, TError> m_data; std::variant<TResult, TError> m_data;
}; };
#define ENSURE_RESULT_VAR(var) \ #define ENSURE_RESULT_VAR(var) \
if (!(var)) \ if (!(var)) \
@@ -122,3 +181,5 @@ private:
if (!result) \ if (!result) \
return result; \ return result; \
} }
} // namespace result

View File

@@ -2,7 +2,6 @@
#include "Loading/IZoneLoaderFactory.h" #include "Loading/IZoneLoaderFactory.h"
#include "Loading/ZoneLoader.h" #include "Loading/ZoneLoader.h"
#include "Utils/Logging/Log.h"
#include "Utils/ObjFileStream.h" #include "Utils/ObjFileStream.h"
#include <filesystem> #include <filesystem>
@@ -12,24 +11,18 @@
namespace fs = std::filesystem; namespace fs = std::filesystem;
std::unique_ptr<Zone> ZoneLoading::LoadZone(const std::string& path) result::Expected<std::unique_ptr<Zone>, std::string> ZoneLoading::LoadZone(const std::string& path)
{ {
auto zoneName = fs::path(path).filename().replace_extension().string(); auto zoneName = fs::path(path).filename().replace_extension().string();
std::ifstream file(path, std::fstream::in | std::fstream::binary); std::ifstream file(path, std::fstream::in | std::fstream::binary);
if (!file.is_open()) if (!file.is_open())
{ return result::Unexpected(std::format("Could not open file '{}'.", path));
con::error("Could not open file '{}'.", path);
return nullptr;
}
ZoneHeader header{}; ZoneHeader header{};
file.read(reinterpret_cast<char*>(&header), sizeof(header)); file.read(reinterpret_cast<char*>(&header), sizeof(header));
if (file.gcount() != sizeof(header)) if (file.gcount() != sizeof(header))
{ return result::Unexpected(std::format("Failed to read zone header from file '{}'.", path));
con::error("Failed to read zone header from file '{}'.", path);
return nullptr;
}
std::unique_ptr<ZoneLoader> zoneLoader; std::unique_ptr<ZoneLoader> zoneLoader;
for (auto game = 0u; game < static_cast<unsigned>(GameId::COUNT); game++) for (auto game = 0u; game < static_cast<unsigned>(GameId::COUNT); game++)
@@ -42,10 +35,7 @@ std::unique_ptr<Zone> ZoneLoading::LoadZone(const std::string& path)
} }
if (!zoneLoader) if (!zoneLoader)
{ return result::Unexpected(std::format("Could not create factory for zone '{}'.", zoneName));
con::error("Could not create factory for zone '{}'.", zoneName);
return nullptr;
}
auto loadedZone = zoneLoader->LoadZone(file); auto loadedZone = zoneLoader->LoadZone(file);

View File

@@ -1,4 +1,6 @@
#pragma once #pragma once
#include "Utils/Result.h"
#include "Zone/Zone.h" #include "Zone/Zone.h"
#include <string> #include <string>
@@ -6,5 +8,5 @@
class ZoneLoading class ZoneLoading
{ {
public: public:
static std::unique_ptr<Zone> LoadZone(const std::string& path); static result::Expected<std::unique_ptr<Zone>, std::string> LoadZone(const std::string& path);
}; };