add Mod::checkUpdates to replace Mod::hasUpdatesAvailable

This commit is contained in:
HJfod 2024-07-06 17:06:50 +03:00
parent d9d4c113ef
commit 9d02155d76
7 changed files with 36 additions and 139 deletions

View file

@ -244,130 +244,4 @@ namespace geode {
virtual ~Event();
};
// template <is_filter F, std::move_constructible T>
// class [[nodiscard]] EventMapper final {
// public:
// using Value = T;
// class Handle final {
// std::optional<EventListener<F>> m_listener;
// class PrivateMarker final {};
// static std::shared_ptr<Handle> create() {
// return std::make_shared<Handle>(PrivateMarker());
// }
// friend class EventMapper;
// public:
// Handle(PrivateMarker) {}
// };
// class Event final : public geode::Event {
// private:
// std::shared_ptr<Handle> m_handle;
// T m_value;
// Event(std::shared_ptr<Handle> handle, T&& value)
// : m_handle(handle), m_value(std::move(value)) {}
// friend class EventMapper;
// public:
// T& getValue() & {
// return m_value;
// }
// T const& getValue() const& {
// return m_value;
// }
// T&& getValue() && {
// return std::move(m_value);
// }
// operator T*() const {
// return m_value;
// }
// T* operator*() const {
// return m_value;
// }
// T* operator->() const {
// return m_value;
// }
// };
// using Mapper = utils::MiniFunction<T(typename F::Event*)>;
// using Callback = void(Event*);
// private:
// EventListenerProtocol* m_listener = nullptr;
// std::shared_ptr<Handle> m_handle;
// EventMapper(std::shared_ptr<Handle> handle) : m_handle(handle) {}
// public:
// EventMapper() : m_handle(nullptr) {}
// static EventMapper immediate(T&& value) {
// auto emapper = EventMapper(Handle::create());
// Loader::get()->queueInMainThread([handle = emapper.m_handle, value = std::move(value)]() mutable {
// EventMapper::Event(handle, std::move(value)).post();
// });
// return emapper;
// }
// static EventMapper create(F&& filter, Mapper&& mapper) {
// auto emapper = EventMapper(Handle::create());
// emapper.m_handle->m_listener.emplace(EventListener(
// // The event listener should not own itself (circular ref = memory leak!!)
// [handle = std::weak_ptr(emapper.m_handle), mapper = std::move(mapper)](F::Event* event) {
// if (auto lock = handle.lock()) {
// EventMapper::Event(lock, mapper(event)).post();
// }
// },
// std::move(filter)
// ));
// return emapper;
// }
// template <class NewMapper>
// auto map(NewMapper&& mapper) {
// using T2 = decltype(mapper(std::declval<T*>()));
// return mapEvent(*this, [mapper = std::move(mapper)](Event* event) -> T2 {
// return mapper(&event->getValue());
// });
// }
// ListenerResult handle(utils::MiniFunction<Callback> fn, Event* e) {
// if (e->m_handle == m_handle) {
// fn(e);
// }
// return ListenerResult::Propagate;
// }
// // todo: i believe alk wanted these to be in their own pool
// EventListenerPool* getPool() const {
// return DefaultEventListenerPool::get();
// }
// void setListener(EventListenerProtocol* listener) {
// m_listener = listener;
// }
// EventListenerProtocol* getListener() const {
// return m_listener;
// }
// };
// template <is_filter F, class Mapper>
// static auto mapEvent(F&& filter, Mapper&& mapper) {
// using T = decltype(mapper(std::declval<typename F::Event*>()));
// return EventMapper<F, T>::create(std::move(filter), std::move(mapper));
// }
// template <is_filter F, class Mapper>
// requires std::copy_constructible<F>
// static auto mapEvent(F const& filter, Mapper&& mapper) {
// using T = decltype(mapper(std::declval<typename F::Event*>()));
// return EventMapper<F, T>::create(F(filter), std::move(mapper));
// }
}

