2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-10-21 13:56:42 +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();
auto absoluteZoneDirectory = absolute(zoneDirectory).string();
auto zone = ZoneLoading::LoadZone(zonePath);
if (!zone)
auto maybeZone = ZoneLoading::LoadZone(zonePath);
if (!maybeZone)
{
con::error("Failed to load zone \"{}\".", zonePath);
con::error("Failed to load zone \"{}\": {}", zonePath, maybeZone.error());
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));
}

View File

@@ -2,11 +2,11 @@
#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);
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
#include "Utils/Result.h"
#include "Zone/Zone.h"
#include <memory>
#include <optional>
#include <vector>
class FastFileContext
{
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;
};

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,7 +2,6 @@
#include "Loading/IZoneLoaderFactory.h"
#include "Loading/ZoneLoader.h"
#include "Utils/Logging/Log.h"
#include "Utils/ObjFileStream.h"
#include <filesystem>
@@ -12,24 +11,18 @@
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();
std::ifstream file(path, std::fstream::in | std::fstream::binary);
if (!file.is_open())
{
con::error("Could not open file '{}'.", path);
return nullptr;
}
return result::Unexpected(std::format("Could not open file '{}'.", path));
ZoneHeader header{};
file.read(reinterpret_cast<char*>(&header), sizeof(header));
if (file.gcount() != sizeof(header))
{
con::error("Failed to read zone header from file '{}'.", path);
return nullptr;
}
return result::Unexpected(std::format("Failed to read zone header from file '{}'.", path));
std::unique_ptr<ZoneLoader> zoneLoader;
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)
{
con::error("Could not create factory for zone '{}'.", zoneName);
return nullptr;
}
return result::Unexpected(std::format("Could not create factory for zone '{}'.", zoneName));
auto loadedZone = zoneLoader->LoadZone(file);

View File

@@ -1,4 +1,6 @@
#pragma once
#include "Utils/Result.h"
#include "Zone/Zone.h"
#include <string>
@@ -6,5 +8,5 @@
class ZoneLoading
{
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);
};