From 3724038af472468b8811b88b7adf433e2bdacae3 Mon Sep 17 00:00:00 2001 From: Allen Faure Date: Tue, 30 Jan 2024 14:54:36 -0600 Subject: [PATCH] convert 'experimental mode' into a feature flag system Signed-off-by: Allen Faure --- WeakAuras/Features.lua | 98 +++++++++++++++++++++++++++++++++ WeakAuras/Init.lua | 27 +++++---- WeakAuras/WeakAuras.lua | 15 ++++- WeakAuras/WeakAuras.toc | 1 + WeakAuras/WeakAuras_Vanilla.toc | 1 + WeakAuras/WeakAuras_Wrath.toc | 1 + 6 files changed, 129 insertions(+), 14 deletions(-) create mode 100644 WeakAuras/Features.lua diff --git a/WeakAuras/Features.lua b/WeakAuras/Features.lua new file mode 100644 index 0000000000..e5e26c4d44 --- /dev/null +++ b/WeakAuras/Features.lua @@ -0,0 +1,98 @@ +---@type string, Private +local addon, Private = ... + +---@alias BuildType "dev" | "pr" | "alpha" | "beta" | "release" + +---@class feature +---@field id string +---@field autoEnable? BuildType[] +---@field requiredByAura? fun(self: self, aura: auraData): boolean +---@field enabled? boolean +---@field persist? true +---@field sub? SubscribableObject + +---@class Features +local Features = { + ---@type table + __feats = {} +} +Private.Features = Features + +---@param id string +function Features:Exists(id) + return self.__feats[id] ~= nil +end + +---@param id string +function Features:Enabled(id) + return self:Exists(id) and self.__feats[id].enabled +end + +---@param id string +function Features:Enable(id) + if self.__feats[id] then + self.__feats[id].enabled = true + if self.__feats[id].persist then + Private.db.features[id] = true + end + self.__feats[id].sub:Notify("ENABLED") + end +end + +---@param id string +function Features:Disable(id) + if self.__feats[id] then + self.__feats[id].enabled = false + if self.__feats[id].persist then + Private.db.features[id] = false + end + self.__feats[id].sub:Notify("DISABLED") + end +end + +---@param feature feature +function Features:Register(feature) + if not self.__feats[feature.id] then + self.__feats[feature.id] = feature + feature.sub = Private.CreateSubscribableObject() + for _, buildType in ipairs(feature.autoEnable or {}) do + if Private.buildType == buildType then + self:Enable(feature.id) + end + end + end +end + +---@param id string +---@param func function +-- hides a function behind a feature flag +function Features:Wrap(id, func) + return function(...) + if self:IsFeatureEnabled(id) then + return func(...) + end + end +end + +---@param data auraData +---@return boolean, table +function Features:AuraCanFunction(data) + local enabled = true + local reasons = {} + + for _, feature in pairs(self.__feats) do + if feature.requiredByAura and not feature:requiredByAura(data) then + enabled = false + reasons[feature.id] = false + end + end + + return enabled, reasons +end + +-- sample debug feature +Features:Register({ + id = "debug", + autoEnable = {"dev"} +}) + diff --git a/WeakAuras/Init.lua b/WeakAuras/Init.lua index ad771e8270..369ca514d3 100644 --- a/WeakAuras/Init.lua +++ b/WeakAuras/Init.lua @@ -55,6 +55,7 @@ local GetAddOnMetadata = C_AddOns and C_AddOns.GetAddOnMetadata or GetAddOnMetad --- @field ExecEnv table --- @field event_prototypes table --- @field event_categories table +--- @field Features Features --- @field FindUnusedId fun(prefix: string?): string --- @field FixGroupChildrenOrderForGroup fun(data: auraData) --- @field frames table @@ -370,31 +371,33 @@ local flavorFromTocToNumber = { } local flavor = flavorFromTocToNumber[flavorFromToc] +if versionString:find("alpha") then + WeakAuras.buildType = "alpha" +elseif versionString:find("beta") then + WeakAuras.buildType = "beta" +else + WeakAuras.buildType = "release" +end + +--[[@experimental@ +WeakAuras.buildType = "pr" +--@end-experimental@]] + + --@debug@ if versionStringFromToc == "@project-version@" then versionStringFromToc = "Dev" buildTime = "Dev" - experimental = true + WeakAuras.BuildType = "dev" end --@end-debug@ ---[[@experimental@ -experimental = true ---@end-experimental@]] WeakAuras.versionString = versionStringFromToc WeakAuras.buildTime = buildTime WeakAuras.newFeatureString = "|TInterface\\OptionsFrame\\UI-OptionsFrame-NewFeatureIcon:0|t" WeakAuras.BuildInfo = select(4, GetBuildInfo()) -function WeakAuras.IsExperimental() - return experimental -end - -function Private.EnableExperiments(enabled) - experimental = enabled -end - function WeakAuras.IsClassicEra() return flavor == 1 end diff --git a/WeakAuras/WeakAuras.lua b/WeakAuras/WeakAuras.lua index 8a8c9b2191..cffbc34406 100644 --- a/WeakAuras/WeakAuras.lua +++ b/WeakAuras/WeakAuras.lua @@ -194,8 +194,18 @@ function SlashCmdList.WEAKAURAS(input) elseif msg == "repair" then StaticPopup_Show("WEAKAURAS_CONFIRM_REPAIR", nil, nil, {reason = "user"}) elseif msg == "optin" then - Private.EnableExperiments(true) - prettyPrint(L["Experimental mode active! If you have any problems with an experimental feature, please let us know via a ticket on Github!"]) + local feature = args[1] + if not Private.Features:Exists(feature) then + print(L["Unknown feature '%s'"]:format(feature)) + else + if Private.Features:Enabled(feature) then + Private.Features:Disable(feature) + prettyPrint(L["Disabled feature '%s'"]:format(feature)) + else + Private.Features:Enable(feature) + prettyPrint(L["Enabled feature '%s'"]:format(feature)) + end + end else WeakAuras.OpenOptions(msg); end @@ -1160,6 +1170,7 @@ function Private.Login(initialTime, takeNewSnapshots) local loginThread = coroutine.create(function() Private.Pause(); + db.features = db.features or {} if db.history then local histRepo = WeakAuras.LoadFromArchive("Repository", "history") local migrationRepo = WeakAuras.LoadFromArchive("Repository", "migration") diff --git a/WeakAuras/WeakAuras.toc b/WeakAuras/WeakAuras.toc index b3f2ff4b0a..4ac40ea97d 100644 --- a/WeakAuras/WeakAuras.toc +++ b/WeakAuras/WeakAuras.toc @@ -33,6 +33,7 @@ Init.lua locales.xml ArchiveTypes\Repository.lua DefaultOptions.lua +Features.lua # Core files Atlas_Retail.lua diff --git a/WeakAuras/WeakAuras_Vanilla.toc b/WeakAuras/WeakAuras_Vanilla.toc index aec634ab3f..d9a4f41067 100644 --- a/WeakAuras/WeakAuras_Vanilla.toc +++ b/WeakAuras/WeakAuras_Vanilla.toc @@ -26,6 +26,7 @@ Init.lua locales.xml ArchiveTypes\Repository.lua DefaultOptions.lua +Features.lua # Core files Atlas_Vanilla.lua diff --git a/WeakAuras/WeakAuras_Wrath.toc b/WeakAuras/WeakAuras_Wrath.toc index 260774c556..72f45bb648 100644 --- a/WeakAuras/WeakAuras_Wrath.toc +++ b/WeakAuras/WeakAuras_Wrath.toc @@ -29,6 +29,7 @@ Init.lua locales.xml ArchiveTypes\Repository.lua DefaultOptions.lua +Features.lua # Core files Atlas_Wrath.lua