View file

@ -142,8 +142,22 @@ namespace geode {
* @returns The latest available version on the index if there are
* updates for this mod
*/
[[deprecated("Use Mod::checkUpdates instead; this function always returns nullopt")]]
std::optional<VersionInfo> hasAvailableUpdate() const;
using CheckUpdatesTask = Task<Result<std::optional<VersionInfo>, std::string>>;
/**
* Check if this Mod has updates available on the mods index. If
* you're using this for automatic update checking, use
* `openInfoPopup` from the `ui/GeodeUI.hpp` header to open the Mod's
* page to let the user install the update
* @returns A task that resolves to an option, either the latest
* available version on the index if there are updates available, or
* `std::nullopt` if there are no updates. On error, the Task returns
* an error
*/
CheckUpdatesTask checkUpdates() const;
Result<> saveData();
Result<> loadData();

View file

@ -103,7 +103,6 @@ namespace geode {
class FieldIntermediate;
}
// TODO: make ordered
using ModJson = matjson::Value;
}

View file

@ -22,7 +22,6 @@
#include <queue>
#include <tulip/TulipHook.hpp>
// TODO: Find a file convention for impl headers
namespace geode {
static constexpr std::string_view LAUNCH_ARG_PREFIX = "--geode:";

View file

@ -4,6 +4,7 @@
#include <Geode/loader/Mod.hpp>
#include <optional>
#include <string_view>
#include <server/Server.hpp>
using namespace geode::prelude;
@ -101,17 +102,27 @@ std::vector<Mod*> Mod::getDependants() const {
#endif
std::optional<VersionInfo> Mod::hasAvailableUpdate() const {
// TODO
// if (auto item = Index::get()->getItem(this->getID(), std::nullopt)) {
// if (
// item->getMetadata().getVersion() > this->getVersion() &&
// item->getAvailablePlatforms().contains(GEODE_PLATFORM_TARGET)
// ) {
// return item->getMetadata().getVersion();
// }
// }
return std::nullopt;
}
Mod::CheckUpdatesTask Mod::checkUpdates() const {
server::checkUpdates(this).map([](server::ServerRequest<std::optional<server::ServerModUpdate>>::Value* result) -> Mod::CheckUpdatesTask::Value {
if (result->isOk()) {
if (auto value = result->unwrap()) {
if (value->replacement) {
return Err(
"Mod has been replaced by {} - please visit the Geode "
"menu to install the replacement",
value->replacement->id
);
}
return Ok(value->version);
}
return Ok(std::nullopt);
}
auto err = result->unwrapErr();
return Err("{} (code {})", err.details, err.code);
});
}
Result<> Mod::saveData() {
return m_impl->saveData();

View file

@ -770,7 +770,7 @@ ServerRequest<std::unordered_set<std::string>> server::getTags(bool useCache) {
);
}
ServerRequest<std::optional<ServerModUpdate>> server::checkUpdates(Mod* mod) {
ServerRequest<std::optional<ServerModUpdate>> server::checkUpdates(Mod const* mod) {
return checkAllUpdates().map(
[mod](Result<std::vector<ServerModUpdate>, ServerError>* result) -> Result<std::optional<ServerModUpdate>, ServerError> {
if (result->isOk()) {

View file

@ -150,7 +150,7 @@ namespace server {
ServerRequest<ByteVector> getModLogo(std::string const& id, bool useCache = true);
ServerRequest<std::unordered_set<std::string>> getTags(bool useCache = true);
ServerRequest<std::optional<ServerModUpdate>> checkUpdates(Mod* mod);
ServerRequest<std::optional<ServerModUpdate>> checkUpdates(Mod const* mod);
ServerRequest<std::vector<ServerModUpdate>> checkAllUpdates(bool useCache = true);
void clearServerCaches(bool clearGlobalCaches = false);