get ready for v0.4.5 release

- update changelog
 - add documentation to AsyncWebRequest
 - remove some debugs
This commit is contained in:
HJfod 2022-10-13 22:30:57 +03:00
parent 7dd94422b4
commit 22ee4b3f29
3 changed files with 154 additions and 10 deletions

View file

@ -1,5 +1,36 @@
# Geode Changelog
## v0.4.5
- Rework bindings and codegen to improve compile times, now individual bindings can be included with `<Geode/binding/{ClassName}.hpp>`
- Modify has also been separated, you can now include individual modifiers with `<Geode/modify/{ClassName}.hpp>`
- Various other fixes to improve compile times
- Fix mod resources not being loaded when installed from Index
- Fix crashes related to downloading mods
- Fix `Loader::queueInGDThread` sometimes leaving out functions
- Fix crashes related to logging
- Add new overloads to `file` utils and deprecate ones that don't use `ghc::filesystem::path`
- Index mods now show their `about.md` files
- More addresses
- Various other fixes & improvements
- Index reworked
- Fix issues with `VERSION` file
- Add `GEODE_DEBUG` macro for enabling `log::debug` to actually print stuff
- Show crashlog on crash when `GEODE_DEBUG` is enabled
- Add `JsonChecker::at` and `JsonChecker::array` for dealing with arrays
- Add `geode::utils::web::fetchBytes` for fetching a byte array synchronously
- Add `geode::utils::web::AsyncWebRequest` for creating thread-safe asynchronous web requests
- Add `Loader::updateModResourcePaths` for adding a mods' resources to search paths. Not recommended to be called manually
- Add an overload to `geode::createQuickPopup` for specifying popup width
- `ModInfo::createFromFile` now checks for `about.md` and other special files in the same directory
- Remove automatic mod updating for now, however automatic update checking for mods is still there
## v0.4.4
- New `listenForSettingChanges` API for more ergonomically listening for setting changes
- Fixed bug where GD was unopenable through Steam
- Various other internal fixes
## v0.4.3
- Simplified the minimum and maximum loader versions, loader will now load any mod whose target version major and minor match. In practice, this means that for example mods whose target version is v0.4.8 can be loaded by loader of version v0.4.6.

View file

@ -66,6 +66,10 @@ namespace geode::utils::web {
using AsyncThen = std::function<void(SentAsyncWebRequest&, byte_array const&)>;
using AsyncCancelled = std::function<void(SentAsyncWebRequest&)>;
/**
* A handle to an in-progress sent asynchronous web request. Use this to
* cancel the request / query information about it
*/
class SentAsyncWebRequest {
private:
std::string m_id;
@ -95,9 +99,20 @@ namespace geode::utils::web {
void doCancel();
public:
/**
* Do not call this manually.
*/
SentAsyncWebRequest(AsyncWebRequest const&, std::string const& id);
/**
* Cancel the request. Cleans up any downloaded files, but if you run
* extra code in `then`, you will have to clean it up manually in
* `cancelled`
*/
void cancel();
/**
* Check if the request is finished
*/
bool finished() const;
};
@ -106,6 +121,11 @@ namespace geode::utils::web {
template<class T>
using DataConverter = Result<T>(*)(byte_array const&);
/**
* An asynchronous, thread-safe web request. Downloads data from the
* internet without slowing the main thread. All callbacks are run in the
* GD thread, so interacting with the Cocos2d UI is perfectly safe
*/
class GEODE_DLL AsyncWebRequest {
private:
std::optional<std::string> m_joinID;
@ -127,14 +147,54 @@ namespace geode::utils::web {
friend class AsyncWebResponse;
public:
/**
* If you only want one instance of this web request to run (for example,
* you're downloading some global data for a manager), then use this
* to specify a Join ID. If another request with the same ID is
* already running, this request's callbacks will be appended to the
* existing one instead of creating a new request
* @param requestID The Join ID of the request. Can be anything,
* recommended to be something unique
* @returns Same AsyncWebRequest
*/
AsyncWebRequest& join(std::string const& requestID);
/**
* URL to fetch from the internet asynchronously
* @param url URL of the data to download. Redirects will be
* automatically followed
* @returns Same AsyncWebRequest
*/
AsyncWebResponse fetch(std::string const& url);
/**
* Specify a callback to run if the download fails. Runs in the GD
* thread, so interacting with UI is safe
* @param handler Callback to run if the download fails
* @returns Same AsyncWebRequest
*/
AsyncWebRequest& expect(AsyncExpect handler);
AsyncWebRequest& progress(AsyncProgress progressFunc);
// Web requests may be cancelled after they are finished (for example,
// if downloading files in bulk and one fails). In that case, handle
// freeing up the results of `then` here
AsyncWebRequest& cancelled(AsyncCancelled cancelledFunc);
/**
* Specify a callback to run when the download progresses. Runs in the
* GD thread, so interacting with UI is safe
* @param handler Callback to run when the download progresses
* @returns Same AsyncWebRequest
*/
AsyncWebRequest& progress(AsyncProgress handler);
/**
* Specify a callback to run if the download is cancelled. Runs in the
* GD thread, so interacting with UI is safe. Web requests may be
* cancelled after they are finished (for example, if downloading files
* in bulk and one fails). In that case, handle freeing up the results
* of `then` in this handler
* @param handler Callback to run if the download is cancelled
* @returns Same AsyncWebRequest
*/
AsyncWebRequest& cancelled(AsyncCancelled handler);
/**
* Begin the web request. It's not always necessary to call this as the
* destructor calls it automatically, but if you need access to the
* handle of the sent request, use this
* @returns Handle to the sent web request
*/
SentAsyncWebRequestHandle send();
~AsyncWebRequest();
};
@ -151,7 +211,21 @@ namespace geode::utils::web {
friend class AsyncWebResponse;
public:
/**
* Specify a callback to run after a download is finished. Runs in the
* GD thread, so interacting with UI is safe
* @param handle Callback to run
* @returns The original AsyncWebRequest, where you can specify more
* aspects about the request like failure and progress callbacks
*/
AsyncWebRequest& then(std::function<void(T)> handle);
/**
* Specify a callback to run after a download is finished. Runs in the
* GD thread, so interacting with UI is safe
* @param handle Callback to run
* @returns The original AsyncWebRequest, where you can specify more
* aspects about the request like failure and progress callbacks
*/
AsyncWebRequest& then(std::function<void(SentAsyncWebRequest&, T)> handle);
};
@ -164,13 +238,56 @@ namespace geode::utils::web {
friend class AsyncWebRequest;
public:
// Make sure the stream lives for the entire duration of the request.
/**
* Download into a stream. Make sure the stream lives for the entire
* duration of the request. If you want to download a file, use the
* `ghc::filesystem::path` overload of `into` instead
* @param stream Stream to download into. Make sure it lives long
* enough, otherwise the web request will crash
* @returns AsyncWebResult, where you can specify the `then` action for
* after the download is finished. The result has a `std::monostate`
* template parameter, as it can be assumed you know what you passed
* into `into`
*/
AsyncWebResult<std::monostate> into(std::ostream& stream);
/**
* Download into a file
* @param path File to download into. If it already exists, it will
* be overwritten.
* @returns AsyncWebResult, where you can specify the `then` action for
* after the download is finished. The result has a `std::monostate`
* template parameter, as it can be assumed you know what you passed
* into `into`
*/
AsyncWebResult<std::monostate> into(ghc::filesystem::path const& path);
/**
* Download into memory as a string
* @returns AsyncWebResult, where you can specify the `then` action for
* after the download is finished
*/
AsyncWebResult<std::string> text();
/**
* Download into memory as a byte array
* @returns AsyncWebResult, where you can specify the `then` action for
* after the download is finished
*/
AsyncWebResult<byte_array> bytes();
/**
* Download into memory as JSON
* @returns AsyncWebResult, where you can specify the `then` action for
* after the download is finished
*/
AsyncWebResult<nlohmann::json> json();
/**
* Download into memory as a custom type. The data will first be
* downloaded into memory as a byte array, and then converted using
* the specified converter function
* @param converter Function that converts the data from a byte array
* to the desired type
* @returns AsyncWebResult, where you can specify the `then` action for
* after the download is finished
*/
template<class T>
AsyncWebResult<T> as(DataConverter<T> converter) {
return AsyncWebResult(m_request, converter);

View file

@ -49,12 +49,8 @@ Result<Mod*> Loader::loadModFromFile(std::string const& path) {
m_mods.insert({ res.value().m_id, mod });
mod->updateDependencyStates();
log::debug("loaded mod, adding resources");
// add mod resources
this->queueInGDThread([this, mod]() {
log::debug("steve :pleading_face:");
this->updateModResourcePaths(mod);
this->updateModResources(mod);
});