mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-14 11:05:08 -05:00
Compare commits
13 commits
0ee9aebdee
...
f96ea5e727
Author | SHA1 | Date | |
---|---|---|---|
|
f96ea5e727 | ||
|
0b2fc66a89 | ||
|
df2528c8a5 | ||
|
03a4387c80 | ||
|
5c85b3c48d | ||
|
123b3abff3 | ||
|
6d13f7837d | ||
|
9b95301472 | ||
|
02845d967e | ||
|
2d66279243 | ||
|
b662aac29d | ||
|
c197e2913c | ||
|
ab196b9adf |
7 changed files with 80 additions and 31 deletions
|
@ -236,8 +236,8 @@ if (ANDROID)
|
|||
endif()
|
||||
|
||||
set(MAT_JSON_AS_INTERFACE ON)
|
||||
CPMAddPackage("gh:geode-sdk/result@1.2.0")
|
||||
CPMAddPackage("gh:geode-sdk/json@3.0.2")
|
||||
CPMAddPackage("gh:geode-sdk/result@1.2.1")
|
||||
CPMAddPackage("gh:geode-sdk/json@3.0.3")
|
||||
CPMAddPackage("gh:fmtlib/fmt#11.0.2")
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} INTERFACE MAT_JSON_DYNAMIC=1)
|
||||
|
@ -267,7 +267,7 @@ if (DEFINED GEODE_TULIPHOOK_REPO_PATH)
|
|||
message(STATUS "Using ${GEODE_TULIPHOOK_REPO_PATH} for TulipHook")
|
||||
add_subdirectory(${GEODE_TULIPHOOK_REPO_PATH} ${GEODE_TULIPHOOK_REPO_PATH}/build)
|
||||
else()
|
||||
CPMAddPackage("gh:geode-sdk/TulipHook@2.4.0")
|
||||
CPMAddPackage("gh:geode-sdk/TulipHook@2.4.1")
|
||||
endif()
|
||||
set(CMAKE_WARN_DEPRECATED ON CACHE BOOL "" FORCE)
|
||||
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
4.0.0
|
||||
4.0.0-alpha.1
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
namespace geode {
|
||||
namespace geode_internal {
|
||||
template <class T>
|
||||
template <class T, class P>
|
||||
struct TaskPromise;
|
||||
|
||||
template <class T, class P>
|
||||
|
@ -161,7 +161,7 @@ namespace geode {
|
|||
template <std::move_constructible T2, std::move_constructible P2>
|
||||
friend class Task;
|
||||
|
||||
template <class>
|
||||
template <class, class>
|
||||
friend struct geode_internal::TaskPromise;
|
||||
|
||||
template <class, class>
|
||||
|
@ -322,7 +322,7 @@ namespace geode {
|
|||
template <std::move_constructible T2, std::move_constructible P2>
|
||||
friend class Task;
|
||||
|
||||
template <class>
|
||||
template <class, class>
|
||||
friend struct geode_internal::TaskPromise;
|
||||
|
||||
template <class, class>
|
||||
|
@ -924,12 +924,22 @@ namespace geode {
|
|||
//
|
||||
// The body of the coroutine is ran in whatever thread it got called in.
|
||||
// TODO: maybe guarantee main thread?
|
||||
//
|
||||
// The coroutine can also yield progress values using `co_yield`:
|
||||
// ```
|
||||
// Task<std::string, int> someTask() {
|
||||
// for (int i = 0; i < 10; i++) {
|
||||
// co_yield i;
|
||||
// }
|
||||
// co_return "done!";
|
||||
// }
|
||||
// ```
|
||||
|
||||
namespace geode {
|
||||
namespace geode_internal {
|
||||
template <class T>
|
||||
template <class T, class P>
|
||||
struct TaskPromise {
|
||||
using MyTask = Task<T>;
|
||||
using MyTask = Task<T, P>;
|
||||
std::weak_ptr<typename MyTask::Handle> m_handle;
|
||||
|
||||
~TaskPromise() {
|
||||
|
@ -948,10 +958,15 @@ namespace geode {
|
|||
return handle;
|
||||
}
|
||||
|
||||
void return_value(T&& x) {
|
||||
void return_value(T x) {
|
||||
MyTask::finish(m_handle.lock(), std::move(x));
|
||||
}
|
||||
|
||||
std::suspend_never yield_value(P value) {
|
||||
MyTask::progress(m_handle.lock(), std::move(value));
|
||||
return {};
|
||||
}
|
||||
|
||||
bool isCancelled() {
|
||||
if (auto p = m_handle.lock()) {
|
||||
return p->is(MyTask::Status::Cancelled);
|
||||
|
@ -968,8 +983,8 @@ namespace geode {
|
|||
return task.isFinished();
|
||||
}
|
||||
|
||||
template <class U>
|
||||
void await_suspend(std::coroutine_handle<TaskPromise<U>> handle) {
|
||||
template <class U, class V>
|
||||
void await_suspend(std::coroutine_handle<TaskPromise<U, V>> handle) {
|
||||
if (handle.promise().isCancelled()) {
|
||||
handle.destroy();
|
||||
return;
|
||||
|
@ -981,7 +996,7 @@ namespace geode {
|
|||
handle.destroy();
|
||||
return;
|
||||
}
|
||||
parentHandle->m_extraData = std::make_unique<typename Task<U>::Handle::ExtraData>(
|
||||
parentHandle->m_extraData = std::make_unique<typename Task<U, V>::Handle::ExtraData>(
|
||||
static_cast<void*>(new EventListener<Task<T, P>>(
|
||||
[handle](auto* event) {
|
||||
if (event->getValue()) {
|
||||
|
@ -1014,7 +1029,7 @@ auto operator co_await(geode::Task<T, P> task) {
|
|||
return geode::geode_internal::TaskAwaiter<T, P>{task};
|
||||
}
|
||||
|
||||
template <class T, class... Args>
|
||||
struct std::coroutine_traits<geode::Task<T>, Args...> {
|
||||
using promise_type = geode::geode_internal::TaskPromise<T>;
|
||||
template <class T, class P, class... Args>
|
||||
struct std::coroutine_traits<geode::Task<T, P>, Args...> {
|
||||
using promise_type = geode::geode_internal::TaskPromise<T, P>;
|
||||
};
|
|
@ -41,9 +41,9 @@ $execute {
|
|||
// hook them to call our own handler
|
||||
if (LoaderImpl::get()->isForwardCompatMode()) return;
|
||||
|
||||
#if GEODE_COMP_GD_VERSION == 22060
|
||||
const uintptr_t offset1 = 0x75d00; // member function in CCEGLView
|
||||
const uintptr_t offset2 = 0x75d60; // static function
|
||||
#if GEODE_COMP_GD_VERSION == 22074
|
||||
const uintptr_t offset1 = 0x75D90; // member function in CCEGLView
|
||||
const uintptr_t offset2 = 0x75DF0; // static function
|
||||
|
||||
(void) Mod::get()->hook(
|
||||
reinterpret_cast<void*>(geode::base::getCocos() + offset1),
|
||||
|
|
|
@ -136,7 +136,7 @@ void SettingNodeV3::updateState(CCNode* invoker) {
|
|||
m_impl->bg->setOpacity(75);
|
||||
}
|
||||
|
||||
m_impl->nameMenu->setContentWidth(this->getContentWidth() - m_impl->buttonMenu->getContentWidth() - 20);
|
||||
m_impl->nameMenu->setContentWidth(this->getContentWidth() - m_impl->buttonMenu->getContentWidth() - 25);
|
||||
m_impl->nameMenu->updateLayout();
|
||||
}
|
||||
|
||||
|
@ -462,6 +462,7 @@ void FileSettingNodeV3::updateState(CCNode* invoker) {
|
|||
// which is clever and good UX but also a hack so I also need to hack to support that
|
||||
const auto isTextualDefaultValue = [this, setting = this->getSetting()]() {
|
||||
if (this->hasNonDefaultValue()) return false;
|
||||
if (setting->getDefaultValue().string().size() > 20) return false;
|
||||
std::error_code ec;
|
||||
return setting->isFolder() ?
|
||||
!std::filesystem::is_directory(setting->getDefaultValue(), ec) :
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
#include "ModItem.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <Geode/ui/GeodeUI.hpp>
|
||||
#include <Geode/utils/ColorProvider.hpp>
|
||||
#include <Geode/binding/ButtonSprite.hpp>
|
||||
#include <Geode/loader/Loader.hpp>
|
||||
#include <vector>
|
||||
#include "../GeodeStyle.hpp"
|
||||
#include "../popups/ModPopup.hpp"
|
||||
#include "../popups/DevPopup.hpp"
|
||||
#include "ui/mods/GeodeStyle.hpp"
|
||||
#include "ui/mods/popups/ModPopup.hpp"
|
||||
#include "ui/mods/popups/DevPopup.hpp"
|
||||
#include "ui/mods/popups/ModErrorPopup.hpp"
|
||||
#include "ui/mods/sources/ModSource.hpp"
|
||||
#include "../../GeodeUIEvent.hpp"
|
||||
#include "ui/GeodeUIEvent.hpp"
|
||||
|
||||
bool ModItem::init(ModSource&& source) {
|
||||
if (!CCNode::init())
|
||||
|
@ -422,13 +426,31 @@ void ModItem::updateState() {
|
|||
// If there were problems, tint the BG red
|
||||
m_outdatedLabel->setVisible(false);
|
||||
if (m_source.asMod()) {
|
||||
std::optional<LoadProblem> targetsOutdated = m_source.asMod()->targetsOutdatedVersion();
|
||||
if (m_source.asMod()->hasLoadProblems()) {
|
||||
m_bg->setColor("mod-list-errors-found"_cc3b);
|
||||
m_bg->setOpacity(isGeodeTheme() ? 25 : 90);
|
||||
}
|
||||
if (m_source.asMod()->targetsOutdatedVersion()) {
|
||||
if (!wantsRestart && targetsOutdated) {
|
||||
LoadProblem problem = targetsOutdated.value();
|
||||
m_bg->setColor("mod-list-outdated-label"_cc3b);
|
||||
m_bg->setOpacity(isGeodeTheme() ? 25 : 90);
|
||||
std::string content;
|
||||
if (
|
||||
problem.type == LoadProblem::Type::UnsupportedGeodeVersion ||
|
||||
problem.type == LoadProblem::Type::NeedsNewerGeodeVersion
|
||||
) {
|
||||
content = fmt::format(
|
||||
"Outdated (Geode {})",
|
||||
m_source.getMetadata().getGeodeVersion().toNonVString()
|
||||
);
|
||||
} else {
|
||||
content = fmt::format(
|
||||
"Outdated (GD {})",
|
||||
m_source.getMetadata().getGameVersion().value_or("*")
|
||||
);
|
||||
}
|
||||
m_outdatedLabel->setString(content.c_str());
|
||||
m_outdatedLabel->setVisible(true);
|
||||
m_developers->setVisible(false);
|
||||
}
|
||||
|
@ -568,13 +590,13 @@ void ModItem::onViewError(CCObject*) {
|
|||
"the mod</c> that supports the newer version.";
|
||||
} break;
|
||||
|
||||
case LoadProblem::Type::UnsupportedGeodeVersion: {
|
||||
case LoadProblem::Type::NeedsNewerGeodeVersion: {
|
||||
issue = "This mod is made for a <cp>newer version of Geode</c>.";
|
||||
howToFix = "<cp>update Geode</c> by enabling <co>Automatic Updates</c> "
|
||||
"or redownloading it from the Geode website.";
|
||||
} break;
|
||||
|
||||
case LoadProblem::Type::NeedsNewerGeodeVersion: {
|
||||
case LoadProblem::Type::UnsupportedGeodeVersion: {
|
||||
issue = "This mod is made for an <cy>older version of Geode</c>.";
|
||||
howToFix = "wait for the developer to <cj>release an update to "
|
||||
"the mod</c> that supports the newer version.";
|
||||
|
|
|
@ -352,7 +352,7 @@ bool ModList::init(ModListSource* src, CCSize const& size) {
|
|||
m_statusDetailsBtn->setID("status-details-button");
|
||||
m_statusContainer->addChild(m_statusDetailsBtn);
|
||||
|
||||
m_statusDetails = SimpleTextArea::create("", "chatFont.fnt", .6f);
|
||||
m_statusDetails = SimpleTextArea::create("", "chatFont.fnt", .6f, 650.f);
|
||||
m_statusDetails->setID("status-details-input");
|
||||
m_statusDetails->setAlignment(kCCTextAlignmentCenter);
|
||||
m_statusContainer->addChild(m_statusDetails);
|
||||
|
@ -649,8 +649,19 @@ void ModList::showStatus(ModListStatus status, std::string const& message, std::
|
|||
m_statusContainer->setVisible(true);
|
||||
m_statusDetails->setVisible(false);
|
||||
m_statusDetailsBtn->setVisible(details.has_value());
|
||||
m_statusLoadingCircle->setVisible(std::holds_alternative<ModListUnkProgressStatus>(status));
|
||||
m_statusLoadingBar->setVisible(std::holds_alternative<ModListProgressStatus>(status));
|
||||
m_statusLoadingCircle->setVisible(
|
||||
std::holds_alternative<ModListUnkProgressStatus>(status)
|
||||
|| std::holds_alternative<ModListProgressStatus>(status)
|
||||
);
|
||||
|
||||
// the loading bar makes no sense to display - it's meant for progress of mod list page loading
|
||||
// however the mod list pages are so small, that there usually isn't a scenario where the loading
|
||||
// takes longer than a single frame - therefore this is useless
|
||||
// server processing time isn't included in this - it's only after the server starts responding
|
||||
// that we get any progress information
|
||||
// also the position is wrong if you wanna restore the functionality
|
||||
//m_statusLoadingBar->setVisible(std::holds_alternative<ModListProgressStatus>(status));
|
||||
m_statusLoadingBar->setVisible(false);
|
||||
|
||||
// Update progress bar
|
||||
if (auto per = std::get_if<ModListProgressStatus>(&status)) {
|
||||
|
|
Loading…
Reference in a new issue