Result stuff

- add NewResult
 - deprecate and nodiscard old Result
 - silence some warnings
This commit is contained in:
HJfod 2022-10-22 17:49:09 +03:00
parent a85823a322
commit 1dad98b235
11 changed files with 346 additions and 21 deletions
loader

View file

@ -175,13 +175,13 @@ namespace geode {
void setValue(ValueType const& value) {
m_value = value;
if constexpr (std::is_base_of_v<IMinMax<ValueType>, Class>) {
static_cast<Class*>(this)->constrainMinMax(m_value);
(void)static_cast<Class*>(this)->constrainMinMax(m_value);
}
if constexpr (std::is_base_of_v<IOneOf<Class, ValueType>, Class>) {
static_cast<Class*>(this)->constrainOneOf(m_value);
(void)static_cast<Class*>(this)->constrainOneOf(m_value);
}
if constexpr (std::is_base_of_v<IMatch<Class, ValueType>, Class>) {
static_cast<Class*>(this)->constrainMatch(m_value);
(void)static_cast<Class*>(this)->constrainMatch(m_value);
}
this->valueChanged();
}

View file

@ -12,7 +12,7 @@ if constexpr (
wrap::functionName<Derived, types::pure##pure_index>::uuid != nullptr && \
(void*)wrap::functionName<Base, types::pure##pure_index>::uuid != (void*)wrap::functionName<Derived, types::pure##pure_index>::uuid \
) { \
Mod::get()->addHook<wrap::functionName<Derived, types::pure##pure_index>::value, convention>( \
(void)Mod::get()->addHook<wrap::functionName<Derived, types::pure##pure_index>::value, convention>( \
#className "::" #functionName, \
(void*)addresses::address##addr_index() \
); \

View file

@ -0,0 +1,315 @@
#pragma once
#include "../DefaultInclude.hpp"
#include <string_view>
#include <string>
#include <variant>
namespace geode {
namespace {
struct AnyType {
explicit AnyType() = delete;
};
template<class V, class RV>
concept ConvertibleToResult =
std::is_convertible_v<
std::remove_reference_t<V>,
std::remove_reference_t<RV>
> || std::is_same_v<
std::remove_reference_t<V>,
std::remove_reference_t<RV>
>;
using DefaultValue = std::monostate;
using DefaultError = std::string;
}
template<class T = DefaultValue, class E = DefaultError>
class [[nodiscard]] NewResult {
public:
using value_type = std::remove_reference_t<T>;
using error_type = std::remove_reference_t<E>;
// for some reason doing requires causes errors with pch...
static_assert(
std::is_copy_constructible_v<value_type> ||
std::is_move_constructible_v<value_type>,
"T must be copiable or movable!"
);
static_assert(
std::is_copy_constructible_v<error_type> ||
std::is_move_constructible_v<error_type>,
"E must be copiable or movable!"
);
protected:
std::variant<value_type, error_type> m_value;
public:
bool isOk() const {
return std::holds_alternative<value_type>(m_value);
}
bool isErr() const {
return std::holds_alternative<error_type>(m_value);
}
explicit NewResult(value_type const& value)
requires std::is_copy_constructible_v<value_type>
: m_value(value) {}
explicit NewResult(value_type&& value)
requires std::is_move_constructible_v<value_type>
: m_value(std::forward<value_type>(value)) {}
explicit NewResult(error_type const& value)
requires std::is_copy_constructible_v<error_type>
: m_value(value) {}
explicit NewResult(error_type&& value)
requires std::is_move_constructible_v<error_type>
: m_value(std::forward<error_type>(value)) {}
NewResult(NewResult<T, E> const& other)
requires
std::is_copy_constructible_v<value_type> &&
std::is_copy_constructible_v<error_type>
= default;
NewResult(NewResult<T, E>&& other)
requires (
!std::is_copy_constructible_v<value_type> ||
!std::is_copy_constructible_v<error_type>
) = default;
template<class T2, class E2>
requires ConvertibleToResult<T2, T> && ConvertibleToResult<E2, E>
NewResult(NewResult<T2, E2> const& other)
requires
std::is_copy_constructible_v<value_type> &&
std::is_copy_constructible_v<error_type>
: m_value(other.isOk() ? other.unwrap() : other.unwrapErr()) {}
template<class T2, class E2>
requires ConvertibleToResult<T2, T> && ConvertibleToResult<E2, E>
NewResult(NewResult<T2, E2>&& other)
requires (
!std::is_copy_constructible_v<value_type> ||
!std::is_copy_constructible_v<error_type>
) : m_value(other.isOk() ? other.unwrap() : other.unwrapErr()) {}
template<class T2>
requires ConvertibleToResult<T2, T>
NewResult(NewResult<T2, AnyType> const& other)
requires
std::is_copy_constructible_v<value_type> &&
std::is_copy_constructible_v<error_type>
: NewResult(value_type(other.unwrap())) {}
template<class E2>
requires ConvertibleToResult<E2, E>
NewResult(NewResult<AnyType, E2> const& other)
requires
std::is_copy_constructible_v<value_type> &&
std::is_copy_constructible_v<error_type>
: m_value(std::forward<E2>(other.unwrapErr())) {}
template<class T2>
requires ConvertibleToResult<T2, T>
NewResult(NewResult<T2, AnyType>&& other)
requires (
!std::is_copy_constructible_v<value_type> ||
!std::is_copy_constructible_v<error_type>
) : m_value(other.unwrap()) {}
template<class E2>
requires ConvertibleToResult<E2, E>
NewResult(NewResult<AnyType, E2>&& other)
requires (
!std::is_copy_constructible_v<value_type> ||
!std::is_copy_constructible_v<error_type>
) : NewResult(std::forward<error_type>(other.unwrapErr())) {}
value_type unwrap() const
requires std::is_copy_constructible_v<value_type>
{
return std::get<value_type>(m_value);
}
value_type&& unwrap()
requires (!std::is_copy_constructible_v<value_type>)
{
return std::move(std::get<value_type>(m_value));
}
error_type unwrapErr() const
requires std::is_copy_constructible_v<error_type>
{
return std::get<error_type>(m_value);
}
error_type&& unwrapErr()
requires (!std::is_copy_constructible_v<error_type>)
{
return std::move(std::get<error_type>(m_value));
}
explicit operator bool() const requires (
!std::is_same_v<T, bool> &&
!std::is_same_v<E, bool>
) {
return this->isOk();
}
};
template<class T>
class [[nodiscard]] NewResult<T, T> {
public:
using value_type = std::remove_reference_t<T>;
using error_type = std::remove_reference_t<T>;
// for some reason doing requires causes errors with pch...
static_assert(
std::is_copy_constructible_v<value_type> ||
std::is_move_constructible_v<value_type>,
"T must be copiable or movable!"
);
protected:
bool m_success;
value_type m_value;
public:
bool isOk() const {
return m_success;
}
bool isErr() const {
return !m_success;
}
explicit NewResult(value_type const& value, bool success)
requires std::is_copy_constructible_v<value_type>
: m_value(value), m_success(success) {}
explicit NewResult(value_type&& value, bool success)
requires std::is_move_constructible_v<value_type>
: m_value(std::forward<value_type>(value)), m_success(success) {}
NewResult(NewResult<T, T> const& other)
requires std::is_copy_constructible_v<value_type> = default;
NewResult(NewResult<T, T>&& other)
requires (!std::is_copy_constructible_v<value_type>) = default;
template<class T2, class E2>
requires ConvertibleToResult<T2, T> && ConvertibleToResult<E2, T>
NewResult(NewResult<T2, E2> const& other)
requires
std::is_copy_constructible_v<value_type>
: m_value(other.isOk() ? other.unwrap() : other.unwrapErr()),
m_success(other.isOk()) {}
template<class T2, class E2>
requires ConvertibleToResult<T2, T> && ConvertibleToResult<E2, T>
NewResult(NewResult<T2, E2>&& other)
requires (
!std::is_copy_constructible_v<value_type>
) : m_value(other.isOk() ? other.unwrap() : other.unwrapErr()),
m_success(other.isOk()) {}
template<class T2>
requires ConvertibleToResult<T2, T>
NewResult(NewResult<T2, AnyType> const& other)
requires
std::is_copy_constructible_v<value_type>
: NewResult(value_type(other.unwrap()), true) {}
template<class E2>
requires ConvertibleToResult<E2, E>
NewResult(NewResult<AnyType, E2> const& other)
requires
std::is_copy_constructible_v<value_type>
: NewResult(error_type(other.unwrapErr()), false) {}
template<class T2>
requires ConvertibleToResult<T2, T>
NewResult(NewResult<T2, AnyType>&& other)
requires (
!std::is_copy_constructible_v<value_type>
) : NewResult(std::forward<value_type>(other.unwrap()), true) {}
template<class E2>
requires ConvertibleToResult<E2, T>
NewResult(NewResult<AnyType, E2>&& other)
requires (
!std::is_copy_constructible_v<value_type>
) : NewResult(std::forward<error_type>(other.unwrapErr()), false) {}
value_type unwrap() const
requires std::is_copy_constructible_v<value_type>
{
return m_value;
}
value_type&& unwrap()
requires (!std::is_copy_constructible_v<value_type>)
{
return std::move(m_value);
}
error_type unwrapErr() const
requires std::is_copy_constructible_v<error_type>
{
return m_value;
}
error_type&& unwrapErr()
requires (!std::is_copy_constructible_v<error_type>)
{
return std::move(m_value);
}
explicit operator bool() const requires (
!std::is_same_v<T, bool>
) {
return this->isOk();
}
};
template<class T = DefaultValue, class E = AnyType>
requires std::is_copy_constructible_v<T>
NewResult<T, E> NewOk(T value = T()) {
return NewResult<T, E>(value);
}
template<class T = DefaultValue, class E = AnyType>
requires (!std::is_copy_constructible_v<T>)
NewResult<T, E> NewOk(T&& value) {
return NewResult<T, E>(std::forward<T>(value));
}
template<class E = DefaultError, class T = AnyType>
requires std::is_copy_constructible_v<E>
NewResult<T, E> NewErr(E error = E()) {
return NewResult<T, E>(error);
}
template<class E = DefaultError, class T = AnyType>
requires (!std::is_copy_constructible_v<E>)
NewResult<T, E> NewErr(E&& error) {
return NewResult<T, E>(std::forward<E>(error));
}
#define GEODE_UNWRAP_INTO(into, ...) \
auto GEODE_CONCAT(res_, __LINE__) = (__VA_ARGS__);\
if (GEODE_CONCAT(res_, __LINE__).isErr()) {\
return Err(std::move(GEODE_CONCAT(res_, __LINE__).unwrapErr()));\
}\
into = std::move(GEODE_CONCAT(res_, __LINE__).unwrap())
#define GEODE_UNWRAP(...) \
{ auto GEODE_CONCAT(res_, __LINE__) = (__VA_ARGS__);\
if (GEODE_CONCAT(res_, __LINE__).isErr()) {\
return Err(std::move(GEODE_CONCAT(res_, __LINE__).unwrapErr()));\
} }
}

View file

@ -3,6 +3,7 @@
#include <Geode/DefaultInclude.hpp>
#include <string_view>
#include "types.hpp"
#include "NewResult.hpp"
namespace geode {
/**
@ -26,7 +27,7 @@ namespace geode {
* @authors Matcool, HJfod
*/
template <class T = no_result, class E = std::string>
class Result {
class [[nodiscard, deprecated("Result's implementation will be replaced with geode::NewResult later")]] Result {
protected:
bool success;
union {
@ -109,7 +110,7 @@ namespace geode {
* Convert to bool
* @example if (result) { <handle success> } else { <handle failure> }
*/
operator bool() const { return this->success; }
explicit operator bool() const { return this->success; }
/**
* Create a success result
@ -130,7 +131,7 @@ namespace geode {
* @returns Successful Result
*/
template <class T = no_result>
Result<T> Ok(T value = T()) {
Result<T> [[nodiscard, deprecated("Result's implementation will be replaced with geode::NewResult later")]] Ok(T value = T()) {
return Result<T>::ok(value);
}
@ -141,7 +142,7 @@ namespace geode {
* @returns Errorful Result
*/
template <class E = std::string>
struct Err {
struct [[nodiscard, deprecated("Result's implementation will be replaced with geode::NewResult later")]] Err {
const E _value;
Err(const TypeIdentityType<E> value) : _value(value) {}
template <class T>

View file

@ -37,7 +37,7 @@ static CCEGLView* CCEGLView_CCEGLView(CCEGLView* self) {
}
$execute {
Mod::get()->addHook<&CCEGLView_CCEGLView, Thiscall>("CCEGLView::CCEGLView", CCEGLVIEW_CON_ADDR);
(void)Mod::get()->addHook<&CCEGLView_CCEGLView, Thiscall>("CCEGLView::CCEGLView", CCEGLVIEW_CON_ADDR);
}
#endif

View file

@ -150,7 +150,7 @@ void Index::updateIndex(IndexUpdateCallback callback, bool force) {
// different sha
if (force || currentCommitSHA != upcomingCommitSHA) {
// save new sha in file
utils::file::writeString(indexDir / "current", upcomingCommitSHA);
(void)utils::file::writeString(indexDir / "current", upcomingCommitSHA);
web::AsyncWebRequest()
.join("index-download")
@ -643,7 +643,7 @@ InstallItems::CallbackID InstallItems::start(
auto item = Index::get()->getKnownItem(inst);
auto indexDir = Loader::get()->getGeodeDirectory() / "index";
file::createDirectoryAll(indexDir / "temp");
(void)file::createDirectoryAll(indexDir / "temp");
auto tempFile = indexDir / "temp" / item.m_download.m_filename;
m_downloaded.push_back(tempFile);

View file

@ -257,11 +257,11 @@ static void printMods(std::ostream& stream) {
static LONG WINAPI exceptionHandler(LPEXCEPTION_POINTERS info) {
// make sure crashlog directory exists
utils::file::createDirectoryAll(crashlog::getCrashLogDirectory());
(void)utils::file::createDirectoryAll(crashlog::getCrashLogDirectory());
// add a file to let Geode know on next launch that it crashed previously
// this could also be done by saving a loader setting or smth but eh.
utils::file::writeBinary(
(void)utils::file::writeBinary(
crashlog::getCrashLogDirectory() + "/last-crashed", {}
);

View file

@ -362,7 +362,10 @@ bool Loader::setup() {
log::debug("Setting up Loader...");
this->createDirectories();
this->loadSettings();
auto sett = this->loadSettings();
if (!sett) {
log::warn("Unable to load loader settings: {}", sett.error());
}
this->refreshMods();
m_isSetup = true;

View file

@ -48,7 +48,7 @@ Mod::Mod(ModInfo const& info) {
}
Mod::~Mod() {
this->unload();
(void)this->unload();
}
Result<> Mod::loadSettings() {
@ -217,14 +217,14 @@ Result<> Mod::load() {
if (m_implicitLoadFunc) {
auto r = m_implicitLoadFunc(this);
if (!r) {
this->unloadPlatformBinary();
(void)this->unloadPlatformBinary();
RETURN_LOAD_ERR("Implicit mod entry point returned an error");
}
}
if (m_loadFunc) {
auto r = m_loadFunc(this);
if (!r) {
this->unloadPlatformBinary();
(void)this->unloadPlatformBinary();
RETURN_LOAD_ERR("Mod entry point returned an error");
}
}
@ -406,7 +406,7 @@ bool Mod::updateDependencyStates() {
}
if (dep.isUnresolved()) {
m_resolved = false;
this->unload();
(void)this->unload();
hasUnresolved = true;
}
}

View file

@ -195,7 +195,10 @@ Result<ModInfo> ModInfo::createFromFile(ghc::filesystem::path const& path) {
auto info = res.value();
info.m_path = path;
if (path.has_parent_path()) {
info.addSpecialFiles(path.parent_path());
auto err = info.addSpecialFiles(path.parent_path());
if (!err) {
return Err(err.error());
}
}
return Ok(info);
} catch(std::exception& e) {
@ -245,7 +248,10 @@ Result<ModInfo> ModInfo::createFromGeodeFile(ghc::filesystem::path const& path)
auto info = res.value();
info.m_path = path;
info.addSpecialFiles(unzip);
auto err = info.addSpecialFiles(unzip);
if (!err) {
return Err(err.error());
}
return Ok(info);
}

View file

@ -18,7 +18,7 @@ static bool tryOrAlert(Result<T> const& res, const char* title) {
if (!res) {
FLAlertLayer::create(title, res.error(), "OK")->show();
}
return res;
return res.is_value();
}
ModCell::ModCell(const char* name, CCSize size) :