mirror of
https://github.com/geode-sdk/geode.git
synced 2025-02-17 00:30:26 -05:00
Merge branch 'main' of https://github.com/geode-sdk/geode into main
This commit is contained in:
commit
a45032ae2c
8 changed files with 144 additions and 17 deletions
|
@ -116,6 +116,10 @@ file(GLOB CODEGEN_DEPENDS CONFIGURE_DEPENDS
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/codegen/src/*.hpp
|
||||
)
|
||||
|
||||
file(GLOB CODEGEN_OUTPUTS CONFIGURE_DEPENDS
|
||||
${GEODE_CODEGEN_PATH}/Geode/binding/*.hpp
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
DEPENDS ${CODEGEN_DEPENDS}
|
||||
DEPENDS CodegenProject
|
||||
|
@ -123,7 +127,7 @@ add_custom_command(
|
|||
COMMAND echo codegen > ${GEODE_CODEGEN_PATH}/.stamp
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT "Run Codegen"
|
||||
OUTPUT ${GEODE_CODEGEN_PATH}/Geode/GeneratedSource.cpp ${GEODE_CODEGEN_PATH}/Geode/GeneratedAddress.cpp ${GEODE_CODEGEN_PATH}/.stamp
|
||||
OUTPUT ${GEODE_CODEGEN_PATH}/Geode/GeneratedSource.cpp ${GEODE_CODEGEN_PATH}/Geode/GeneratedAddress.cpp ${GEODE_CODEGEN_PATH}/.stamp ${CODEGEN_OUTPUTS}
|
||||
)
|
||||
|
||||
add_custom_target(CodegenRun
|
||||
|
|
|
@ -803,14 +803,14 @@ class ColorSelectPopup : FLAlertLayer, cocos2d::extension::ColorPickerDelegate,
|
|||
int m_copyChannelID;
|
||||
bool m_copyOpacity;
|
||||
ConfigureHSVWidget* m_hsvWidget;
|
||||
PAD = win 0x10;
|
||||
PAD = win 0x10, mac 0x10;
|
||||
cocos2d::CCArray* m_unk254;
|
||||
cocos2d::CCArray* m_unk258;
|
||||
CCTextInputNode* m_textInput2;
|
||||
PAD = win 0x4;
|
||||
PAD = win 0x4, mac 0x8;
|
||||
CCMenuItemToggler* m_toggler3;
|
||||
CCMenuItemToggler* m_toggler4;
|
||||
PAD = win 0x8;
|
||||
PAD = win 0x8, mac 0x10;
|
||||
cocos2d::CCArray* m_unk274;
|
||||
bool m_spawnTrigger;
|
||||
bool m_multiTrigger;
|
||||
|
@ -5148,11 +5148,11 @@ class SetupPulsePopup : FLAlertLayer, cocos2d::extension::ColorPickerDelegate, T
|
|||
|
||||
|
||||
cocos2d::extension::CCControlColourPicker* m_colorPicker;
|
||||
PAD = win 0x30;
|
||||
PAD = win 0x30, mac 0x60;
|
||||
cocos2d::CCSprite* m_currentColorSpr;
|
||||
cocos2d::CCSprite* m_prevColorSpr;
|
||||
PAD = win 0x64;
|
||||
int m_pulseMode;
|
||||
PAD = win 0x64, mac 0xac;
|
||||
int m_pulseMode; // 0x38c on mac
|
||||
}
|
||||
|
||||
class SetupShakePopup : FLAlertLayer {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Result.hpp"
|
||||
#include "general.hpp"
|
||||
#include "../loader/Event.hpp"
|
||||
|
||||
#include <json.hpp>
|
||||
#include <Geode/DefaultInclude.hpp>
|
||||
|
@ -41,7 +42,7 @@ namespace geode::utils::file {
|
|||
template <class T>
|
||||
Result<> writeToJson(ghc::filesystem::path const& path, T const& data) {
|
||||
try {
|
||||
GEODE_UNWRAP(writeString(json::Value(data).dump()));
|
||||
GEODE_UNWRAP(writeString(path, json::Value(data).dump()));
|
||||
return Ok();
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
|
@ -252,4 +253,40 @@ namespace geode::utils::file {
|
|||
* @param options Picker options
|
||||
*/
|
||||
GEODE_DLL Result<std::vector<ghc::filesystem::path>> pickFiles(FilePickOptions const& options);
|
||||
|
||||
class GEODE_DLL FileWatchEvent : public Event {
|
||||
protected:
|
||||
ghc::filesystem::path m_path;
|
||||
|
||||
public:
|
||||
FileWatchEvent(ghc::filesystem::path const& path);
|
||||
ghc::filesystem::path getPath() const;
|
||||
};
|
||||
|
||||
class GEODE_DLL FileWatchFilter : public EventFilter<FileWatchEvent> {
|
||||
protected:
|
||||
ghc::filesystem::path m_path;
|
||||
|
||||
public:
|
||||
using Callback = void(FileWatchEvent*);
|
||||
|
||||
ListenerResult handle(utils::MiniFunction<Callback> callback, FileWatchEvent* event);
|
||||
FileWatchFilter(ghc::filesystem::path const& path);
|
||||
};
|
||||
|
||||
/**
|
||||
* Watch a file for changes. Whenever the file is modified on disk, a
|
||||
* FileWatchEvent is emitted. Add an EventListener with FileWatchFilter
|
||||
* to catch these events
|
||||
* @param file The file to watch
|
||||
* @note Watching uses file system equivalence instead of path equivalence,
|
||||
* so different paths that point to the same file will be considered the
|
||||
* same
|
||||
*/
|
||||
GEODE_DLL Result<> watchFile(ghc::filesystem::path const& file);
|
||||
/**
|
||||
* Stop watching a file for changes
|
||||
* @param file The file to unwatch
|
||||
*/
|
||||
GEODE_DLL void unwatchFile(ghc::filesystem::path const& file);
|
||||
}
|
||||
|
|
|
@ -25,12 +25,28 @@ protected:
|
|||
public:
|
||||
bool watching() const;
|
||||
|
||||
ghc::filesystem::path path() {
|
||||
ghc::filesystem::path path() const {
|
||||
return m_file;
|
||||
}
|
||||
|
||||
FileWatcher(
|
||||
ghc::filesystem::path const& file, FileWatchCallback callback, ErrorCallback error = nullptr
|
||||
ghc::filesystem::path const& file,
|
||||
FileWatchCallback callback,
|
||||
ErrorCallback error = nullptr
|
||||
);
|
||||
FileWatcher(FileWatcher const&) = delete;
|
||||
inline FileWatcher(FileWatcher&& other)
|
||||
: m_file(std::move(other.m_file)),
|
||||
m_callback(std::move(other.m_callback)),
|
||||
m_error(std::move(other.m_error)),
|
||||
m_filemode(other.m_filemode),
|
||||
m_platformHandle(other.m_platformHandle),
|
||||
m_exiting(other.m_exiting)
|
||||
{
|
||||
other.m_callback = nullptr;
|
||||
other.m_error = nullptr;
|
||||
other.m_platformHandle = nullptr;
|
||||
other.m_exiting = true;
|
||||
}
|
||||
~FileWatcher();
|
||||
};
|
||||
|
|
|
@ -77,7 +77,7 @@ void utils::web::openLinkInBrowser(std::string const& url) {
|
|||
NSOpenPanel* panel = [NSOpenPanel openPanel];
|
||||
|
||||
// allowed files
|
||||
NSMutableArray* allowed;
|
||||
NSMutableArray* allowed = [NSMutableArray array];
|
||||
|
||||
for (auto& f : options.filters) {
|
||||
for (auto& i : f.files) {
|
||||
|
|
|
@ -38,6 +38,12 @@ static std::optional<int> fuzzyMatch(std::string const& kw, std::string const& s
|
|||
someMatched = true; \
|
||||
}
|
||||
|
||||
#define WEIGHTED_MATCH_MAX(str_, weight_) \
|
||||
if (auto match = fuzzyMatch(query.keywords.value(), str_)) { \
|
||||
weighted = std::max<double>(match.value() * weight_, weighted); \
|
||||
someMatched = true; \
|
||||
}
|
||||
|
||||
#define WEIGHTED_MATCH_ADD(str_, weight_) \
|
||||
if (auto match = fuzzyMatch(query.keywords.value(), str_)) {\
|
||||
weighted += match.value() * weight_; \
|
||||
|
@ -52,11 +58,11 @@ static std::optional<int> queryMatchKeywords(
|
|||
// fuzzy match keywords
|
||||
if (query.keywords) {
|
||||
bool someMatched = false;
|
||||
WEIGHTED_MATCH(info.name(), 2);
|
||||
WEIGHTED_MATCH(info.id(), 1.5);
|
||||
WEIGHTED_MATCH(info.developer(), 1);
|
||||
WEIGHTED_MATCH(info.details().value_or(""), 2);
|
||||
WEIGHTED_MATCH(info.description().value_or(""), 1);
|
||||
WEIGHTED_MATCH_MAX(info.name(), 2);
|
||||
WEIGHTED_MATCH_MAX(info.id(), 1);
|
||||
WEIGHTED_MATCH_MAX(info.developer(), 0.5);
|
||||
WEIGHTED_MATCH_MAX(info.details().value_or(""), 0.05);
|
||||
WEIGHTED_MATCH_MAX(info.description().value_or(""), 0.2);
|
||||
if (!someMatched) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
@ -67,7 +73,12 @@ static std::optional<int> queryMatchKeywords(
|
|||
// sorted, at least enough so that if you're scrolling it based on
|
||||
// alphabetical order you will find the part you're looking for easily
|
||||
// so it's fine
|
||||
weighted = -tolower(info.name()[0]);
|
||||
return static_cast<int>(-tolower(info.name()[0]));
|
||||
}
|
||||
|
||||
// if the weight is relatively small we can ignore it
|
||||
if (weighted < 2) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// empty keywords always match
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <mz_strm_os.h>
|
||||
#include <mz_strm_mem.h>
|
||||
#include <mz_zip.h>
|
||||
#include <internal/FileWatcher.hpp>
|
||||
|
||||
using namespace geode::prelude;
|
||||
using namespace geode::utils::file;
|
||||
|
@ -551,3 +552,54 @@ Result<> Zip::addAllFrom(Path const& dir) {
|
|||
Result<> Zip::addFolder(Path const& entry) {
|
||||
return m_impl->addFolder(entry);
|
||||
}
|
||||
|
||||
FileWatchEvent::FileWatchEvent(ghc::filesystem::path const& path)
|
||||
: m_path(path) {}
|
||||
|
||||
ghc::filesystem::path FileWatchEvent::getPath() const {
|
||||
return m_path;
|
||||
}
|
||||
|
||||
ListenerResult FileWatchFilter::handle(
|
||||
MiniFunction<Callback> callback,
|
||||
FileWatchEvent* event
|
||||
) {
|
||||
std::error_code ec;
|
||||
if (ghc::filesystem::equivalent(event->getPath(), m_path, ec)) {
|
||||
callback(event);
|
||||
}
|
||||
return ListenerResult::Propagate;
|
||||
}
|
||||
|
||||
FileWatchFilter::FileWatchFilter(ghc::filesystem::path const& path)
|
||||
: m_path(path) {}
|
||||
|
||||
// This is a vector because need to use ghc::filesystem::equivalent for
|
||||
// comparisons and removal is not exactly performance-critical here
|
||||
// (who's going to add and remove 500 file watchers every frame)
|
||||
static std::vector<std::unique_ptr<FileWatcher>> FILE_WATCHERS {};
|
||||
|
||||
Result<> file::watchFile(ghc::filesystem::path const& file) {
|
||||
if (!ghc::filesystem::exists(file)) {
|
||||
return Err("File does not exist");
|
||||
}
|
||||
auto watcher = std::make_unique<FileWatcher>(
|
||||
file,
|
||||
[](auto const& path) {
|
||||
Loader::get()->queueInGDThread([=] {
|
||||
FileWatchEvent(path).post();
|
||||
});
|
||||
}
|
||||
);
|
||||
if (!watcher->watching()) {
|
||||
return Err("Unknown error watching file");
|
||||
}
|
||||
FILE_WATCHERS.emplace_back(std::move(watcher));
|
||||
return Ok();
|
||||
}
|
||||
|
||||
void file::unwatchFile(ghc::filesystem::path const& file) {
|
||||
ranges::remove(FILE_WATCHERS, [=](std::unique_ptr<FileWatcher> const& watcher) {
|
||||
return ghc::filesystem::equivalent(file, watcher->path());
|
||||
});
|
||||
}
|
||||
|
|
|
@ -57,4 +57,11 @@ GEODE_MEMBER_CHECK(TeleportPortalObject, m_orangePortal, 0x4f8);
|
|||
// StartPosObject
|
||||
GEODE_MEMBER_CHECK(StartPosObject, m_levelSettings, 0x5e0);
|
||||
|
||||
// SetupPulsePopup
|
||||
GEODE_MEMBER_CHECK(SetupPulsePopup, m_currentColorSpr, 0x2d0);
|
||||
GEODE_MEMBER_CHECK(SetupPulsePopup, m_pulseMode, 0x38c);
|
||||
|
||||
// ColorSelectPopup
|
||||
GEODE_MEMBER_CHECK(ColorSelectPopup, m_copyColor, 0x372);
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue