diff --git a/.gitignore b/.gitignore index 4db610b..e01d693 100644 --- a/.gitignore +++ b/.gitignore @@ -1,56 +1,6 @@ -# Prerequisites -*.d - -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app - -# Macos be like -**/.DS_Store - -# Cache files for Sublime Text -*.tmlanguage.cache -*.tmPreferences.cache -*.stTheme.cache - -# Ignore build folders -**/build -**/build-* - -# Workspace files are user-specific -*.sublime-workspace - -# ILY vscode -**/.vscode -.idea/ - -# clangd -.cache/ +.vscode/ +build/ +build-*/ pro/ +resources/images/support-popup.png diff --git a/CMakeLists.txt b/CMakeLists.txt index 315c2e1..c4a765c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,15 @@ else() message(STATUS "Including only free features, no Pro") endif() +if (NOT SKIP_INCLUDING_LARGE_RESOURCES_FOR_SHORTER_BUILD_TIMES) + file(COPY_FILE + resources/support-popup/support-popup.png + resources/images/support-popup.png + ) +else() + file(REMOVE resources/images/support-popup.png) +endif() + file(GLOB SOURCES src/features/*.cpp src/features/scaling/*.cpp diff --git a/changelog.md b/changelog.md index 887c817..933d4fa 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,8 @@ # BetterEdit 6 +## v6.9.0-alpha.1 + * Support for GD 2.2704 and Geode 4.0.0-beta.1 + ## v6.8.0 * Add Modifying Mixed Values in the Group ID Popup (Editor Layers, Z Order, Channel) * Add inputs for Scale, Scale X, and Scale Y diff --git a/mod.json b/mod.json index 6fb80fa..809a331 100644 --- a/mod.json +++ b/mod.json @@ -1,10 +1,10 @@ { - "geode": "3.8.1", - "version": "6.8.0", + "geode": "4.0.0-beta.1", + "version": "6.9.0-alpha.1", "gd": { - "win": "2.206", - "mac": "2.206", - "android": "2.206" + "win": "2.2074", + "mac": "2.2074", + "android": "2.2074" }, "id": "hjfod.betteredit", "name": "BetterEdit", diff --git a/resources/images/support-popup.png b/resources/support-popup/support-popup.png similarity index 100% rename from resources/images/support-popup.png rename to resources/support-popup/support-popup.png diff --git a/src/features/ForceHideTriggerUI.cpp b/src/features/ForceHideTriggerUI.cpp index 109c942..687ff84 100644 --- a/src/features/ForceHideTriggerUI.cpp +++ b/src/features/ForceHideTriggerUI.cpp @@ -9,15 +9,15 @@ class $modify(SetupTriggerPopup) { if (!Mod::get()->getSettingValue("hide-trigger-ui")) { return; } - getChildOfType(m_mainLayer, 0)->runAction(CCFadeTo::create(0.15f, 0)); - this->runAction(CCFadeTo::create(0.15f, 0)); + m_mainLayer->getChildByType(0)->runAction(CCFadeTo::create(.15f, 0)); + this->runAction(CCFadeTo::create(.15f, 0)); } virtual void sliderEnded(Slider* slider) { SetupTriggerPopup::sliderEnded(slider); if (!Mod::get()->getSettingValue("hide-trigger-ui")) { return; } - getChildOfType(m_mainLayer, 0)->runAction(CCFadeTo::create(0.15f, 255)); - this->runAction(CCFadeTo::create(0.15f, 150)); + m_mainLayer->getChildByType(0)->runAction(CCFadeTo::create(.15f, 255)); + this->runAction(CCFadeTo::create(.15f, 150)); } }; diff --git a/src/features/Keybinds.cpp b/src/features/Keybinds.cpp index edbbac4..f943b10 100644 --- a/src/features/Keybinds.cpp +++ b/src/features/Keybinds.cpp @@ -61,7 +61,7 @@ struct $modify(EditorUI) { this->editGroup(nullptr); }); this->defineKeybind("open-edit-special"_spr, [this]() { - this->editObject2(nullptr); + this->editObjectSpecial(0); }); this->defineKeybind("copy-values"_spr, [this]() { this->onCopyState(nullptr); diff --git a/src/features/ViewTab/ViewTab.cpp b/src/features/ViewTab/ViewTab.cpp index 8324af1..10f0476 100644 --- a/src/features/ViewTab/ViewTab.cpp +++ b/src/features/ViewTab/ViewTab.cpp @@ -20,7 +20,7 @@ using namespace keybinds; template class CCFunction : public CCObject { protected: - MiniFunction m_func; + std::function m_func; public: template @@ -108,7 +108,7 @@ struct $modify(ViewTabUI, EditorUI) { toggler->setUserObject("setter", CCFunction::create(set)); return toggler; } - CCMenuItemToggler* createViewToggleGV(const char* frame, const char* gv, MiniFunction postSet = nullptr) { + CCMenuItemToggler* createViewToggleGV(const char* frame, const char* gv, std::function postSet = nullptr) { auto off = createViewToggleSpr(frame, false); auto on = createViewToggleSpr(frame, true); auto toggler = CCMenuItemToggler::create(off, on, this, menu_selector(ViewTabUI::onViewToggle)); @@ -121,7 +121,7 @@ struct $modify(ViewTabUI, EditorUI) { })); return toggler; } - CCMenuItemToggler* createViewToggleMSV(const char* frame, const char* modSavedValue, MiniFunction postSet = nullptr) { + CCMenuItemToggler* createViewToggleMSV(const char* frame, const char* modSavedValue, std::function postSet = nullptr) { auto off = createViewToggleSpr(frame, false); auto on = createViewToggleSpr(frame, true); auto toggler = CCMenuItemToggler::create(off, on, this, menu_selector(ViewTabUI::onViewToggle)); @@ -163,7 +163,7 @@ struct $modify(ViewTabUI, EditorUI) { auto winSize = CCDirector::get()->getWinSize(); // Make a bit space for new style menu since the old one is a tiny bit cramped - if (auto left = getChildOfType(this, 1), right = getChildOfType(this, 2); left && right) { + if (auto left = this->getChildByType(1), right = this->getChildByType(2); left && right) { left->setPositionX(winSize.width - right->getPositionX()); } for (auto& child : CCArrayExt(m_pChildren)) { diff --git a/src/features/backups/Backup.cpp b/src/features/backups/Backup.cpp index 55d0be0..6765887 100644 --- a/src/features/backups/Backup.cpp +++ b/src/features/backups/Backup.cpp @@ -19,27 +19,22 @@ struct BackupMetadata final { template <> struct matjson::Serialize { - static matjson::Value to_json(BackupMetadata const& meta) { - return matjson::Object({ + static matjson::Value toJson(BackupMetadata const& meta) { + return matjson::makeObject({ { "create-time", std::chrono::duration_cast(meta.createTime.time_since_epoch()).count() }, { "automated", meta.automated }, }); } - static BackupMetadata from_json(matjson::Value const& value) { + static Result fromJson(matjson::Value const& value) { auto meta = BackupMetadata(); - auto obj = value.as_object(); + auto obj = checkJson(value, "BackupMetadata"); - meta.createTime = Backup::TimePoint(Backup::TimeUnit(obj["create-time"].as_int())); + int createTime; + obj.needs("create-time").into(createTime); + meta.createTime = Backup::TimePoint(Backup::TimeUnit(createTime)); + obj.has("automated").into(meta.automated); - // Parsing should be as fault-tolerant as possible - if (obj.contains("automated")) { - meta.automated = obj["automated"].as_bool(); - } - - return meta; - } - static bool is_json(matjson::Value const& value) { - return value.is_object(); + return Ok(meta); } }; @@ -85,12 +80,16 @@ Result<> Backup::preserveAutomated() { .createTime = m_createTime, .automated = false, }; - GEODE_UNWRAP(file::writeToJson(m_directory / "meta.json", metadata).expect("Unable to save metadata: {error}")); + GEODE_UNWRAP(file::writeToJson(m_directory / "meta.json", metadata).mapErr([](auto error) { + return fmt::format("Unable to save metadata: {}", error); + })); return Ok(); } Result> Backup::load(std::filesystem::path const& dir, GJGameLevel* forLevel) { - GEODE_UNWRAP_INTO(auto level, gmd::importGmdAsLevel(dir / "level.gmd").expect("Unable to read level file: {error}")); + GEODE_UNWRAP_INTO(auto level, gmd::importGmdAsLevel(dir / "level.gmd").mapErr([](auto error) { + return fmt::format("Unable to read level file: {}", error); + })); auto meta = file::readFromJson(dir / "meta.json").unwrapOrDefault(); auto backup = std::make_shared(); @@ -133,15 +132,21 @@ Result<> Backup::create(GJGameLevel* level, bool automated) { return Err("Level was already backed up less than a minute ago"); } - GEODE_UNWRAP(file::createDirectoryAll(dir).expect("Failed to create directory: {error}")); + GEODE_UNWRAP(file::createDirectoryAll(dir).mapErr([](auto error) { + return fmt::format("Failed to create directory: {}", error); + })); - GEODE_UNWRAP(gmd::exportLevelAsGmd(level, dir / "level.gmd").expect("Unable to save level: {error}")); + GEODE_UNWRAP(gmd::exportLevelAsGmd(level, dir / "level.gmd").mapErr([](auto error) { + return fmt::format("Unable to save level: {}", error); + })); auto metadata = BackupMetadata { .createTime = time, .automated = automated, }; - GEODE_UNWRAP(file::writeToJson(dir / "meta.json", metadata).expect("Unable to save metadata: {error}")); + GEODE_UNWRAP(file::writeToJson(dir / "meta.json", metadata).mapErr([](auto error) { + return fmt::format("Unable to save metadata: {}", error); + })); return Ok(); } diff --git a/src/features/backups/Backup.hpp b/src/features/backups/Backup.hpp index 8b15a9e..09a9707 100644 --- a/src/features/backups/Backup.hpp +++ b/src/features/backups/Backup.hpp @@ -2,7 +2,6 @@ #include #include -#include using namespace geode::prelude; diff --git a/src/features/scaling/EditorUIScaling.cpp b/src/features/scaling/EditorUIScaling.cpp index 41b6cb5..e23bdb9 100644 --- a/src/features/scaling/EditorUIScaling.cpp +++ b/src/features/scaling/EditorUIScaling.cpp @@ -52,7 +52,7 @@ class $modify(BetterEditButtonBar, EditButtonBar) { setPositionX(winSize.width / 2); m_scrollLayer->setPositionX(-(winSize.width / 2)); - if (auto menu = getChildOfType(this, 0)) { + if (auto menu = this->getChildByType(0)) { menu->setVisible(false); // easier to create a new menu than work with the old one @@ -88,7 +88,7 @@ class $modify(BetterEditButtonBar, EditButtonBar) { // layout the pages and set their widths and heights according to the row and column counts, scale accordingly for (ButtonPage* page : CCArrayExt(m_scrollLayer->m_pages)) { - if (CCMenu* buttonMenu = getChildOfType(page, 0)) { + if (CCMenu* buttonMenu = page->getChildByType(0)) { RowLayout* layout = RowLayout::create(); layout->setAxisAlignment(AxisAlignment::Start); layout->setCrossAxisAlignment(AxisAlignment::End); @@ -132,7 +132,7 @@ class $modify(ScaledUI, EditorUI) { float scale = Mod::get()->getSettingValue("scale-factor"); auto size = CCDirector::get()->getWinSize(); - if (auto slider = getChildOfType(this, 0)) { + if (auto slider = this->getChildByType(0)) { slider->ignoreAnchorPointForPosition(false); slider->setContentSize(ccp(0, 0)); slider->setScale(scale); @@ -189,9 +189,9 @@ class $modify(ScaledUI, EditorUI) { } // i am very sorry for using object indexes but no id - // doggo for the love of god at least use getChildOfType + // doggo for the love of god at least use getChildByType - if (auto objBG = getChildOfType(this, 0)) { + if (auto objBG = this->getChildByType(0)) { objBG->setScaleY(scale); } @@ -220,12 +220,12 @@ class $modify(ScaledUI, EditorUI) { rightTabs->setScale(scale); } - if (auto leftLine = getChildOfType(this, 1)) { + if (auto leftLine = this->getChildByType(1)) { leftLine->setScale(scale); leftLine->setPosition(leftLine->getPosition() * scale); } - if (auto rightLine = getChildOfType(this, 2)) { + if (auto rightLine = this->getChildByType(2)) { rightLine->setScale(scale); rightLine->setPosition(ccp(size.width - (size.width - rightLine->getPositionX()) * scale, rightLine->getPositionY() * scale)); } diff --git a/src/utils/Editor.cpp b/src/utils/Editor.cpp index a7d0402..bbae925 100644 --- a/src/utils/Editor.cpp +++ b/src/utils/Editor.cpp @@ -63,10 +63,10 @@ class $modify(GameManager) { //// View-only editor stuff class ViewOnlyModeData : public CCObject { protected: - utils::MiniFunction m_returnTo; + std::function m_returnTo; public: - static ViewOnlyModeData* create(utils::MiniFunction returnTo) { + static ViewOnlyModeData* create(std::function returnTo) { auto ret = new ViewOnlyModeData(); ret->m_returnTo = returnTo; ret->autorelease(); @@ -78,7 +78,7 @@ class ViewOnlyModeData : public CCObject { } }; -LevelEditorLayer* be::createViewOnlyEditor(GJGameLevel* level, utils::MiniFunction returnTo) { +LevelEditorLayer* be::createViewOnlyEditor(GJGameLevel* level, std::function returnTo) { auto editor = LevelEditorLayer::create(level, false); editor->setUserObject("view-only-mode"_spr, ViewOnlyModeData::create(returnTo)); @@ -227,7 +227,7 @@ class $modify(HideUI, EditorUI) { UIShowEvent::UIShowEvent(EditorUI* ui, bool show) : ui(ui), show(show) {} UIShowFilter::UIShowFilter(EditorUI* ui) : m_ui(ui) {} -ListenerResult UIShowFilter::handle(MiniFunction fn, UIShowEvent* ev) { +ListenerResult UIShowFilter::handle(std::function fn, UIShowEvent* ev) { if (m_ui == ev->ui) { fn(ev); } diff --git a/src/utils/Editor.hpp b/src/utils/Editor.hpp index 4c9e9fd..86f2d16 100644 --- a/src/utils/Editor.hpp +++ b/src/utils/Editor.hpp @@ -21,7 +21,7 @@ namespace be { * Create a view-only editor, i.e. one where no objects can be placed nor * edited */ - LevelEditorLayer* createViewOnlyEditor(GJGameLevel* level, utils::MiniFunction returnTo); + LevelEditorLayer* createViewOnlyEditor(GJGameLevel* level, std::function returnTo); /** * Check if the given editor is view-only */ @@ -66,6 +66,6 @@ class UIShowFilter : public EventFilter { UIShowFilter() = default; UIShowFilter(EditorUI* ui); - ListenerResult handle(MiniFunction fn, UIShowEvent* ev); + ListenerResult handle(std::function fn, UIShowEvent* ev); }; using OnUIHide = EventListener; diff --git a/src/utils/Warn.hpp b/src/utils/Warn.hpp index b9b7e91..5164720 100644 --- a/src/utils/Warn.hpp +++ b/src/utils/Warn.hpp @@ -30,4 +30,4 @@ #define BE_ALLOW_UNUSED_FUNCTION #endif -#define $be_ensure_hookable(...) static_assert(requires { __VA_ARGS__; }) +#define $be_ensure_hookable(...) if (0) { return __VA_ARGS__; }