mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-26 17:36:05 -05:00
Merge pull request #92 from altalk23/altalk
Replace result implementation with bitwizeshift/result
This commit is contained in:
commit
51109919f9
13 changed files with 6554 additions and 415 deletions
|
@ -84,7 +84,7 @@ IndentCaseLabels: true
|
|||
IndentExternBlock: Indent
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: BeforeHash
|
||||
IndentRequiresClause: false
|
||||
IndentRequiresClause: true
|
||||
IndentWrappedFunctionNames: false
|
||||
# InsertBraces: true
|
||||
InsertTrailingCommas: None
|
||||
|
@ -101,6 +101,7 @@ PenaltyBreakBeforeFirstCallParameter: 19
|
|||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakOpenParenthesis: 0
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 1000000
|
||||
|
|
|
@ -210,6 +210,7 @@ class cocos2d::CCFileUtils : cocos2d::TypeInfo {
|
|||
virtual void addSearchPath(const char* path);
|
||||
virtual void removeSearchPath(const char *path);
|
||||
virtual std::string fullPathForFilename(const char* filename, bool unk);
|
||||
void removeAllPaths() = mac 0x241600;
|
||||
}
|
||||
|
||||
class cocos2d::CCGLProgram {
|
||||
|
|
153
loader/include/Geode/c++stl/gdlib.hpp
Normal file
153
loader/include/Geode/c++stl/gdlib.hpp
Normal file
|
@ -0,0 +1,153 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
|
||||
namespace geode::stl {
|
||||
|
||||
template <class Type>
|
||||
class AllocatorTemplate {
|
||||
protected:
|
||||
inline Type* allocate(size_t count);
|
||||
inline void deallocate(Type* pointer);
|
||||
};
|
||||
|
||||
#if defined(GEODE_IS_WINDOWS)
|
||||
template <class Type>
|
||||
class AllocatorBase {
|
||||
protected:
|
||||
inline Type* allocate(size_t count) {
|
||||
|
||||
}
|
||||
inline void deallocate(Type* pointer) {
|
||||
|
||||
}
|
||||
};
|
||||
#elif defined(GEODE_IS_MACOS) || defined(GEODE_IS_ANDROID)
|
||||
|
||||
#elif defined(GEODE_IS_IOS)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
class StringTemplate : public AllocatorBase {
|
||||
protected:
|
||||
// depends on already set size and capacity
|
||||
inline void setStorage(char* pointer) = delete;
|
||||
inline char* getStorage() = delete;
|
||||
|
||||
inline void setSize(size_t size) = delete;
|
||||
inline size_t getSize() = delete;
|
||||
|
||||
inline void setCapacity(size_t capacity) = delete;
|
||||
inline size_t getCapacity() = delete;
|
||||
};
|
||||
|
||||
#if defined(GEODE_IS_WINDOWS)
|
||||
class StringBase : public StringTemplate {
|
||||
protected:
|
||||
union {
|
||||
std::array<char, 16> m_smallStorage;
|
||||
char* m_bigStorage;
|
||||
};
|
||||
|
||||
size_t m_size;
|
||||
size_t m_capacity;
|
||||
|
||||
inline void setStorage(char* storage) {
|
||||
if (m_capacity > 15) {
|
||||
return m_bigStorage = storage;
|
||||
}
|
||||
}
|
||||
inline char* getStorage() {
|
||||
if (m_capacity > 15) {
|
||||
return m_bigStorage;
|
||||
}
|
||||
return m_smallStorage.data();
|
||||
}
|
||||
|
||||
inline void setSize(size_t size) {
|
||||
m_size = size;
|
||||
}
|
||||
inline size_t getSize() {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
inline void setCapacity(size_t capacity) {
|
||||
m_capacity = capacity;
|
||||
}
|
||||
inline size_t getCapacity() {
|
||||
return m_capacity;
|
||||
}
|
||||
};
|
||||
#elif defined(GEODE_IS_MACOS) || defined(GEODE_IS_ANDROID)
|
||||
class StringBase : public StringTemplate {
|
||||
protected:
|
||||
char* m_storage;
|
||||
size_t m_size;
|
||||
size_t m_capacity;
|
||||
|
||||
inline void setStorage(char* storage) {
|
||||
m_storage = storage;
|
||||
}
|
||||
inline char* getStorage() {
|
||||
return m_storage;
|
||||
}
|
||||
|
||||
inline void setSize(size_t size) {
|
||||
m_size = size;
|
||||
}
|
||||
inline size_t getSize() {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
inline void setCapacity(size_t capacity) {
|
||||
m_capacity = capacity;
|
||||
}
|
||||
inline size_t getCapacity() {
|
||||
return m_capacity;
|
||||
}
|
||||
};
|
||||
#elif defined(GEODE_IS_IOS)
|
||||
class StringBase : public StringTemplate {
|
||||
protected:
|
||||
struct Short {
|
||||
uint8_t sizex2;
|
||||
std::array<char, 23> shortStorage;
|
||||
};
|
||||
|
||||
struct Long {
|
||||
size_t capacitym1;
|
||||
size_t size;
|
||||
char* longStorage;
|
||||
};
|
||||
|
||||
union {
|
||||
Short m_short;
|
||||
Long m_long;
|
||||
};
|
||||
|
||||
inline void setStorage(char* storage) {
|
||||
m_storage = storage;
|
||||
}
|
||||
inline char* getStorage() {
|
||||
return m_storage;
|
||||
}
|
||||
|
||||
inline void setSize(size_t size) {
|
||||
m_size = size;
|
||||
}
|
||||
inline size_t getSize() {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
inline void setCapacity(size_t capacity) {
|
||||
m_capacity = capacity;
|
||||
}
|
||||
inline size_t getCapacity() {
|
||||
return m_capacity;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
}
|
|
@ -296,84 +296,166 @@ namespace gd {
|
|||
}
|
||||
};
|
||||
|
||||
// template <class Type>
|
||||
// using vector = std::vector<Type>;
|
||||
|
||||
template <typename T>
|
||||
class GEODE_DLL vector {
|
||||
public:
|
||||
using value_type = T;
|
||||
|
||||
auto allocator() const {
|
||||
return std::allocator<T>();
|
||||
}
|
||||
|
||||
operator std::vector<T>() const {
|
||||
std::vector<T> out;
|
||||
|
||||
for (auto i = m_start; i != m_finish; ++i) {
|
||||
out.push_back(*i);
|
||||
}
|
||||
return out;
|
||||
return std::vector<T>(m_start, m_finish);
|
||||
}
|
||||
|
||||
vector(std::vector<T> input) {
|
||||
std::allocator<T> alloc;
|
||||
auto tmp = alloc.allocate(input.size());
|
||||
vector() {
|
||||
m_start = nullptr;
|
||||
m_finish = nullptr;
|
||||
m_reserveEnd = nullptr;
|
||||
}
|
||||
|
||||
m_start = tmp;
|
||||
m_finish = m_start + input.size();
|
||||
m_capacity_end = m_start + input.size();
|
||||
for (auto i : input) {
|
||||
*tmp = i;
|
||||
tmp++;
|
||||
vector(std::vector<T> const& input) : vector() {
|
||||
if (input.size()) {
|
||||
m_start = this->allocator().allocate(input.size());
|
||||
m_finish = m_start + input.size();
|
||||
m_reserveEnd = m_start + input.size();
|
||||
|
||||
std::copy(input.begin(), input.end(), m_start);
|
||||
}
|
||||
}
|
||||
|
||||
vector(std::initializer_list<T> const& input) {
|
||||
std::allocator<T> alloc;
|
||||
auto tmp = alloc.allocate(input.size());
|
||||
m_start = tmp;
|
||||
m_finish = m_start + input.size();
|
||||
m_capacity_end = m_start + input.size();
|
||||
std::copy(input.begin(), input.end(), tmp);
|
||||
vector(gd::vector<T> const& input) : vector() {
|
||||
if (input.size()) {
|
||||
m_start = this->allocator().allocate(input.size());
|
||||
m_finish = m_start + input.size();
|
||||
m_reserveEnd = m_start + input.size();
|
||||
|
||||
std::copy(input.begin(), input.end(), m_start);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vector(gd::vector<T>&& input) : vector() {
|
||||
m_start = input.m_start;
|
||||
m_finish = input.m_finish;
|
||||
m_reserveEnd = input.m_reserveEnd;
|
||||
|
||||
input.m_start = nullptr;
|
||||
input.m_finish = nullptr;
|
||||
input.m_reserveEnd = nullptr;
|
||||
}
|
||||
|
||||
vector& operator=(gd::vector<T> const& input) {
|
||||
this->clear();
|
||||
|
||||
if (input.size()) {
|
||||
m_start = this->allocator().allocate(input.size());
|
||||
m_finish = m_start + input.size();
|
||||
m_reserveEnd = m_start + input.size();
|
||||
|
||||
std::copy(input.begin(), input.end(), m_start);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
vector& operator=(gd::vector<T>&& input) {
|
||||
m_start = input.m_start;
|
||||
m_finish = input.m_finish;
|
||||
m_reserveEnd = input.m_reserveEnd;
|
||||
|
||||
input.m_start = nullptr;
|
||||
input.m_finish = nullptr;
|
||||
input.m_reserveEnd = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
vector(std::initializer_list<T> const& input) : vector() {
|
||||
if (input.size()) {
|
||||
m_start = this->allocator().allocate(input.size());
|
||||
m_finish = m_start + input.size();
|
||||
m_reserveEnd = m_start + input.size();
|
||||
|
||||
std::copy(input.begin(), input.end(), m_start);
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
std::allocator<T> alloc;
|
||||
alloc.deallocate(m_start, (m_finish - m_start) / 8);
|
||||
m_start = 0;
|
||||
m_finish = 0;
|
||||
m_capacity_end = 0;
|
||||
if (m_start) {
|
||||
std::destroy(m_start, m_finish);
|
||||
|
||||
this->allocator().deallocate(m_start, this->size());
|
||||
}
|
||||
|
||||
m_start = nullptr;
|
||||
m_finish = nullptr;
|
||||
m_reserveEnd = nullptr;
|
||||
}
|
||||
|
||||
T& operator[](size_t index) {
|
||||
return m_start[index];
|
||||
}
|
||||
|
||||
T const& operator[](size_t index) const {
|
||||
return m_start[index];
|
||||
}
|
||||
|
||||
T& at(size_t index) {
|
||||
if (index >= this->size()) {
|
||||
throw std::out_of_range("gd::vector::at");
|
||||
}
|
||||
return m_start[index];
|
||||
}
|
||||
|
||||
T const& at(size_t index) const {
|
||||
if (index >= this->size()) {
|
||||
throw std::out_of_range("gd::vector::at");
|
||||
}
|
||||
return m_start[index];
|
||||
}
|
||||
|
||||
T& front() {
|
||||
return *m_start;
|
||||
}
|
||||
|
||||
auto begin() {
|
||||
T* begin() {
|
||||
return m_start;
|
||||
}
|
||||
|
||||
auto end() {
|
||||
T* end() {
|
||||
return m_finish;
|
||||
}
|
||||
|
||||
auto begin() const {
|
||||
return static_cast<const T*>(m_start);
|
||||
T const* begin() const {
|
||||
return m_start;
|
||||
}
|
||||
|
||||
auto end() const {
|
||||
return static_cast<const T*>(m_finish);
|
||||
T const* end() const {
|
||||
return m_finish;
|
||||
}
|
||||
|
||||
vector(vector const& lol) : vector(std::vector<T>(lol)) {}
|
||||
|
||||
vector() : vector(std::vector<T>()) {}
|
||||
|
||||
~vector() {
|
||||
for (auto i = m_start; i != m_finish; ++i) {
|
||||
delete i;
|
||||
}
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return m_finish - m_start;
|
||||
}
|
||||
|
||||
size_t capacity() const {
|
||||
return m_reserveEnd - m_start;
|
||||
}
|
||||
|
||||
protected:
|
||||
T* m_start;
|
||||
T* m_finish;
|
||||
T* m_capacity_end;
|
||||
T* m_reserveEnd;
|
||||
};
|
||||
|
||||
struct _bit_reference {
|
||||
|
@ -444,24 +526,32 @@ namespace gd {
|
|||
uintptr_t* m_capacity_end;
|
||||
|
||||
public:
|
||||
vector(std::vector<bool> input) : m_start(0), m_end(0) {
|
||||
auto realsize = input.size() / int(sizeof(uintptr_t));
|
||||
auto tmp = new uintptr_t[realsize];
|
||||
|
||||
m_start = _bit_iterator(tmp);
|
||||
m_end = _bit_iterator(tmp + realsize, input.size() % sizeof(uintptr_t));
|
||||
m_capacity_end = tmp + realsize;
|
||||
|
||||
auto itmp = m_start;
|
||||
for (auto i : input) {
|
||||
*itmp = i;
|
||||
++itmp;
|
||||
}
|
||||
auto allocator() const {
|
||||
return std::allocator<uintptr_t>();
|
||||
}
|
||||
|
||||
vector(vector<bool> const& lol) : vector(std::vector<bool>(lol)) {}
|
||||
vector() : m_start(nullptr), m_end(nullptr), m_capacity_end(nullptr) {}
|
||||
|
||||
vector() : vector(std::vector<bool>()) {}
|
||||
// vector(std::vector<bool> input) : vector() {
|
||||
// auto realsize = input.size() / int(sizeof(uintptr_t));
|
||||
// auto start = this->allocator().allocate(realsize);
|
||||
|
||||
// m_start = _bit_iterator(start);
|
||||
// m_end = _bit_iterator(start + realsize, input.size() % sizeof(uintptr_t));
|
||||
// m_capacity_end = start + realsize;
|
||||
|
||||
// auto itmp = m_start;
|
||||
// for (auto i : input) {
|
||||
// *itmp = i;
|
||||
// ++itmp;
|
||||
// }
|
||||
// }
|
||||
|
||||
// vector(vector<bool> const& input) : vector() {
|
||||
|
||||
// }
|
||||
|
||||
// vector() : vector(std::vector<bool>()) {}
|
||||
|
||||
~vector() {
|
||||
delete[] m_start.m_bitptr;
|
||||
|
@ -476,8 +566,8 @@ namespace gd {
|
|||
}
|
||||
|
||||
_bit_reference operator[](size_t index) {
|
||||
const auto real_index = index / sizeof(uintptr_t);
|
||||
const auto offset = index % sizeof(uintptr_t);
|
||||
auto const real_index = index / sizeof(uintptr_t);
|
||||
auto const offset = index % sizeof(uintptr_t);
|
||||
return _bit_reference(&m_start.m_bitptr[real_index], 1UL << offset);
|
||||
}
|
||||
|
||||
|
@ -535,7 +625,7 @@ namespace gd {
|
|||
operator std::vector<T>() {
|
||||
return m_internal;
|
||||
}
|
||||
|
||||
|
||||
void clear() {
|
||||
m_internal.clear();
|
||||
}
|
||||
|
|
5994
loader/include/Geode/external/result/result.hpp
vendored
Normal file
5994
loader/include/Geode/external/result/result.hpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,322 +1,234 @@
|
|||
#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 <fmt/format.h>
|
||||
|
||||
// clang-format off
|
||||
// clang-format on
|
||||
|
||||
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>>;
|
||||
|
||||
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 T, class E>
|
||||
struct Storage {
|
||||
std::variant<T, E> m_value;
|
||||
template <class E = impl::DefaultError>
|
||||
class [[nodiscard]] Failure {
|
||||
public:
|
||||
WrappedResult<E> m_error;
|
||||
|
||||
bool holdsOk() const {
|
||||
return std::holds_alternative<T>(m_value);
|
||||
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;
|
||||
}
|
||||
|
||||
T getOk() const requires std::is_copy_constructible_v<T> {
|
||||
return std::get<T>(m_value);
|
||||
E const& error() const& noexcept {
|
||||
return m_error;
|
||||
}
|
||||
|
||||
T&& getOk() requires(!std::is_copy_constructible_v<T>) {
|
||||
return std::move(std::get<T>(m_value));
|
||||
E&& error() && noexcept {
|
||||
return static_cast<E&&>(m_error);
|
||||
}
|
||||
|
||||
E getErr() const requires std::is_copy_constructible_v<E> {
|
||||
return std::get<E>(m_value);
|
||||
E const&& error() const&& noexcept {
|
||||
return static_cast<E&&>(m_error);
|
||||
}
|
||||
|
||||
E&& getErr() requires(!std::is_copy_constructible_v<E>) {
|
||||
return std::move(std::get<E>(m_value));
|
||||
}
|
||||
|
||||
template<class T2, class E2>
|
||||
requires
|
||||
std::is_convertible_v<T2, T> &&
|
||||
std::is_convertible_v<E2, E>
|
||||
Storage(Storage<T2, E2> const& other)
|
||||
requires
|
||||
std::is_copy_constructible_v<T> &&
|
||||
std::is_copy_constructible_v<E>
|
||||
{
|
||||
if (other.holdsOk()) {
|
||||
m_value = other.getOk();
|
||||
} else {
|
||||
m_value = other.getErr();
|
||||
}
|
||||
}
|
||||
|
||||
Storage(T const& value)
|
||||
requires std::is_copy_constructible_v<T>
|
||||
: m_value(value) {}
|
||||
|
||||
Storage(T&& value)
|
||||
requires std::is_move_constructible_v<T>
|
||||
: m_value(std::forward<T>(value)) {}
|
||||
|
||||
Storage(E const& value, std::monostate)
|
||||
requires std::is_copy_constructible_v<E>
|
||||
: m_value(value) {}
|
||||
|
||||
Storage(E&& value, std::monostate)
|
||||
requires std::is_move_constructible_v<E>
|
||||
: m_value(std::forward<E>(value)) {}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct Storage<T, T> {
|
||||
bool m_holdsOk;
|
||||
T m_value;
|
||||
template <class T = impl::DefaultValue>
|
||||
class [[nodiscard]] Success {
|
||||
public:
|
||||
WrappedResult<T> m_value;
|
||||
|
||||
bool holdsOk() const {
|
||||
return m_holdsOk;
|
||||
}
|
||||
Success() = default;
|
||||
|
||||
T getOk() const requires std::is_copy_constructible_v<T> {
|
||||
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&& getOk() requires(!std::is_copy_constructible_v<T>) {
|
||||
return std::move(m_value);
|
||||
}
|
||||
|
||||
T getErr() const requires std::is_copy_constructible_v<T> {
|
||||
T const& value() const& noexcept {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
T&& getErr() requires(!std::is_copy_constructible_v<T>) {
|
||||
return std::move(m_value);
|
||||
T&& value() && noexcept {
|
||||
return static_cast<T&&>(m_value);
|
||||
}
|
||||
|
||||
template<class T2, class E2>
|
||||
requires
|
||||
std::is_convertible_v<T2, T> &&
|
||||
std::is_convertible_v<E2, T>
|
||||
Storage(Storage<T2, E2> const& other)
|
||||
requires
|
||||
std::is_copy_constructible_v<T> &&
|
||||
std::is_copy_constructible_v<T>
|
||||
: m_value(other.holdsOk() ? other.getOk() : other.getErr()),
|
||||
m_holdsOk(other.holdsOk()) {}
|
||||
|
||||
Storage(T const& value)
|
||||
requires std::is_copy_constructible_v<T>
|
||||
: m_value(value),
|
||||
m_holdsOk(true) {}
|
||||
|
||||
Storage(T&& value)
|
||||
requires std::is_move_constructible_v<T>
|
||||
: m_value(std::forward<T>(value)),
|
||||
m_holdsOk(true) {}
|
||||
|
||||
Storage(T const& value, std::monostate)
|
||||
requires std::is_copy_constructible_v<T>
|
||||
: m_value(value),
|
||||
m_holdsOk(false) {}
|
||||
|
||||
Storage(T&& value, std::monostate)
|
||||
requires std::is_move_constructible_v<T>
|
||||
: m_value(std::forward<T>(value)),
|
||||
m_holdsOk(false) {}
|
||||
T const&& value() const&& noexcept {
|
||||
return static_cast<T&&>(m_value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <class T = DefaultValue, class E = DefaultError>
|
||||
class [[nodiscard]] Result final {
|
||||
template <class T = impl::DefaultValue, class E = impl::DefaultError>
|
||||
class [[nodiscard]] Result : public cpp::result<T, E> {
|
||||
public:
|
||||
using value_type = std::remove_reference_t<T>;
|
||||
using error_type = std::remove_reference_t<E>;
|
||||
using Base = cpp::result<T, E>;
|
||||
using ValueType = typename Base::value_type;
|
||||
using ErrorType = typename Base::error_type;
|
||||
|
||||
// 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!"
|
||||
);
|
||||
using Base::result;
|
||||
|
||||
protected:
|
||||
Storage<value_type, error_type> m_value;
|
||||
template <class U>
|
||||
requires(cpp::detail::result_is_implicit_value_convertible<T, U>::value)
|
||||
constexpr Result(U&& value) = delete;
|
||||
|
||||
public:
|
||||
Storage<value_type, error_type> const& _Raw_Storage() const {
|
||||
return m_value;
|
||||
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->operator bool();
|
||||
}
|
||||
|
||||
bool isOk() const {
|
||||
return m_value.holdsOk();
|
||||
[[nodiscard]] constexpr bool isOk() const noexcept {
|
||||
return this->has_value();
|
||||
}
|
||||
|
||||
bool isErr() const {
|
||||
return !m_value.holdsOk();
|
||||
[[nodiscard]] constexpr bool isErr() const noexcept {
|
||||
return this->has_error();
|
||||
}
|
||||
|
||||
template<class ... Args>
|
||||
Result<T, std::string> expect(const char* str, Args&&... args) {
|
||||
if (isErr()) {
|
||||
return Result<T, std::string>(fmt::format(
|
||||
str,
|
||||
std::forward<Args>(args)...,
|
||||
fmt::arg("error", unwrapErr())
|
||||
), std::monostate());
|
||||
} else {
|
||||
[[nodiscard]] constexpr decltype(auto) unwrap() & {
|
||||
return this->value();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr decltype(auto) unwrap() const& {
|
||||
return this->value();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr decltype(auto) unwrap() && {
|
||||
return this->value();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr decltype(auto) unwrap() const&& {
|
||||
return this->value();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr decltype(auto) unwrapErr() & {
|
||||
return this->error();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr decltype(auto) unwrapErr() const& {
|
||||
return this->error();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr decltype(auto) unwrapErr() && {
|
||||
return this->error();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr decltype(auto) unwrapErr() const&& {
|
||||
return this->error();
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
[[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;
|
||||
}
|
||||
}
|
||||
|
||||
explicit Result(value_type const& value)
|
||||
requires std::is_copy_constructible_v<value_type>
|
||||
: m_value(value) {}
|
||||
|
||||
explicit Result(value_type&& value)
|
||||
requires std::is_move_constructible_v<value_type>
|
||||
: m_value(std::forward<value_type>(value)) {}
|
||||
|
||||
explicit Result(error_type const& value, std::monostate)
|
||||
requires std::is_copy_constructible_v<error_type>
|
||||
: m_value(value, std::monostate()) {}
|
||||
|
||||
explicit Result(error_type&& value, std::monostate)
|
||||
requires std::is_move_constructible_v<error_type>
|
||||
: m_value(std::forward<error_type>(value), std::monostate()) {}
|
||||
|
||||
Result(Result<T, E> const& other)
|
||||
requires
|
||||
std::is_copy_constructible_v<value_type> &&
|
||||
std::is_copy_constructible_v<error_type>
|
||||
= default;
|
||||
|
||||
Result(Result<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
|
||||
std::is_convertible_v<T2, T> &&
|
||||
std::is_convertible_v<E2, E>
|
||||
Result(Result<T2, E2> const& other)
|
||||
requires
|
||||
std::is_copy_constructible_v<value_type> &&
|
||||
std::is_copy_constructible_v<error_type>
|
||||
: m_value(other._Raw_Storage()) {}
|
||||
|
||||
template <class T2>
|
||||
requires ConvertibleToResult<T2, T>
|
||||
Result(Result<T2, AnyType> const& other)
|
||||
requires
|
||||
std::is_copy_constructible_v<value_type> &&
|
||||
std::is_copy_constructible_v<error_type>
|
||||
: Result(value_type(other.unwrap())) {}
|
||||
|
||||
template <class E2>
|
||||
requires ConvertibleToResult<E2, E>
|
||||
Result(Result<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()), std::monostate()) {}
|
||||
|
||||
template <class T2>
|
||||
requires ConvertibleToResult<T2, T>
|
||||
Result(Result<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>
|
||||
Result(Result<AnyType, E2>&& other)
|
||||
requires(
|
||||
!std::is_copy_constructible_v<value_type> ||
|
||||
!std::is_copy_constructible_v<error_type>
|
||||
)
|
||||
: Result(std::forward<error_type>(other.unwrapErr()), std::monostate()) {}
|
||||
|
||||
value_type unwrap() const requires std::is_copy_constructible_v<value_type> {
|
||||
return m_value.getOk();
|
||||
template <class U>
|
||||
[[nodiscard]] constexpr decltype(auto) unwrapOr(U&& val) && {
|
||||
return this->value_or(std::forward<U>(val));
|
||||
}
|
||||
|
||||
value_type&& unwrap() requires(!std::is_copy_constructible_v<value_type>) {
|
||||
return std::forward<value_type>(m_value.getOk());
|
||||
template <class U>
|
||||
[[nodiscard]] constexpr decltype(auto) unwrapOr(U&& val) const& {
|
||||
return this->value_or(std::forward<U>(val));
|
||||
}
|
||||
|
||||
error_type unwrapErr() const requires std::is_copy_constructible_v<error_type> {
|
||||
return m_value.getErr();
|
||||
template <class U>
|
||||
[[nodiscard]] constexpr decltype(auto) errorOr(U&& val) && {
|
||||
return this->error_or(std::forward<U>(val));
|
||||
}
|
||||
|
||||
error_type&& unwrapErr() requires(!std::is_copy_constructible_v<error_type>) {
|
||||
return std::forward<error_type>(m_value.getErr());
|
||||
}
|
||||
|
||||
explicit operator bool() const requires(
|
||||
!std::is_same_v<T, bool> &&
|
||||
!std::is_same_v<E, bool>
|
||||
) {
|
||||
return this->isOk();
|
||||
template <class U>
|
||||
[[nodiscard]] constexpr decltype(auto) errorOr(U&& val) const& {
|
||||
return this->error_or(std::forward<U>(val));
|
||||
}
|
||||
};
|
||||
|
||||
template <class T = DefaultValue, class E = AnyType>
|
||||
requires std::is_copy_constructible_v<T>
|
||||
Result<T, E> Ok(T value = T()) {
|
||||
return Result<T, E>(value);
|
||||
template <class T = impl::DefaultValue>
|
||||
constexpr impl::Success<T> Ok() {
|
||||
return impl::Success<T>();
|
||||
}
|
||||
|
||||
template <class T = DefaultValue, class E = AnyType>
|
||||
requires(!std::is_copy_constructible_v<T>)
|
||||
Result<T, E> Ok(T&& value) {
|
||||
return Result<T, E>(std::forward<T>(value));
|
||||
template <class T>
|
||||
constexpr impl::Success<T> Ok(T&& value) {
|
||||
return impl::Success<T>(std::forward<T>(value));
|
||||
}
|
||||
|
||||
template <class E = DefaultError, class T = AnyType>
|
||||
requires std::is_copy_constructible_v<E>
|
||||
Result<T, E> Err(E error) {
|
||||
return Result<T, E>(error, std::monostate());
|
||||
template <class E>
|
||||
constexpr impl::Failure<E> Err(E&& error) {
|
||||
return impl::Failure<E>(std::forward<E>(error));
|
||||
}
|
||||
|
||||
template <class E = DefaultError, class T = AnyType>
|
||||
requires(!std::is_copy_constructible_v<E>)
|
||||
Result<T, E> Err(E&& error) {
|
||||
return Result<T, E>(std::forward<E>(error), std::monostate());
|
||||
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, ...) \
|
||||
#define GEODE_UNWRAP_INTO(into, ...) \
|
||||
auto GEODE_CONCAT(unwrap_res_, __LINE__) = (__VA_ARGS__); \
|
||||
if (GEODE_CONCAT(unwrap_res_, __LINE__).isErr()) { \
|
||||
return Err(std::move(GEODE_CONCAT(unwrap_res_, __LINE__).unwrapErr())); \
|
||||
} \
|
||||
into = std::move(GEODE_CONCAT(unwrap_res_, __LINE__).unwrap())
|
||||
|
||||
#define GEODE_UNWRAP(...) \
|
||||
{ \
|
||||
auto GEODE_CONCAT(unwrap_res_, __LINE__) = (__VA_ARGS__); \
|
||||
if (GEODE_CONCAT(unwrap_res_, __LINE__).isErr()) { \
|
||||
return Err(std::move(GEODE_CONCAT(unwrap_res_, __LINE__).unwrapErr())); \
|
||||
} \
|
||||
into = std::move(GEODE_CONCAT(unwrap_res_, __LINE__).unwrap())
|
||||
|
||||
#define GEODE_UNWRAP(...) \
|
||||
{ \
|
||||
auto GEODE_CONCAT(unwrap_res_, __LINE__) = (__VA_ARGS__); \
|
||||
if (GEODE_CONCAT(unwrap_res_, __LINE__).isErr()) { \
|
||||
return Err(std::move(GEODE_CONCAT(unwrap_res_, __LINE__).unwrapErr())); \
|
||||
} \
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clang-format on
|
||||
|
|
|
@ -20,10 +20,10 @@ Result<> Hook::enable() {
|
|||
m_enabled = true;
|
||||
m_handle = res.unwrap();
|
||||
return Ok();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return Err(
|
||||
"Unable to create hook at " +
|
||||
std::to_string(reinterpret_cast<uintptr_t>(m_address))
|
||||
"Unable to create hook at " + std::to_string(reinterpret_cast<uintptr_t>(m_address))
|
||||
);
|
||||
}
|
||||
return Err("Hook already has a handle");
|
||||
|
@ -33,8 +33,7 @@ Result<> Hook::enable() {
|
|||
|
||||
Result<> Hook::disable() {
|
||||
if (m_enabled) {
|
||||
if (!geode::core::hook::remove(m_handle))
|
||||
return Err("Unable to remove hook");
|
||||
if (!geode::core::hook::remove(m_handle)) return Err("Unable to remove hook");
|
||||
|
||||
log::debug("Disabling hook at function {}", m_displayName);
|
||||
m_enabled = false;
|
||||
|
|
|
@ -1,20 +1,17 @@
|
|||
#include <string>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include <Geode/loader/Mod.hpp>
|
||||
#include <Geode/loader/Hook.hpp>
|
||||
#include <Geode/loader/Mod.hpp>
|
||||
#include <Geode/utils/file.hpp>
|
||||
|
||||
#include <InternalLoader.hpp>
|
||||
#include <InternalMod.hpp>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
USE_GEODE_NAMESPACE();
|
||||
|
||||
Mod::Mod(ModInfo const& info) {
|
||||
m_info = info;
|
||||
m_saveDirPath = Loader::get()->getGeodeSaveDirectory() /
|
||||
GEODE_MOD_DIRECTORY / info.m_id;
|
||||
m_saveDirPath = Loader::get()->getGeodeSaveDirectory() / GEODE_MOD_DIRECTORY / info.m_id;
|
||||
ghc::filesystem::create_directories(m_saveDirPath);
|
||||
}
|
||||
|
||||
|
@ -27,57 +24,75 @@ Mod::~Mod() {
|
|||
ghc::filesystem::path Mod::getSaveDir() const {
|
||||
return m_saveDirPath;
|
||||
}
|
||||
|
||||
std::string Mod::getID() const {
|
||||
return m_info.m_id;
|
||||
}
|
||||
|
||||
std::string Mod::getName() const {
|
||||
return m_info.m_name;
|
||||
}
|
||||
|
||||
std::string Mod::getDeveloper() const {
|
||||
return m_info.m_developer;
|
||||
}
|
||||
|
||||
std::optional<std::string> Mod::getDescription() const {
|
||||
return m_info.m_description;
|
||||
}
|
||||
|
||||
std::optional<std::string> Mod::getDetails() const {
|
||||
return m_info.m_details;
|
||||
}
|
||||
|
||||
ModInfo Mod::getModInfo() const {
|
||||
return m_info;
|
||||
}
|
||||
|
||||
ghc::filesystem::path Mod::getTempDir() const {
|
||||
return m_tempDirName;
|
||||
}
|
||||
|
||||
ghc::filesystem::path Mod::getBinaryPath() const {
|
||||
return m_tempDirName / m_info.m_binaryName;
|
||||
}
|
||||
|
||||
ghc::filesystem::path Mod::getPackagePath() const {
|
||||
return m_info.m_path;
|
||||
}
|
||||
|
||||
VersionInfo Mod::getVersion() const {
|
||||
return m_info.m_version;
|
||||
}
|
||||
|
||||
bool Mod::isEnabled() const {
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
bool Mod::isLoaded() const {
|
||||
return m_binaryLoaded;
|
||||
}
|
||||
|
||||
bool Mod::supportsDisabling() const {
|
||||
return m_info.m_supportsDisabling;
|
||||
}
|
||||
|
||||
bool Mod::supportsUnloading() const {
|
||||
return m_info.m_supportsUnloading;
|
||||
}
|
||||
|
||||
bool Mod::wasSuccesfullyLoaded() const {
|
||||
return !this->isEnabled() || this->isLoaded();
|
||||
}
|
||||
|
||||
std::vector<Hook*> Mod::getHooks() const {
|
||||
return m_hooks;
|
||||
}
|
||||
|
||||
bool Mod::hasSettings() const {
|
||||
return m_info.m_settings.size();
|
||||
}
|
||||
|
||||
decltype(ModInfo::m_settings) Mod::getSettings() const {
|
||||
return m_info.m_settings;
|
||||
}
|
||||
|
@ -104,7 +119,8 @@ Result<> Mod::loadData() {
|
|||
// load its value
|
||||
if (!setting->load(value.json()))
|
||||
return Err("Unable to load value for setting \"" + key + "\"");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
log::log(
|
||||
Severity::Warning, this,
|
||||
"Encountered unknown setting \"{}\" while loading "
|
||||
|
@ -113,7 +129,8 @@ Result<> Mod::loadData() {
|
|||
);
|
||||
}
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
return Err(std::string("Unable to parse settings: ") + e.what());
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +141,8 @@ Result<> Mod::loadData() {
|
|||
GEODE_UNWRAP_INTO(auto data, utils::file::readString(savedPath));
|
||||
try {
|
||||
m_saved = nlohmann::json::parse(data);
|
||||
} catch(std::exception& e) {
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
return Err(std::string("Unable to parse saved values: ") + e.what());
|
||||
}
|
||||
}
|
||||
|
@ -138,20 +156,13 @@ Result<> Mod::saveData() {
|
|||
// Settings
|
||||
auto json = nlohmann::json::object();
|
||||
for (auto& [key, value] : m_info.m_settings) {
|
||||
if (!value->save(json[key]))
|
||||
return Err("Unable to save setting \"" + key + "\"");
|
||||
if (!value->save(json[key])) return Err("Unable to save setting \"" + key + "\"");
|
||||
}
|
||||
|
||||
GEODE_UNWRAP(utils::file::writeString(
|
||||
m_saveDirPath / "settings.json",
|
||||
json.dump(4)
|
||||
));
|
||||
GEODE_UNWRAP(utils::file::writeString(m_saveDirPath / "settings.json", json.dump(4)));
|
||||
|
||||
// Saved values
|
||||
GEODE_UNWRAP(utils::file::writeString(
|
||||
m_saveDirPath / "saved.json",
|
||||
m_saved.dump(4)
|
||||
));
|
||||
GEODE_UNWRAP(utils::file::writeString(m_saveDirPath / "saved.json", m_saved.dump(4)));
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
@ -180,8 +191,7 @@ Result<> Mod::loadBinary() {
|
|||
if (!m_binaryLoaded) {
|
||||
GEODE_UNWRAP(this->createTempDir().expect("Unable to create temp directory"));
|
||||
|
||||
if (this->hasUnresolvedDependencies())
|
||||
return Err("Mod has unresolved dependencies");
|
||||
if (this->hasUnresolvedDependencies()) return Err("Mod has unresolved dependencies");
|
||||
|
||||
GEODE_UNWRAP(this->loadPlatformBinary());
|
||||
m_binaryLoaded = true;
|
||||
|
@ -206,9 +216,8 @@ Result<> Mod::loadBinary() {
|
|||
|
||||
Result<> Mod::unloadBinary() {
|
||||
if (m_binaryLoaded) {
|
||||
if (!m_info.m_supportsUnloading)
|
||||
return Err("Mod does not support unloading");
|
||||
|
||||
if (!m_info.m_supportsUnloading) return Err("Mod does not support unloading");
|
||||
|
||||
GEODE_UNWRAP(this->saveData());
|
||||
|
||||
GEODE_UNWRAP(this->disable());
|
||||
|
@ -235,8 +244,7 @@ Result<> Mod::unloadBinary() {
|
|||
}
|
||||
|
||||
Result<> Mod::enable() {
|
||||
if (!m_binaryLoaded)
|
||||
return this->loadBinary();
|
||||
if (!m_binaryLoaded) return this->loadBinary();
|
||||
|
||||
for (auto const& hook : m_hooks) {
|
||||
GEODE_UNWRAP(this->enableHook(hook));
|
||||
|
@ -255,8 +263,7 @@ Result<> Mod::enable() {
|
|||
|
||||
Result<> Mod::disable() {
|
||||
if (m_enabled) {
|
||||
if (!m_info.m_supportsDisabling)
|
||||
return Err("Mod does not support disabling");
|
||||
if (!m_info.m_supportsDisabling) return Err("Mod does not support disabling");
|
||||
|
||||
ModStateEvent(this, ModEventType::Disabled).post();
|
||||
|
||||
|
@ -278,8 +285,7 @@ Result<> Mod::uninstall() {
|
|||
if (m_info.m_supportsDisabling) {
|
||||
GEODE_UNWRAP(this->disable());
|
||||
|
||||
if (m_info.m_supportsUnloading)
|
||||
GEODE_UNWRAP(this->unloadBinary());
|
||||
if (m_info.m_supportsUnloading) GEODE_UNWRAP(this->unloadBinary());
|
||||
}
|
||||
|
||||
if (!ghc::filesystem::remove(m_info.m_path)) {
|
||||
|
@ -308,15 +314,15 @@ bool Dependency::isUnresolved() const {
|
|||
bool Mod::updateDependencyStates() {
|
||||
bool hasUnresolved = false;
|
||||
for (auto& dep : m_info.m_dependencies) {
|
||||
if (!dep.m_mod)
|
||||
dep.m_mod = Loader::get()->getLoadedMod(dep.m_id);
|
||||
if (!dep.m_mod) dep.m_mod = Loader::get()->getLoadedMod(dep.m_id);
|
||||
|
||||
if (dep.m_mod) {
|
||||
dep.m_mod->updateDependencyStates();
|
||||
|
||||
if (dep.m_mod->hasUnresolvedDependencies()) {
|
||||
dep.m_state = ModResolveState::Unresolved;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (!dep.m_mod->m_resolved) {
|
||||
dep.m_mod->m_resolved = true;
|
||||
dep.m_state = ModResolveState::Resolved;
|
||||
|
@ -325,15 +331,18 @@ bool Mod::updateDependencyStates() {
|
|||
dep.m_state = ModResolveState::Unloaded;
|
||||
log::log(Severity::Error, dep.m_mod, "{}", r.unwrapErr());
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (dep.m_mod->isEnabled()) {
|
||||
dep.m_state = ModResolveState::Loaded;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
dep.m_state = ModResolveState::Disabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
dep.m_state = ModResolveState::Unloaded;
|
||||
}
|
||||
if (dep.isUnresolved()) {
|
||||
|
@ -352,7 +361,8 @@ bool Mod::updateDependencyStates() {
|
|||
if (!r) {
|
||||
log::error("{} Error loading: {}", this, r.unwrapErr());
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
log::debug("Resolved {}, however not loading it as it is disabled", m_info.m_id);
|
||||
}
|
||||
}
|
||||
|
@ -361,8 +371,7 @@ bool Mod::updateDependencyStates() {
|
|||
|
||||
bool Mod::hasUnresolvedDependencies() const {
|
||||
for (auto const& dep : m_info.m_dependencies) {
|
||||
if (dep.isUnresolved())
|
||||
return true;
|
||||
if (dep.isUnresolved()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -370,8 +379,7 @@ bool Mod::hasUnresolvedDependencies() const {
|
|||
std::vector<Dependency> Mod::getUnresolvedDependencies() {
|
||||
std::vector<Dependency> unresolved;
|
||||
for (auto const& dep : m_info.m_dependencies) {
|
||||
if (dep.isUnresolved())
|
||||
unresolved.push_back(dep);
|
||||
if (dep.isUnresolved()) unresolved.push_back(dep);
|
||||
}
|
||||
return unresolved;
|
||||
}
|
||||
|
@ -386,9 +394,8 @@ bool Mod::depends(std::string const& id) const {
|
|||
|
||||
Result<> Mod::enableHook(Hook* hook) {
|
||||
auto res = hook->enable();
|
||||
if (res)
|
||||
m_hooks.push_back(hook);
|
||||
|
||||
if (res) m_hooks.push_back(hook);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -403,11 +410,12 @@ Result<Hook*> Mod::addHook(Hook* hook) {
|
|||
delete hook;
|
||||
return Err("Can't create hook");
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
InternalLoader::get()->addInternalHook(hook, this);
|
||||
}
|
||||
|
||||
return Ok<Hook*>(hook);
|
||||
return Ok(hook);
|
||||
}
|
||||
|
||||
Result<> Mod::removeHook(Hook* hook) {
|
||||
|
@ -440,7 +448,7 @@ Result<Patch*> Mod::patch(void* address, byte_array data) {
|
|||
return Err("Unable to enable patch at " + std::to_string(p->getAddress()));
|
||||
}
|
||||
m_patches.push_back(p);
|
||||
return Ok<Patch*>(p);
|
||||
return Ok(p);
|
||||
}
|
||||
|
||||
Result<> Mod::unpatch(Patch* patch) {
|
||||
|
@ -473,8 +481,7 @@ Result<> Mod::createTempDir() {
|
|||
GEODE_UNWRAP_INTO(auto unzip, file::Unzip::create(m_info.m_path));
|
||||
if (!unzip.hasEntry(m_info.m_binaryName)) {
|
||||
return Err(fmt::format(
|
||||
"Unable to find platform binary under the name \"{}\"",
|
||||
m_info.m_binaryName
|
||||
"Unable to find platform binary under the name \"{}\"", m_info.m_binaryName
|
||||
));
|
||||
}
|
||||
GEODE_UNWRAP(unzip.extractAllTo(tempPath));
|
||||
|
@ -495,10 +502,9 @@ ghc::filesystem::path Mod::getConfigDir(bool create) const {
|
|||
return dir;
|
||||
}
|
||||
|
||||
const char* Mod::expandSpriteName(const char* name) {
|
||||
static std::unordered_map<std::string, const char*> expanded = {};
|
||||
if (expanded.count(name))
|
||||
return expanded[name];
|
||||
char const* Mod::expandSpriteName(char const* name) {
|
||||
static std::unordered_map<std::string, char const*> expanded = {};
|
||||
if (expanded.count(name)) return expanded[name];
|
||||
|
||||
auto exp = new char[strlen(name) + 2 + m_info.m_id.size()];
|
||||
auto exps = m_info.m_id + "/" + name;
|
||||
|
|
|
@ -123,7 +123,7 @@ Result<ModInfo> ModInfo::create(ModJson const& json) {
|
|||
if (schema < Loader::minModVersion()) {
|
||||
return Err(
|
||||
"[mod.json] is built for an older version (" + schema.toString() +
|
||||
") of Geode (current: " + Loader::minModVersion().toString() +
|
||||
") of Geode (current: " + Loader::getVersion().toString() +
|
||||
"). Please update the mod to the latest version, "
|
||||
"and if the problem persists, contact the developer "
|
||||
"to update it."
|
||||
|
@ -132,7 +132,7 @@ Result<ModInfo> ModInfo::create(ModJson const& json) {
|
|||
if (schema > Loader::maxModVersion()) {
|
||||
return Err(
|
||||
"[mod.json] is built for a newer version (" + schema.toString() +
|
||||
") of Geode (current: " + Loader::maxModVersion().toString() +
|
||||
") of Geode (current: " + Loader::getVersion().toString() +
|
||||
"). You need to update Geode in order to use "
|
||||
"this mod."
|
||||
);
|
||||
|
|
|
@ -5,10 +5,6 @@
|
|||
#include <cocos2d.h>
|
||||
using namespace cocos2d;
|
||||
|
||||
void CCFileUtils::removeAllPaths() {
|
||||
m_searchPathArray.clear();
|
||||
}
|
||||
|
||||
CCObject* CCObject::copy()
|
||||
{
|
||||
return copyWithZone(0);
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
#include <Geode/binding/LoadingCircle.hpp>
|
||||
#include <Geode/ui/Notification.hpp>
|
||||
#include <Geode/loader/Mod.hpp>
|
||||
#include <Geode/ui/Notification.hpp>
|
||||
|
||||
USE_GEODE_NAMESPACE();
|
||||
|
||||
constexpr auto NOTIFICATION_FADEIN = .3f;
|
||||
constexpr auto NOTIFICATION_FADEIN = .3f;
|
||||
constexpr auto NOTIFICATION_FADEOUT = 1.f;
|
||||
|
||||
Ref<CCArray> Notification::s_queue = CCArray::create();
|
||||
|
||||
bool Notification::init(std::string const& text, CCSprite* icon, float time) {
|
||||
if (!CCNodeRGBA::init())
|
||||
return false;
|
||||
|
||||
if (!CCNodeRGBA::init()) return false;
|
||||
|
||||
m_time = time;
|
||||
|
||||
|
||||
m_bg = CCScale9Sprite::create("square02b_small.png", { 0, 0, 40, 40 });
|
||||
m_bg->setColor({ 0, 0, 0 });
|
||||
this->addChild(m_bg);
|
||||
|
@ -48,7 +47,8 @@ void Notification::updateLayout() {
|
|||
if (m_icon) {
|
||||
m_icon->setPosition({ size.height / 2, size.height / 2 });
|
||||
m_label->setPosition(size / 2 + CCSize { spaceForIcon / 2, .0f });
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
m_label->setPosition(size / 2);
|
||||
}
|
||||
}
|
||||
|
@ -73,9 +73,7 @@ CCSprite* Notification::createIcon(NotificationIcon icon) {
|
|||
|
||||
case NotificationIcon::Loading: {
|
||||
auto icon = CCSprite::create("loadingCircle.png");
|
||||
icon->runAction(CCRepeatForever::create(
|
||||
CCRotateBy::create(1.f, 360.f)
|
||||
));
|
||||
icon->runAction(CCRepeatForever::create(CCRotateBy::create(1.f, 360.f)));
|
||||
icon->setBlendFunc({ GL_ONE, GL_ONE });
|
||||
return icon;
|
||||
} break;
|
||||
|
@ -94,11 +92,7 @@ CCSprite* Notification::createIcon(NotificationIcon icon) {
|
|||
}
|
||||
}
|
||||
|
||||
Notification* Notification::create(
|
||||
std::string const& text,
|
||||
NotificationIcon icon,
|
||||
float time
|
||||
) {
|
||||
Notification* Notification::create(std::string const& text, NotificationIcon icon, float time) {
|
||||
return Notification::create(text, createIcon(icon), time);
|
||||
}
|
||||
|
||||
|
@ -125,7 +119,8 @@ void Notification::setIcon(cocos2d::CCSprite* icon) {
|
|||
if (m_icon) {
|
||||
m_icon->removeFromParent();
|
||||
}
|
||||
if (m_icon = icon) {
|
||||
m_icon = icon;
|
||||
if (icon) {
|
||||
m_bg->addChild(icon);
|
||||
}
|
||||
this->updateLayout();
|
||||
|
@ -171,8 +166,7 @@ void Notification::show() {
|
|||
CCCallFunc::create(this, callfunc_selector(Notification::animateIn)),
|
||||
// wait for fade-in to finish
|
||||
CCDelayTime::create(NOTIFICATION_FADEIN),
|
||||
CCCallFunc::create(this, callfunc_selector(Notification::wait)),
|
||||
nullptr
|
||||
CCCallFunc::create(this, callfunc_selector(Notification::wait)), nullptr
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -181,8 +175,7 @@ void Notification::wait() {
|
|||
if (m_time) {
|
||||
this->runAction(CCSequence::create(
|
||||
CCDelayTime::create(m_time),
|
||||
CCCallFunc::create(this, callfunc_selector(Notification::hide)),
|
||||
nullptr
|
||||
CCCallFunc::create(this, callfunc_selector(Notification::hide)), nullptr
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -193,8 +186,6 @@ void Notification::hide() {
|
|||
CCCallFunc::create(this, callfunc_selector(Notification::animateOut)),
|
||||
// wait for fade-out to finish
|
||||
CCDelayTime::create(NOTIFICATION_FADEOUT),
|
||||
CCCallFunc::create(this, callfunc_selector(Notification::showNextNotification)),
|
||||
nullptr
|
||||
CCCallFunc::create(this, callfunc_selector(Notification::showNextNotification)), nullptr
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <Geode/utils/cocos.hpp>
|
||||
#include <Geode/modify/LoadingLayer.hpp>
|
||||
#include <Geode/utils/cocos.hpp>
|
||||
|
||||
USE_GEODE_NAMESPACE();
|
||||
|
||||
|
@ -346,7 +346,7 @@ void geode::cocos::reloadTextures(CreateLayerFunc returnTo) {
|
|||
GameManager::get()->reloadAll(false, false, true);
|
||||
}
|
||||
|
||||
class $modify(LoadingLayer) {
|
||||
struct LoadingFinished : Modify<LoadingFinished, LoadingLayer> {
|
||||
void loadAssets() {
|
||||
// loadFinished is inlined on Macchew OS :sob:
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#include <Geode/utils/file.hpp>
|
||||
#include <Geode/utils/string.hpp>
|
||||
#include <Geode/utils/map.hpp>
|
||||
#include <Geode/loader/Log.hpp>
|
||||
#include <fstream>
|
||||
#include <../support/zip_support/ZipUtils.h>
|
||||
#include <../support/zip_support/ioapi.h>
|
||||
#include <../support/zip_support/unzip.h>
|
||||
#include <Geode/loader/Log.hpp>
|
||||
#include <Geode/utils/file.hpp>
|
||||
#include <Geode/utils/map.hpp>
|
||||
#include <Geode/utils/string.hpp>
|
||||
#include <fstream>
|
||||
|
||||
USE_GEODE_NAMESPACE();
|
||||
using namespace geode::utils::file;
|
||||
|
@ -143,9 +143,7 @@ public:
|
|||
unz_file_info64 fileInfo;
|
||||
|
||||
// Read first file
|
||||
if (unzGoToFirstFile64(
|
||||
m_zip, &fileInfo, fileName, sizeof(fileName) - 1
|
||||
)) {
|
||||
if (unzGoToFirstFile64(m_zip, &fileInfo, fileName, sizeof(fileName) - 1)) {
|
||||
return false;
|
||||
}
|
||||
// Loop over all files
|
||||
|
@ -153,18 +151,15 @@ public:
|
|||
// Read file and add to entries
|
||||
unz_file_pos pos;
|
||||
if (unzGetFilePos(m_zip, &pos) == UNZ_OK) {
|
||||
m_entries.insert({
|
||||
fileName, ZipEntry {
|
||||
.m_pos = pos,
|
||||
.m_compressedSize = fileInfo.compressed_size,
|
||||
.m_uncompressedSize = fileInfo.uncompressed_size,
|
||||
}
|
||||
});
|
||||
m_entries.insert({ fileName,
|
||||
ZipEntry {
|
||||
.m_pos = pos,
|
||||
.m_compressedSize = fileInfo.compressed_size,
|
||||
.m_uncompressedSize = fileInfo.uncompressed_size,
|
||||
} });
|
||||
}
|
||||
// Read next file, or break on error
|
||||
if (unzGoToNextFile64(
|
||||
m_zip, &fileInfo, fileName, sizeof(fileName) - 1
|
||||
) != UNZ_OK) {
|
||||
if (unzGoToNextFile64(m_zip, &fileInfo, fileName, sizeof(fileName) - 1) != UNZ_OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -204,6 +199,7 @@ public:
|
|||
}
|
||||
|
||||
UnzipImpl(unzFile zip, Path const& path) : m_zip(zip), m_zipPath(path) {}
|
||||
|
||||
~UnzipImpl() {
|
||||
unzClose(m_zip);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue