mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-26 01:18:01 -05:00
update to new result
This commit is contained in:
parent
8320cf6057
commit
bdb0c99e17
36 changed files with 159 additions and 6391 deletions
|
@ -237,6 +237,7 @@ endif()
|
|||
|
||||
set(MAT_JSON_AS_INTERFACE ON)
|
||||
CPMAddPackage("gh:geode-sdk/json#cda9807")
|
||||
CPMAddPackage("gh:geode-sdk/result@1.0.1")
|
||||
CPMAddPackage("gh:fmtlib/fmt#10.2.1")
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} INTERFACE MAT_JSON_DYNAMIC=1)
|
||||
|
@ -296,7 +297,7 @@ target_include_directories(GeodeBindings PUBLIC
|
|||
${GEODE_LOADER_PATH}/include/Geode/fmod
|
||||
)
|
||||
target_link_directories(GeodeBindings PUBLIC ${GEODE_LOADER_PATH}/include/link)
|
||||
target_link_libraries(GeodeBindings PUBLIC fmt TulipHookInclude mat-json)
|
||||
target_link_libraries(GeodeBindings PUBLIC fmt TulipHookInclude mat-json GeodeResult)
|
||||
target_link_libraries(${PROJECT_NAME} INTERFACE GeodeBindings)
|
||||
|
||||
if (NOT EXISTS ${GEODE_BIN_PATH})
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "DefaultInclude.hpp"
|
||||
#include "utils/Result.hpp"
|
||||
#include "utils/VersionInfo.hpp"
|
||||
#include "utils/ranges.hpp"
|
||||
#include "utils/casts.hpp"
|
||||
|
|
5994
loader/include/Geode/external/result/result.hpp
vendored
5994
loader/include/Geode/external/result/result.hpp
vendored
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include "../utils/Result.hpp"
|
||||
#include <Geode/Result.hpp>
|
||||
#include "Log.hpp"
|
||||
#include "ModEvent.hpp"
|
||||
#include "ModMetadata.hpp"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "../DefaultInclude.hpp"
|
||||
#include "../cocos/support/zip_support/ZipUtils.h"
|
||||
#include "../utils/Result.hpp"
|
||||
#include <Geode/Result.hpp>
|
||||
#include "../utils/VersionInfo.hpp"
|
||||
#include "../utils/general.hpp"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "../utils/Result.hpp"
|
||||
#include <Geode/Result.hpp>
|
||||
#include "../utils/VersionInfo.hpp"
|
||||
#include "Types.hpp"
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace geode::hook {
|
|||
/**
|
||||
* Create a calling convention wrapper for a function.
|
||||
*/
|
||||
GEODE_DLL tulip::hook::Result<void*> createWrapper(
|
||||
GEODE_DLL Result<void*> createWrapper(
|
||||
void* address,
|
||||
tulip::hook::WrapperMetadata const& metadata
|
||||
) noexcept;
|
||||
|
|
|
@ -158,7 +158,7 @@ namespace geode::modifier {
|
|||
for (auto& [uuid, hook] : m_hooks) {
|
||||
auto res = Mod::get()->claimHook(hook);
|
||||
if (!res) {
|
||||
log::error("Failed to claim hook {}: {}", hook->getDisplayName(), res.error());
|
||||
log::error("Failed to claim hook {}: {}", hook->getDisplayName(), res.unwrapErr());
|
||||
}
|
||||
else {
|
||||
added.push_back(uuid);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "../loader/Log.hpp"
|
||||
#include <set>
|
||||
#include <variant>
|
||||
#include <Geode/utils/Result.hpp>
|
||||
#include <Geode/Result.hpp>
|
||||
|
||||
namespace geode {
|
||||
struct JsonChecker;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "../loader/Hook.hpp"
|
||||
#include "Result.hpp"
|
||||
#include <Geode/Result.hpp>
|
||||
|
||||
namespace geode {
|
||||
namespace hook {
|
||||
|
|
|
@ -1,305 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "../DefaultInclude.hpp"
|
||||
#include "../external/result/result.hpp"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <variant>
|
||||
#include <optional>
|
||||
|
||||
namespace geode {
|
||||
namespace impl {
|
||||
using DefaultValue = std::monostate;
|
||||
using DefaultError = std::string;
|
||||
template <class T>
|
||||
using WrappedResult = std::conditional_t<
|
||||
std::is_lvalue_reference_v<T>, std::reference_wrapper<std::remove_reference_t<T>>,
|
||||
std::remove_const_t<T>>;
|
||||
|
||||
template <class E = impl::DefaultError>
|
||||
class [[nodiscard]] Failure {
|
||||
public:
|
||||
WrappedResult<E> m_error;
|
||||
|
||||
Failure() = default;
|
||||
|
||||
template <class E2>
|
||||
requires(std::is_constructible_v<E, E2 const&>)
|
||||
explicit constexpr Failure(E2 const& e) : m_error(e) {}
|
||||
|
||||
template <class E2>
|
||||
requires(std::is_constructible_v<E, E2 &&>)
|
||||
explicit constexpr Failure(E2&& e) : m_error(std::move(e)) {}
|
||||
|
||||
E& error() & noexcept {
|
||||
return m_error;
|
||||
}
|
||||
|
||||
E const& error() const& noexcept {
|
||||
return m_error;
|
||||
}
|
||||
|
||||
E&& error() && noexcept {
|
||||
return static_cast<E&&>(m_error);
|
||||
}
|
||||
|
||||
E const&& error() const&& noexcept {
|
||||
return static_cast<E&&>(m_error);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T = impl::DefaultValue>
|
||||
class [[nodiscard]] Success {
|
||||
public:
|
||||
WrappedResult<T> m_value;
|
||||
|
||||
Success() = default;
|
||||
|
||||
template <class T2>
|
||||
requires(std::is_constructible_v<T, T2 const&>)
|
||||
explicit constexpr Success(T2 const& v) : m_value(v) {}
|
||||
|
||||
template <class T2>
|
||||
requires(std::is_constructible_v<T, T2 &&>)
|
||||
explicit constexpr Success(T2&& v) : m_value(std::forward<T2>(v)) {}
|
||||
|
||||
T& value() & noexcept {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
T const& value() const& noexcept {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
T&& value() && noexcept {
|
||||
return static_cast<T&&>(m_value);
|
||||
}
|
||||
|
||||
T const&& value() const&& noexcept {
|
||||
return static_cast<T&&>(m_value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <class T = impl::DefaultValue, class E = impl::DefaultError>
|
||||
class [[nodiscard]] Result : public cpp::result<T, E> {
|
||||
public:
|
||||
using Base = cpp::result<T, E>;
|
||||
using ValueType = typename Base::value_type;
|
||||
using ErrorType = typename Base::error_type;
|
||||
|
||||
using Base::result;
|
||||
|
||||
template <class U>
|
||||
requires(cpp::detail::result_is_implicit_value_convertible<T, U>::value)
|
||||
constexpr Result(U&& value) = delete;
|
||||
|
||||
template <class E2>
|
||||
requires(std::is_constructible_v<E, E2 const&>)
|
||||
constexpr Result(impl::Failure<E2> const& e) : Base(cpp::failure<E>(e.error())) {}
|
||||
|
||||
template <class E2>
|
||||
requires(std::is_constructible_v<E, E2 &&>)
|
||||
constexpr Result(impl::Failure<E2>&& e) : Base(cpp::failure<E>(std::move(e.error()))) {}
|
||||
|
||||
template <class T2>
|
||||
requires(std::is_constructible_v<T, T2 const&>)
|
||||
constexpr Result(impl::Success<T2> const& s) : Base(s.value()) {}
|
||||
|
||||
template <class T2>
|
||||
requires(std::is_constructible_v<T, T2 &&>)
|
||||
constexpr Result(impl::Success<T2>&& s) : Base(std::move(s.value())) {}
|
||||
|
||||
[[nodiscard]] constexpr explicit operator bool() const noexcept {
|
||||
return this->Base::operator bool();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr bool isOk() const noexcept {
|
||||
return this->Base::has_value();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr bool isErr() const noexcept {
|
||||
return this->Base::has_error();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr decltype(auto) unwrap() & {
|
||||
return this->Base::value();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr decltype(auto) unwrap() const& {
|
||||
return this->Base::value();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr decltype(auto) unwrap() && {
|
||||
return this->Base::value();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr decltype(auto) unwrap() const&& {
|
||||
return this->Base::value();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr decltype(auto) unwrapErr() & {
|
||||
return this->Base::error();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr decltype(auto) unwrapErr() const& {
|
||||
return this->Base::error();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr decltype(auto) unwrapErr() && {
|
||||
return this->Base::error();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr decltype(auto) unwrapErr() const&& {
|
||||
return this->Base::error();
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
requires(std::is_constructible_v<T, T &&>)
|
||||
[[nodiscard]] Result<T, std::string> expect(std::string const& format, Args&&... args) {
|
||||
if (this->isErr()) {
|
||||
return impl::Failure<std::string>(fmt::format(
|
||||
fmt::runtime(format), std::forward<Args>(args)...,
|
||||
fmt::arg("error", this->unwrapErr())
|
||||
));
|
||||
}
|
||||
else {
|
||||
return std::move(*this);
|
||||
}
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
requires(std::is_constructible_v<T, T const&>)
|
||||
[[nodiscard]] Result<T, std::string> expect(std::string const& format, Args&&... args)
|
||||
const {
|
||||
if (this->isErr()) {
|
||||
return impl::Failure<std::string>(fmt::format(
|
||||
fmt::runtime(format), std::forward<Args>(args)...,
|
||||
fmt::arg("error", this->unwrapErr())
|
||||
));
|
||||
}
|
||||
else {
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
template <class U>
|
||||
[[nodiscard]] constexpr decltype(auto) unwrapOr(U&& val) && {
|
||||
return this->Base::value_or(std::forward<U>(val));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
[[nodiscard]] constexpr decltype(auto) unwrapOr(U&& val) const& {
|
||||
return this->Base::value_or(std::forward<U>(val));
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr decltype(auto) unwrapOrDefault() && requires std::is_default_constructible_v<T> {
|
||||
return this->Base::value_or(T());
|
||||
}
|
||||
[[nodiscard]] constexpr decltype(auto) unwrapOrDefault() const& requires std::is_default_constructible_v<T> {
|
||||
return this->Base::value_or(T());
|
||||
}
|
||||
|
||||
template <class U>
|
||||
[[nodiscard]] constexpr decltype(auto) errorOr(U&& val) && {
|
||||
return this->Base::error_or(std::forward<U>(val));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
[[nodiscard]] constexpr decltype(auto) errorOr(U&& val) const& {
|
||||
return this->Base::error_or(std::forward<U>(val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the result into an optional containing the value if Ok, and
|
||||
* nullopt if Err
|
||||
*/
|
||||
[[nodiscard]] constexpr std::optional<T> ok() const& {
|
||||
if (this->isOk()) {
|
||||
return this->unwrap();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the result into an optional containing the value if Ok, and
|
||||
* nullopt if Err
|
||||
*/
|
||||
[[nodiscard]] constexpr std::optional<T> ok() && {
|
||||
if (this->isOk()) {
|
||||
return this->unwrap();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the result into an optional containing the error if Err, and
|
||||
* nullopt if Ok
|
||||
*/
|
||||
[[nodiscard]] constexpr std::optional<E> err() const& {
|
||||
if (this->isErr()) {
|
||||
return this->unwrapErr();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the result into an optional containing the error if Err, and
|
||||
* nullopt if Ok
|
||||
*/
|
||||
[[nodiscard]] constexpr std::optional<E> err() && {
|
||||
if (this->isErr()) {
|
||||
return this->unwrapErr();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Completely disregard the result. Only recommended if the result is
|
||||
* inconsequential
|
||||
*/
|
||||
constexpr void disregard() && {}
|
||||
};
|
||||
|
||||
template <class T = impl::DefaultValue>
|
||||
constexpr impl::Success<T> Ok() {
|
||||
return impl::Success<T>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
constexpr impl::Success<T> Ok(T value) {
|
||||
// DO NOT MAKE THE PARAMETER T&&!!!! THAT WILL CAUSE C++ TO DO UNEXPECTED
|
||||
// IMPLICIT MOVES FOR EXAMPLE WHEN DOING `Ok(unordered_map.at(value))`
|
||||
return impl::Success<T>(std::forward<T>(value));
|
||||
}
|
||||
|
||||
template <class E>
|
||||
constexpr impl::Failure<E> Err(E error) {
|
||||
return impl::Failure<E>(std::forward<E>(error));
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
inline impl::Failure<std::string> Err(std::string const& format, Args&&... args) {
|
||||
return impl::Failure<std::string>(
|
||||
fmt::format(fmt::runtime(format), std::forward<Args>(args)...)
|
||||
);
|
||||
}
|
||||
|
||||
#define GEODE_UNWRAP_INTO(into, ...) \
|
||||
auto GEODE_CONCAT(unwrap_res_, __LINE__) = (__VA_ARGS__); \
|
||||
if (GEODE_CONCAT(unwrap_res_, __LINE__).isErr()) { \
|
||||
return geode::Err(std::move(GEODE_CONCAT(unwrap_res_, __LINE__).unwrapErr())); \
|
||||
} \
|
||||
into = std::move(GEODE_CONCAT(unwrap_res_, __LINE__).unwrap())
|
||||
|
||||
#define GEODE_UNWRAP(...) \
|
||||
do { \
|
||||
auto GEODE_CONCAT(unwrap_res_, __LINE__) = (__VA_ARGS__); \
|
||||
if (GEODE_CONCAT(unwrap_res_, __LINE__).isErr()) { \
|
||||
return geode::Err(std::move(GEODE_CONCAT(unwrap_res_, __LINE__).unwrapErr())); \
|
||||
} \
|
||||
} while(false)
|
||||
}
|
|
@ -248,7 +248,7 @@ namespace geode {
|
|||
|
||||
using Value = T;
|
||||
using Progress = P;
|
||||
using PostResult = std::function<void(Result)>;
|
||||
using PostResult = std::function<void(Result&&)>;
|
||||
using PostProgress = std::function<void(P)>;
|
||||
using HasBeenCancelled = std::function<bool()>;
|
||||
using Run = std::function<Result(PostProgress, HasBeenCancelled)>;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <string_view>
|
||||
#include <matjson.hpp>
|
||||
#include <tuple>
|
||||
#include "../utils/Result.hpp"
|
||||
#include <Geode/Result.hpp>
|
||||
|
||||
namespace geode {
|
||||
enum class VersionCompare {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "Result.hpp"
|
||||
#include <Geode/Result.hpp>
|
||||
#include "general.hpp"
|
||||
#include "../loader/Event.hpp"
|
||||
#include "Task.hpp"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "Result.hpp"
|
||||
#include <Geode/Result.hpp>
|
||||
|
||||
#include "../DefaultInclude.hpp"
|
||||
#include <chrono>
|
||||
|
@ -13,6 +13,7 @@
|
|||
#include <charconv>
|
||||
#include <clocale>
|
||||
#include <type_traits>
|
||||
#include <fmt/format.h>
|
||||
|
||||
namespace geode {
|
||||
using ByteVector = std::vector<uint8_t>;
|
||||
|
@ -159,6 +160,12 @@ namespace geode {
|
|||
*/
|
||||
GEODE_DLL float getDisplayFactor();
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
requires (sizeof...(Args) > 0)
|
||||
constexpr auto Err(fmt::format_string<Args...> fmt, Args&&... args) {
|
||||
return Err(fmt::format(fmt, std::forward<Args>(args)...));
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "Result.hpp"
|
||||
#include <Geode/Result.hpp>
|
||||
|
||||
#include <Geode/DefaultInclude.hpp>
|
||||
#include <functional>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <Geode/loader/Loader.hpp> // another great circular dependency fix
|
||||
#include <matjson.hpp>
|
||||
#include "Result.hpp"
|
||||
#include <Geode/Result.hpp>
|
||||
#include "Task.hpp"
|
||||
#include <chrono>
|
||||
#include <optional>
|
||||
|
|
|
@ -496,20 +496,20 @@ void Loader::Impl::loadModGraph(Mod* node, bool early) {
|
|||
thread::setName("Mod Unzip");
|
||||
log::loadNest(nest);
|
||||
auto res = unzipFunction();
|
||||
auto prevNest = log::saveNest();
|
||||
log::loadNest(nest);
|
||||
if (!res) {
|
||||
this->addProblem({
|
||||
LoadProblem::Type::UnzipFailed,
|
||||
node,
|
||||
res.unwrapErr()
|
||||
});
|
||||
log::error("Failed to unzip: {}", res.unwrapErr());
|
||||
m_refreshingModCount -= 1;
|
||||
log::loadNest(prevNest);
|
||||
return;
|
||||
}
|
||||
this->queueInMainThread([=, this]() {
|
||||
auto prevNest = log::saveNest();
|
||||
log::loadNest(nest);
|
||||
if (!res) {
|
||||
this->addProblem({
|
||||
LoadProblem::Type::UnzipFailed,
|
||||
node,
|
||||
res.unwrapErr()
|
||||
});
|
||||
log::error("Failed to unzip: {}", res.unwrapErr());
|
||||
m_refreshingModCount -= 1;
|
||||
log::loadNest(prevNest);
|
||||
return;
|
||||
}
|
||||
loadFunction();
|
||||
log::loadNest(prevNest);
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include <Geode/loader/Loader.hpp>
|
||||
#include <Geode/loader/Log.hpp>
|
||||
#include <Geode/loader/Mod.hpp>
|
||||
#include <Geode/utils/Result.hpp>
|
||||
#include <Geode/Result.hpp>
|
||||
#include <Geode/utils/map.hpp>
|
||||
#include <Geode/utils/ranges.hpp>
|
||||
#include "ModImpl.hpp"
|
||||
|
|
|
@ -51,7 +51,9 @@ Result<> Mod::Impl::setup() {
|
|||
(void) utils::file::createDirectoryAll(m_saveDirPath);
|
||||
|
||||
// always create temp dir for all mods, even if disabled, so resources can be loaded
|
||||
GEODE_UNWRAP(this->createTempDir().expect("Unable to create temp dir: {error}"));
|
||||
GEODE_UNWRAP(this->createTempDir().mapErr([](auto const& err) {
|
||||
return fmt::format("Unable to create temp dir: {}", err);
|
||||
}));
|
||||
|
||||
m_settings = std::make_unique<ModSettingsManager>(m_metadata);
|
||||
auto loadRes = this->loadData();
|
||||
|
|
|
@ -307,8 +307,11 @@ Result<ModMetadata> ModMetadata::Impl::create(ModJson const& json) {
|
|||
if (json.contains("geode") && json["geode"].is_string()) {
|
||||
GEODE_UNWRAP_INTO(
|
||||
schema,
|
||||
VersionInfo::parse(json["geode"].as_string())
|
||||
.expect("[mod.json] has invalid target loader version: {error}")
|
||||
VersionInfo::parse(json["geode"].as_string()).mapErr(
|
||||
[](auto const& err) {
|
||||
return fmt::format("[mod.json] has invalid target loader version: {}", err);
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
@ -382,7 +385,9 @@ Result<ModMetadata> ModMetadata::Impl::createFromGeodeZip(file::Unzip& unzip) {
|
|||
|
||||
// Read mod.json & parse if possible
|
||||
GEODE_UNWRAP_INTO(
|
||||
auto jsonData, unzip.extract("mod.json").expect("Unable to read mod.json: {error}")
|
||||
auto jsonData, unzip.extract("mod.json").mapErr([](auto const& err) {
|
||||
return fmt::format("Unable to extract mod.json: {}", err);
|
||||
})
|
||||
);
|
||||
|
||||
std::string error;
|
||||
|
@ -400,7 +405,9 @@ Result<ModMetadata> ModMetadata::Impl::createFromGeodeZip(file::Unzip& unzip) {
|
|||
auto impl = info.m_impl.get();
|
||||
impl->m_path = unzip.getPath();
|
||||
|
||||
GEODE_UNWRAP(info.addSpecialFiles(unzip).expect("Unable to add extra files: {error}"));
|
||||
GEODE_UNWRAP(info.addSpecialFiles(unzip).mapErr([](auto const& err) {
|
||||
return fmt::format("Unable to add extra files: {}", err);
|
||||
}));
|
||||
|
||||
return Ok(info);
|
||||
}
|
||||
|
@ -409,7 +416,9 @@ Result<> ModMetadata::Impl::addSpecialFiles(file::Unzip& unzip) {
|
|||
// unzip known MD files
|
||||
for (auto& [file, target] : this->getSpecialFiles()) {
|
||||
if (unzip.hasEntry(file)) {
|
||||
GEODE_UNWRAP_INTO(auto data, unzip.extract(file).expect("Unable to extract \"{}\"", file));
|
||||
GEODE_UNWRAP_INTO(auto data, unzip.extract(file).mapErr([&](auto const& err) {
|
||||
return fmt::format("Unable to extract \"{}\": {}", file, err);
|
||||
}));
|
||||
*target = sanitizeDetailsData(std::string(data.begin(), data.end()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,22 +8,36 @@ using namespace geode::prelude;
|
|||
// #1 no need to duplicate the built-in settings between all mods
|
||||
// #2 easier lookup of custom settings if a mod uses another mod's custom setting type
|
||||
|
||||
|
||||
namespace {
|
||||
auto changeToGenerator(auto&& function) {
|
||||
return [function](
|
||||
std::string const& key,
|
||||
std::string const& modID,
|
||||
matjson::Value const& json
|
||||
) -> Result<std::shared_ptr<SettingV3>> {
|
||||
return function(key, modID, json).map([](auto&& ptr) {
|
||||
return std::shared_ptr<SettingV3>(ptr);
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
class SharedSettingTypesPool final {
|
||||
private:
|
||||
std::unordered_map<std::string, SettingGenerator> m_types;
|
||||
|
||||
SharedSettingTypesPool() : m_types({
|
||||
{ "title", &TitleSetting::parse },
|
||||
{ "bool", &BoolSetting::parse },
|
||||
{ "int", &IntSetting::parse },
|
||||
{ "float", &FloatSetting::parse },
|
||||
{ "string", &StringSetting::parse },
|
||||
{ "file", &FileSetting::parse },
|
||||
{ "folder", &FileSetting::parse },
|
||||
{ "path", &FileSetting::parse },
|
||||
{ "rgb", &Color3BSetting::parse },
|
||||
{ "color", &Color3BSetting::parse },
|
||||
{ "rgba", &Color4BSetting::parse },
|
||||
{ "title", changeToGenerator(TitleSettingV3::parse) },
|
||||
{ "bool", changeToGenerator(BoolSettingV3::parse) },
|
||||
{ "int", changeToGenerator(IntSettingV3::parse) },
|
||||
{ "float", changeToGenerator(FloatSettingV3::parse) },
|
||||
{ "string", changeToGenerator(StringSettingV3::parse) },
|
||||
{ "file", changeToGenerator(FileSettingV3::parse) },
|
||||
{ "folder", changeToGenerator(FileSettingV3::parse) },
|
||||
{ "path", changeToGenerator(FileSettingV3::parse) },
|
||||
{ "rgb", changeToGenerator(Color3BSettingV3::parse) },
|
||||
{ "color", changeToGenerator(Color3BSettingV3::parse) },
|
||||
{ "rgba", changeToGenerator(Color4BSettingV3::parse) },
|
||||
}) {}
|
||||
|
||||
public:
|
||||
|
@ -135,7 +149,7 @@ public:
|
|||
continue;
|
||||
}
|
||||
if (auto v3 = (*gen)(key, modID, setting.json)) {
|
||||
setting.v3 = *v3;
|
||||
setting.v3 = v3.unwrap();
|
||||
this->loadSettingValueFromSave(key);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -92,8 +92,8 @@ Result<> Patch::Impl::updateBytes(const ByteVector& bytes) {
|
|||
if (m_enabled) {
|
||||
auto res = this->disable();
|
||||
if (!res) return Err("Failed to update patch: {}", res.unwrapErr());
|
||||
res = this->enable();
|
||||
if (!res) return Err("Failed to update patch: {}", res.unwrapErr());
|
||||
auto res2 = this->enable();
|
||||
if (!res2) return Err("Failed to update patch: {}", res2.unwrapErr());
|
||||
}
|
||||
|
||||
return Ok();
|
||||
|
|
|
@ -152,18 +152,21 @@ namespace enable_if_parsing {
|
|||
return Ok();
|
||||
}
|
||||
Result<> eval(std::string const& defaultModID) const override {
|
||||
Result<> err = Ok();
|
||||
std::optional<std::string> err;
|
||||
for (auto& comp : components) {
|
||||
auto res = comp->eval(defaultModID);
|
||||
if (res) {
|
||||
return Ok();
|
||||
}
|
||||
// Only show first condition that isn't met
|
||||
if (err.isOk()) {
|
||||
err = Err(res.unwrapErr());
|
||||
if (!err.has_value()) {
|
||||
err = res.unwrapErr();
|
||||
}
|
||||
}
|
||||
return err;
|
||||
if (err.has_value()) {
|
||||
return Err(*err);
|
||||
}
|
||||
return Ok();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -235,7 +238,10 @@ namespace enable_if_parsing {
|
|||
auto original = m_index;
|
||||
auto ret = this->nextWord();
|
||||
m_index = original;
|
||||
return ret ? *ret : std::nullopt;
|
||||
if (!ret) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return ret.unwrap();
|
||||
}
|
||||
Result<std::unique_ptr<Component>> nextComponent() {
|
||||
GEODE_UNWRAP_INTO(auto maybeWord, this->nextWord());
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
|
||||
#include <Geode/loader/Tulip.hpp>
|
||||
|
||||
tulip::hook::Result<void*> geode::hook::createWrapper(
|
||||
using namespace geode::prelude;
|
||||
|
||||
Result<void*> geode::hook::createWrapper(
|
||||
void* address,
|
||||
tulip::hook::WrapperMetadata const& metadata
|
||||
) noexcept {
|
||||
|
|
|
@ -83,7 +83,7 @@ void updater::fetchLatestGithubRelease(
|
|||
}
|
||||
else {
|
||||
Mod::get()->setSavedValue("last-modified-auto-update-check", response->header("Last-Modified").value_or(""));
|
||||
s_latestGithubRelease = *json;
|
||||
s_latestGithubRelease = json.unwrap();
|
||||
then(*s_latestGithubRelease);
|
||||
}
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ void updater::tryDownloadLoaderResources(std::string const& url, bool tryLatestO
|
|||
// unzip resources zip
|
||||
auto unzip = file::Unzip::create(response->data());
|
||||
if (unzip) {
|
||||
auto ok = unzip->extractAllTo(resourcesDir);
|
||||
auto ok = unzip.unwrap().extractAllTo(resourcesDir);
|
||||
if (ok) {
|
||||
updater::updateSpecialFiles();
|
||||
ResourceDownloadEvent(UpdateFinished()).post();
|
||||
|
@ -308,7 +308,7 @@ void updater::downloadLoaderUpdate(std::string const& url) {
|
|||
// unzip resources zip
|
||||
auto unzip = file::Unzip::create(response->data());
|
||||
if (unzip) {
|
||||
auto ok = unzip->extractAllTo(targetDir);
|
||||
auto ok = unzip.unwrap().extractAllTo(targetDir);
|
||||
if (ok) {
|
||||
s_isNewUpdateDownloaded = true;
|
||||
LoaderUpdateEvent(UpdateFinished()).post();
|
||||
|
|
|
@ -261,12 +261,12 @@ int writeAndGetPid() {
|
|||
|
||||
auto res = file::readString(pidFile);
|
||||
if (!res) {
|
||||
log::warn("Failed to read last-pid file: {}", res.error());
|
||||
log::warn("Failed to read last-pid file: {}", res.unwrapErr());
|
||||
}
|
||||
else {
|
||||
auto res = numFromString<int>(res.unwrap());
|
||||
if (!res) {
|
||||
log::warn("Failed to parse last-pid file: {}", res.error());
|
||||
log::warn("Failed to parse last-pid file: {}", res.unwrapErr());
|
||||
}
|
||||
else lastPid = res.unwrap();
|
||||
}
|
||||
|
@ -281,7 +281,7 @@ int writeAndGetPid() {
|
|||
|
||||
auto res = file::writeString(pidFile, std::to_string(getpid()));
|
||||
if (!res) {
|
||||
log::warn("Failed to write last-pid file: {}", res.error());
|
||||
log::warn("Failed to write last-pid file: {}", res.unwrapErr());
|
||||
}
|
||||
|
||||
return lastPid;
|
||||
|
|
|
@ -12,7 +12,7 @@ using namespace geode::prelude;
|
|||
#include <Geode/binding/AppDelegate.hpp>
|
||||
#include <Geode/loader/Log.hpp>
|
||||
#include <Geode/binding/MenuLayer.hpp>
|
||||
#include <Geode/utils/Result.hpp>
|
||||
#include <Geode/Result.hpp>
|
||||
#include <Geode/DefaultInclude.hpp>
|
||||
#include <optional>
|
||||
#include <mutex>
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#define NFD_UTF8_BOM "\xEF\xBB\xBF"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <Geode/utils/Result.hpp>
|
||||
#include <Geode/Result.hpp>
|
||||
#include <Geode/utils/file.hpp>
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
|
|
@ -120,7 +120,6 @@ Task<Result<std::filesystem::path>> file::pick(PickMode mode, FilePickOptions co
|
|||
return RetTask::immediate(Err<std::string>("Invalid pick mode"));
|
||||
}
|
||||
std::filesystem::path path;
|
||||
Result<std::filesystem::path> result;
|
||||
auto pickresult = nfdPick(nfdMode, options, &path);
|
||||
if (pickresult.isErr()) {
|
||||
if (pickresult.unwrapErr() == "Dialog cancelled") {
|
||||
|
@ -137,13 +136,11 @@ Task<Result<std::vector<std::filesystem::path>>> file::pickMany(FilePickOptions
|
|||
|
||||
std::vector<std::filesystem::path> paths;
|
||||
auto pickResult = nfdPick(NFDMode::OpenFiles, options, &paths);
|
||||
Result<std::vector<std::filesystem::path>> result;
|
||||
if (pickResult.isErr()) {
|
||||
result = Err(pickResult.err().value());
|
||||
return RetTask::immediate(Err(pickResult.err().value()));
|
||||
} else {
|
||||
result = Ok(paths);
|
||||
return RetTask::immediate(Ok(paths));
|
||||
}
|
||||
return RetTask::immediate(std::move(result));
|
||||
// return Task<Result<std::vector<std::filesystem::path>>>::immediate(std::move(file::pickFiles(options)));
|
||||
}
|
||||
|
||||
|
|
|
@ -783,7 +783,7 @@ void server::queueBatches(
|
|||
) {
|
||||
// we have to do the copy here, or else our values die
|
||||
batchedCheckUpdates(batches->back()).listen([resolve, batches, accum](auto result) {
|
||||
if (result->ok()) {
|
||||
if (result->isOk()) {
|
||||
auto serverValues = result->unwrap();
|
||||
|
||||
accum->reserve(accum->size() + serverValues.size());
|
||||
|
@ -798,7 +798,12 @@ void server::queueBatches(
|
|||
}
|
||||
}
|
||||
else {
|
||||
resolve(*result);
|
||||
if (result->isOk()) {
|
||||
resolve(Ok(result->unwrap()));
|
||||
}
|
||||
else {
|
||||
resolve(Err(result->unwrapErr()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ protected:
|
|||
if (auto res = event->getValue()) {
|
||||
if (res->isOk()) {
|
||||
// Copy info first as onClose may free the listener which will free the event
|
||||
auto info = **res;
|
||||
auto info = res->unwrap();
|
||||
this->onClose(nullptr);
|
||||
// Run this on next frame because otherwise the popup is unable to call server::getMod for some reason
|
||||
Loader::get()->queueInMainThread([info = std::move(info)]() mutable {
|
||||
|
|
|
@ -14,9 +14,9 @@ LoadModSuggestionTask loadModSuggestion(LoadProblem const& problem) {
|
|||
|
||||
if (auto suggestionVersionRes = ComparableVersionInfo::parse(suggestionVersionStr)) {
|
||||
server::ModVersion suggestionVersion = server::ModVersionLatest();
|
||||
if (suggestionVersionRes->getComparison() == VersionCompare::MoreEq) {
|
||||
if (suggestionVersionRes.unwrap().getComparison() == VersionCompare::MoreEq) {
|
||||
suggestionVersion = server::ModVersionMajor {
|
||||
.major = suggestionVersionRes->getUnderlyingVersion().getMajor()
|
||||
.major = suggestionVersionRes.unwrap().getUnderlyingVersion().getMajor()
|
||||
};
|
||||
}
|
||||
// todo: if mods are allowed to specify other type of version comparisons in the future,
|
||||
|
@ -195,7 +195,7 @@ server::ServerRequest<std::unordered_set<std::string>> ModSource::fetchValidTags
|
|||
}
|
||||
return Ok(finalTags);
|
||||
}
|
||||
return *result;
|
||||
return Ok(result->unwrap());
|
||||
},
|
||||
[](server::ServerProgress* progress) {
|
||||
return *progress;
|
||||
|
|
|
@ -329,19 +329,19 @@ struct MDParser {
|
|||
if (key == "scale") {
|
||||
auto scaleRes = utils::numFromString<float>(value);
|
||||
if (scaleRes) {
|
||||
spriteScale = *scaleRes;
|
||||
spriteScale = scaleRes.unwrap();
|
||||
}
|
||||
}
|
||||
else if (key == "width") {
|
||||
auto widthRes = utils::numFromString<float>(value);
|
||||
if (widthRes) {
|
||||
spriteWidth = *widthRes;
|
||||
spriteWidth = widthRes.unwrap();
|
||||
}
|
||||
}
|
||||
else if (key == "height") {
|
||||
auto heightRes = utils::numFromString<float>(value);
|
||||
if (heightRes) {
|
||||
spriteHeight = *heightRes;
|
||||
spriteHeight = heightRes.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ Result<matjson::Value> utils::file::readJson(std::filesystem::path const& path)
|
|||
if (!str)
|
||||
return Err(str.unwrapErr());
|
||||
std::string error;
|
||||
auto res = matjson::parse(str.value(), error);
|
||||
auto res = matjson::parse(str.unwrap(), error);
|
||||
if (error.size())
|
||||
return Err("Unable to parse JSON: " + error);
|
||||
return Ok(res.value());
|
||||
|
@ -304,7 +304,9 @@ public:
|
|||
|
||||
GEODE_UNWRAP(
|
||||
mzTry(mz_zip_entry_read_open(m_handle, 0, nullptr))
|
||||
.expect("Unable to open entry (code {error})")
|
||||
.mapErr([&](auto error) {
|
||||
return fmt::format("Unable to open entry (code {})", error);
|
||||
})
|
||||
);
|
||||
|
||||
// if the file is empty, its data is empty (duh)
|
||||
|
@ -323,7 +325,9 @@ public:
|
|||
mz_zip_entry_close(m_handle);
|
||||
|
||||
GEODE_UNWRAP(file::createDirectoryAll((dir / name).parent_path()));
|
||||
GEODE_UNWRAP(file::writeBinary(dir / name, res).expect("Unable to write to {}: {error}", dir / name));
|
||||
GEODE_UNWRAP(file::writeBinary(dir / name, res).mapErr([&](auto error) {
|
||||
return fmt::format("Unable to write to {}: {}", dir / name, error);
|
||||
}));
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
@ -333,14 +337,18 @@ public:
|
|||
|
||||
GEODE_UNWRAP(
|
||||
mzTry(mz_zip_goto_first_entry(m_handle))
|
||||
.expect("Unable to navigate to first entry (code {error})")
|
||||
.mapErr([&](auto error) {
|
||||
return fmt::format("Unable to navigate to first entry (code {})", error);
|
||||
})
|
||||
);
|
||||
|
||||
uint64_t numEntries;
|
||||
|
||||
GEODE_UNWRAP(
|
||||
mzTry(mz_zip_get_number_entry(m_handle, &numEntries))
|
||||
.expect("Unable to get number of entries (code {error})")
|
||||
.mapErr([&](auto error) {
|
||||
return fmt::format("Unable to get number of entries (code {})", error);
|
||||
})
|
||||
);
|
||||
|
||||
uint32_t currentEntry = 0;
|
||||
|
@ -395,7 +403,9 @@ public:
|
|||
|
||||
GEODE_UNWRAP(
|
||||
mzTry(mz_zip_goto_first_entry(m_handle))
|
||||
.expect("Unable to navigate to first entry (code {error})")
|
||||
.mapErr([&](auto error) {
|
||||
return fmt::format("Unable to navigate to first entry (code {})", error);
|
||||
})
|
||||
);
|
||||
|
||||
GEODE_UNWRAP(
|
||||
|
@ -403,12 +413,17 @@ public:
|
|||
m_handle,
|
||||
reinterpret_cast<const char*>(name.u8string().c_str()),
|
||||
1
|
||||
)).expect("Unable to navigate to entry (code {error})")
|
||||
))
|
||||
.mapErr([&](auto error) {
|
||||
return fmt::format("Unable to locate entry (code {})", error);
|
||||
})
|
||||
);
|
||||
|
||||
GEODE_UNWRAP(
|
||||
mzTry(mz_zip_entry_read_open(m_handle, 0, nullptr))
|
||||
.expect("Unable to open entry (code {error})")
|
||||
.mapErr([&](auto error) {
|
||||
return fmt::format("Unable to open entry (code {})", error);
|
||||
})
|
||||
);
|
||||
|
||||
// if the file is empty, its data is empty (duh)
|
||||
|
@ -448,7 +463,9 @@ public:
|
|||
|
||||
GEODE_UNWRAP(
|
||||
mzTry(mz_zip_entry_write_open(m_handle, &info, MZ_COMPRESS_LEVEL_DEFAULT, 0, nullptr))
|
||||
.expect("Unable to open entry for writing (code {error})")
|
||||
.mapErr([&](auto error) {
|
||||
return fmt::format("Unable to open entry for writing (code {})", error);
|
||||
})
|
||||
);
|
||||
mz_zip_entry_close(m_handle);
|
||||
|
||||
|
@ -465,7 +482,9 @@ public:
|
|||
|
||||
GEODE_UNWRAP(
|
||||
mzTry(mz_zip_entry_write_open(m_handle, &info, MZ_COMPRESS_LEVEL_DEFAULT, 0, nullptr))
|
||||
.expect("Unable to open entry for writing (code {error})")
|
||||
.mapErr([&](auto error) {
|
||||
return fmt::format("Unable to open entry for writing (code {})", error);
|
||||
})
|
||||
);
|
||||
auto written = mz_zip_entry_write(m_handle, data.data(), data.size());
|
||||
if (written < 0) {
|
||||
|
@ -550,16 +569,22 @@ bool Unzip::hasEntry(Path const& name) {
|
|||
}
|
||||
|
||||
Result<ByteVector> Unzip::extract(Path const& name) {
|
||||
return m_impl->extract(name).expect("{error} (entry {})", name.string());
|
||||
return m_impl->extract(name).mapErr([&](auto error) {
|
||||
return fmt::format("Unable to extract entry {}: {}", name.string(), error);
|
||||
});
|
||||
}
|
||||
|
||||
Result<> Unzip::extractTo(Path const& name, Path const& path) {
|
||||
GEODE_UNWRAP_INTO(auto bytes, m_impl->extract(name).expect("{error} (entry {})", name.string()));
|
||||
GEODE_UNWRAP_INTO(auto bytes, m_impl->extract(name).mapErr([&](auto error) {
|
||||
return fmt::format("Unable to extract entry {}: {}", name.string(), error);
|
||||
}));
|
||||
// create containing directories for target path
|
||||
if (path.has_parent_path()) {
|
||||
GEODE_UNWRAP(file::createDirectoryAll(path.parent_path()));
|
||||
}
|
||||
GEODE_UNWRAP(file::writeBinary(path, bytes).expect("Unable to write file {}: {error}", path.string()));
|
||||
GEODE_UNWRAP(file::writeBinary(path, bytes).mapErr([&](auto error) {
|
||||
return fmt::format("Unable to write file {}: {}", path.string(), error);
|
||||
}));
|
||||
return Ok();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <Geode/utils/Result.hpp>
|
||||
#include <Geode/Result.hpp>
|
||||
#include <Geode/utils/general.hpp>
|
||||
#include <filesystem>
|
||||
#include <fmt/core.h>
|
||||
|
@ -498,7 +498,7 @@ WebRequest& WebRequest::header(std::string_view name, std::string_view value) {
|
|||
int timeoutValue = 5;
|
||||
auto res = numFromString<int>(value.substr(numStart, numLength));
|
||||
if (res) {
|
||||
timeoutValue = res.value();
|
||||
timeoutValue = res.unwrap();
|
||||
}
|
||||
|
||||
timeout(std::chrono::seconds(timeoutValue));
|
||||
|
|
Loading…
Reference in a new issue