From 4c4674da93b5244a034edd2e6aa0bc15c80748b5 Mon Sep 17 00:00:00 2001 From: HJfod <60038575+HJfod@users.noreply.github.com> Date: Mon, 12 Dec 2022 15:45:27 +0200 Subject: [PATCH] add suffixes to versions --- .gitmodules | 3 + CHANGELOG.md | 3 + CMakeLists.txt | 1 + loader/CMakeLists.txt | 5 +- loader/include/Geode/external/scnlib | 1 + loader/include/Geode/utils/VersionInfo.hpp | 48 +++++++++--- loader/resources/mod.json.in | 2 +- loader/src/internal/about.hpp.in | 6 +- loader/src/loader/Loader.cpp | 2 +- loader/src/ui/internal/list/ModListCell.cpp | 19 ++++- loader/src/utils/VersionInfo.cpp | 81 ++++++++++++++++++--- 11 files changed, 142 insertions(+), 29 deletions(-) create mode 160000 loader/include/Geode/external/scnlib diff --git a/.gitmodules b/.gitmodules index 062479c6..2029bf88 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "loader/minhook"] path = loader/minhook url = https://github.com/TsudaKageyu/minhook +[submodule "loader/include/Geode/external/scnlib"] + path = loader/include/Geode/external/scnlib + url = https://github.com/eliaskosunen/scnlib diff --git a/CHANGELOG.md b/CHANGELOG.md index e5cbe57c..345165d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Geode Changelog +## v0.7.0 + - Jesus H. Christmas Kallen there's like 300 new commits since v0.6.1 I don't think there's a point in listing them all, we basically redesigned the whole framework + ## v0.6.1 - Add `geode::cocos::switchToScene` utility for easily switching to a layer with the default fade transition - Add `Mod::getPackagePath` as a replacement for `Mod::getPath` diff --git a/CMakeLists.txt b/CMakeLists.txt index 4491b65c..ebb53660 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,6 +83,7 @@ add_definitions(-DFMT_CONSTEVAL=) add_subdirectory(loader/include/Geode/external/filesystem) add_subdirectory(loader/include/Geode/external/fmt) +add_subdirectory(loader/include/Geode/external/scnlib) target_link_libraries(${PROJECT_NAME} INTERFACE filesystem fmt) diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt index b715a2cd..74f58d10 100644 --- a/loader/CMakeLists.txt +++ b/loader/CMakeLists.txt @@ -1,7 +1,8 @@ cmake_minimum_required(VERSION 3.21 FATAL_ERROR) project(geode-loader VERSION ${GEODE_VERSION} LANGUAGES C CXX) -set(PROJECT_VERSION_TYPE Alpha) +set(PROJECT_VERSION_TYPE geode::VersionTag::Alpha) +set(PROJECT_VERSION_SUFFIX -alpha) # Package info file for internal representation configure_file(resources/mod.json.in ${CMAKE_CURRENT_SOURCE_DIR}/resources/mod.json) @@ -127,7 +128,7 @@ target_link_libraries(${PROJECT_NAME} md4c) # Lilac (hooking) add_subdirectory(lilac) -target_link_libraries(${PROJECT_NAME} z lilac_hook geode-sdk) +target_link_libraries(${PROJECT_NAME} z lilac_hook geode-sdk scn::scn) # Use precompiled headers for faster builds target_precompile_headers(${PROJECT_NAME} PRIVATE diff --git a/loader/include/Geode/external/scnlib b/loader/include/Geode/external/scnlib new file mode 160000 index 00000000..72a4bab9 --- /dev/null +++ b/loader/include/Geode/external/scnlib @@ -0,0 +1 @@ +Subproject commit 72a4bab9e32f2b44593137fba40c54710e20a623 diff --git a/loader/include/Geode/utils/VersionInfo.hpp b/loader/include/Geode/utils/VersionInfo.hpp index 356774d9..8f6c5468 100644 --- a/loader/include/Geode/utils/VersionInfo.hpp +++ b/loader/include/Geode/utils/VersionInfo.hpp @@ -13,37 +13,67 @@ namespace geode { }; /** - * Class representing version information + * A version label, like v1.0.0-alpha or v2.3.4-prerelease. Purely semantic, + * and not used in comparisons; so for example v1.0.0-alpha == v1.0.0. + */ + enum class VersionTag { + Alpha, + Beta, + Prerelease, + }; + GEODE_DLL std::optional versionTagFromString(std::string const& str); + GEODE_DLL std::string versionTagToSuffixString(VersionTag tag); + GEODE_DLL std::string versionTagToString(VersionTag tag); + + /** + * Class representing version information. Not strictly semver, notably in + * regard to identifiers; identifiers are restricted to a few common ones, + * and are purely semantic, i.e. not used in comparisons. See VersionTag + * for details * @class VersionInfo */ class GEODE_DLL VersionInfo final { protected: - int m_major = 1; - int m_minor = 0; - int m_patch = 0; + size_t m_major = 1; + size_t m_minor = 0; + size_t m_patch = 0; + std::optional m_tag; public: constexpr VersionInfo() = default; - constexpr VersionInfo(int major, int minor, int patch) { + constexpr VersionInfo(size_t major, size_t minor, size_t patch) { m_major = major; m_minor = minor; m_patch = patch; } + constexpr VersionInfo( + size_t major, size_t minor, size_t patch, + std::optional tag + ) { + m_major = major; + m_minor = minor; + m_patch = patch; + m_tag = tag; + } VersionInfo(std::string const& versionString); static bool validate(std::string const& string); - constexpr int getMajor() const { + constexpr size_t getMajor() const { return m_major; } - constexpr int getMinor() const { + constexpr size_t getMinor() const { return m_minor; } - constexpr int getPatch() const { + constexpr size_t getPatch() const { return m_patch; } + constexpr std::optional getTag() const { + return m_tag; + } + // Apple clang does not support operator<=>! Yippee! constexpr bool operator==(VersionInfo const& other) const { @@ -67,7 +97,7 @@ namespace geode { std::tie(other.m_major, other.m_minor, other.m_patch); } - std::string toString() const; + std::string toString(bool includeTag = true) const; }; void GEODE_DLL to_json(nlohmann::json& json, VersionInfo const& info); void GEODE_DLL from_json(nlohmann::json const& json, VersionInfo& info); diff --git a/loader/resources/mod.json.in b/loader/resources/mod.json.in index a0f5d1f6..b4baa56d 100644 --- a/loader/resources/mod.json.in +++ b/loader/resources/mod.json.in @@ -1,7 +1,7 @@ { "geode": "@PROJECT_VERSION@", "id": "geode.loader", - "version": "@PROJECT_VERSION@", + "version": "@PROJECT_VERSION@@PROJECT_VERSION_SUFFIX@", "name": "Geode", "developer": "Geode Team", "description": "The Geode mod loader", diff --git a/loader/src/internal/about.hpp.in b/loader/src/internal/about.hpp.in index 3437f8db..a0cdc50e 100644 --- a/loader/src/internal/about.hpp.in +++ b/loader/src/internal/about.hpp.in @@ -3,14 +3,14 @@ #include static constexpr const char* LOADER_ABOUT_MD = R"MD_SEPARATOR(@LOADER_ABOUT_MD@)MD_SEPARATOR"; -static constexpr const char* LOADER_VERSION_STR = "@PROJECT_VERSION@"; +static constexpr const char* LOADER_VERSION_STR = "@PROJECT_VERSION@@PROJECT_VERSION_SUFFIX@"; static constexpr int LOADER_VERSION_MAJOR = @PROJECT_VERSION_MAJOR@; static constexpr int LOADER_VERSION_MINOR = @PROJECT_VERSION_MINOR@; static constexpr int LOADER_VERSION_PATCH = @PROJECT_VERSION_PATCH@; static constexpr geode::VersionInfo LOADER_VERSION = { @PROJECT_VERSION_MAJOR@, @PROJECT_VERSION_MINOR@, - @PROJECT_VERSION_PATCH@ + @PROJECT_VERSION_PATCH@, + @PROJECT_VERSION_TYPE@, }; -static constexpr const char* LOADER_VERSION_TYPE = "@PROJECT_VERSION_TYPE@"; static constexpr const char* LOADER_MOD_JSON = R"JSON_SEPARATOR(@LOADER_MOD_JSON@)JSON_SEPARATOR"; diff --git a/loader/src/loader/Loader.cpp b/loader/src/loader/Loader.cpp index 5d3e783c..846c756e 100644 --- a/loader/src/loader/Loader.cpp +++ b/loader/src/loader/Loader.cpp @@ -123,4 +123,4 @@ void Loader::closePlatformConsole() { bool Loader::didLastLaunchCrash() const { return m_impl->didLastLaunchCrash(); -} \ No newline at end of file +} diff --git a/loader/src/ui/internal/list/ModListCell.cpp b/loader/src/ui/internal/list/ModListCell.cpp index 85814836..606f484d 100644 --- a/loader/src/ui/internal/list/ModListCell.cpp +++ b/loader/src/ui/internal/list/ModListCell.cpp @@ -60,7 +60,10 @@ void ModListCell::setupInfo(ModInfo const& info, bool spaceForTags) { titleLabel->limitLabelWidth(m_width / 2 - 40.f, .5f, .1f); this->addChild(titleLabel); - auto versionLabel = CCLabelBMFont::create(info.version.toString().c_str(), "bigFont.fnt"); + auto versionLabel = CCLabelBMFont::create( + info.version.toString(false).c_str(), + "bigFont.fnt" + ); versionLabel->setAnchorPoint({ .0f, .5f }); versionLabel->setScale(.3f); versionLabel->setPosition( @@ -70,6 +73,20 @@ void ModListCell::setupInfo(ModInfo const& info, bool spaceForTags) { versionLabel->setColor({ 0, 255, 0 }); this->addChild(versionLabel); + if (auto tag = info.version.getTag()) { + auto tagLabel = TagNode::create( + versionTagToString(tag.value()).c_str() + ); + tagLabel->setAnchorPoint({ .0f, .5f }); + tagLabel->setScale(.3f); + tagLabel->setPosition( + versionLabel->getPositionX() + + versionLabel->getScaledContentSize().width + 5.f, + versionLabel->getPositionY() + ); + this->addChild(tagLabel); + } + auto creatorStr = "by " + info.developer; auto creatorLabel = CCLabelBMFont::create(creatorStr.c_str(), "goldFont.fnt"); creatorLabel->setScale(.43f); diff --git a/loader/src/utils/VersionInfo.cpp b/loader/src/utils/VersionInfo.cpp index a8a2abe2..b8b5dd61 100644 --- a/loader/src/utils/VersionInfo.cpp +++ b/loader/src/utils/VersionInfo.cpp @@ -4,6 +4,7 @@ #include #include +#include USE_GEODE_NAMESPACE(); @@ -13,22 +14,78 @@ USE_GEODE_NAMESPACE(); #define GEODE_SSCANF sscanf #endif -// VersionInfo +// VersionTag -bool VersionInfo::validate(std::string const& string) { - int buf0, buf1, buf2; - if (GEODE_SSCANF(string.c_str(), "v%d.%d.%d", &buf0, &buf1, &buf2)) return true; - if (GEODE_SSCANF(string.c_str(), "%d.%d.%d", &buf0, &buf1, &buf2)) return true; - return false; -} - -VersionInfo::VersionInfo(std::string const& versionString) { - if (!GEODE_SSCANF(versionString.c_str(), "v%d.%d.%d", &m_major, &m_minor, &m_patch)) { - GEODE_SSCANF(versionString.c_str(), "%d.%d.%d", &m_major, &m_minor, &m_patch); +std::optional geode::versionTagFromString(std::string const& str) { + switch (hash(str.c_str())) { + case hash("alpha"): return VersionTag::Alpha; + case hash("beta"): return VersionTag::Beta; + case hash("prerelease"): return VersionTag::Prerelease; + default: return std::nullopt; } } -std::string VersionInfo::toString() const { +std::string geode::versionTagToSuffixString(VersionTag tag) { + switch (tag) { + case VersionTag::Alpha: return "-alpha"; + case VersionTag::Beta: return "-beta"; + case VersionTag::Prerelease: return "-prerelease"; + } + return ""; +} + +std::string geode::versionTagToString(VersionTag tag) { + switch (tag) { + case VersionTag::Alpha: return "Alpha"; + case VersionTag::Beta: return "Beta"; + case VersionTag::Prerelease: return "Prerelease"; + } + return ""; +} + +// VersionInfo + +bool VersionInfo::validate(std::string const& string) { + std::string copy = string; + if (copy.starts_with("v")) { + copy = string.substr(1); + } + + int buf0, buf1, buf2; + std::string bufT; + if (scn::scan(copy, "{}.{}.{}-{}", buf0, buf1, buf2, bufT)) { + return versionTagFromString(bufT).has_value(); + } + if (scn::scan(copy, "{}.{}.{}", buf0, buf1, buf2)) { + return true; + } + + return false; +} + +VersionInfo::VersionInfo(std::string const& string) { + std::string copy = string; + if (copy.starts_with("v")) { + copy = string.substr(1); + } + std::string tag; + scn::scan(copy, "{}.{}.{}-{}", m_major, m_minor, m_patch, tag) || + scn::scan(copy, "{}.{}.{}", m_major, m_minor, m_patch); + if (tag.size()) { + if (auto t = versionTagFromString(tag)) { + m_tag = t; + } + } +} + +std::string VersionInfo::toString(bool includeTag) const { + if (includeTag && m_tag) { + return fmt::format( + "v{}.{}.{}{}", + m_major, m_minor, m_patch, + versionTagToSuffixString(m_tag.value()) + ); + } return fmt::format("v{}.{}.{}", m_major, m_minor, m_patch); }