From 3db651516dc561ea1c57844ea4b43104a6535881 Mon Sep 17 00:00:00 2001 From: Solanya Date: Tue, 23 Apr 2024 20:36:47 +0200 Subject: [PATCH 01/12] Remove Ellyb submodule link --- .gitmodules | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 26b1e70b..658c6cec 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "lib/TRP-Anim-DB"] path = lib/TRP-Anim-DB url = https://github.com/Ellypse/TRP-Anim-DB.git -[submodule "lib/Ellyb"] - path = lib/Ellyb - url = https://github.com/Ellypse/Ellyb [submodule "lib/CustomTutorials-2.1"] path = lib/CustomTutorials-2.1 url = https://github.com/Jaliborc/CustomTutorials-2.1.git From f2bfbed0436c5a734bde44c24c9a4c46de5394f5 Mon Sep 17 00:00:00 2001 From: Solanya Date: Tue, 23 Apr 2024 20:38:38 +0200 Subject: [PATCH 02/12] Removing Ellyb --- lib/Ellyb | 1 - 1 file changed, 1 deletion(-) delete mode 160000 lib/Ellyb diff --git a/lib/Ellyb b/lib/Ellyb deleted file mode 160000 index 6e5de650..00000000 --- a/lib/Ellyb +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6e5de650800213f590cf43e7cb710f09bab8b660 From 7414ac74f8d7807a0fd32647d2114e64c0dc9f27 Mon Sep 17 00:00:00 2001 From: Solanya Date: Tue, 23 Apr 2024 20:40:30 +0200 Subject: [PATCH 03/12] It's back (also IsAddOnLoaded part of C_AddOns) --- lib/Ellyb/Configuration/Configuration.lua | 100 ++++ lib/Ellyb/Documentation/Assertions.lua | 96 ++++ .../Documentation/DeprecationWarnings.lua | 57 +++ lib/Ellyb/Documentation/GameEvents.lua | 49 ++ lib/Ellyb/Documentation/_Documentation.lua | 50 ++ lib/Ellyb/Documentation/_Documentation.xml | 8 + lib/Ellyb/Ellyb.lua | 139 +++++ lib/Ellyb/Ellyb.toc | 8 + lib/Ellyb/Ellyb.xml | 18 + lib/Ellyb/Enum.lua | 43 ++ lib/Ellyb/Internals/Class.lua | 36 ++ lib/Ellyb/Internals/Internals.xml | 6 + lib/Ellyb/Internals/PooledObjectMixin.lua | 62 +++ lib/Ellyb/LICENSE | 201 ++++++++ lib/Ellyb/Libraries/Libraries.xml | 6 + lib/Ellyb/Libraries/easings.lua | 479 ++++++++++++++++++ lib/Ellyb/Libraries/middleclass.lua | 207 ++++++++ lib/Ellyb/Locales.lua | 52 ++ lib/Ellyb/Logs/Log.lua | 32 ++ lib/Ellyb/Logs/Logger.lua | 100 ++++ lib/Ellyb/Logs/Logs.xml | 7 + lib/Ellyb/Logs/LogsManager.lua | 38 ++ lib/Ellyb/README.md | 31 ++ lib/Ellyb/Textures/Texture.lua | 191 +++++++ lib/Ellyb/Tools/Assertions.lua | 147 ++++++ lib/Ellyb/Tools/Colors.lua | 374 ++++++++++++++ lib/Ellyb/Tools/ColorsManager.lua | 206 ++++++++ lib/Ellyb/Tools/DeprecationWarnings.lua | 70 +++ lib/Ellyb/Tools/EventsDispatcher.lua | 85 ++++ lib/Ellyb/Tools/Functions.lua | 22 + lib/Ellyb/Tools/GameEvents.lua | 55 ++ lib/Ellyb/Tools/Icon.lua | 32 ++ lib/Ellyb/Tools/Locale.lua | 82 +++ lib/Ellyb/Tools/Localization.lua | 146 ++++++ lib/Ellyb/Tools/Maths.lua | 44 ++ lib/Ellyb/Tools/Promise.lua | 114 +++++ lib/Ellyb/Tools/Promises.lua | 46 ++ lib/Ellyb/Tools/SlashCommand.lua | 81 +++ lib/Ellyb/Tools/Strings/Interpolate.lua | 110 ++++ lib/Ellyb/Tools/Strings/Strings.lua | 254 ++++++++++ lib/Ellyb/Tools/System.lua | 88 ++++ lib/Ellyb/Tools/Tables.lua | 149 ++++++ lib/Ellyb/Tools/Thread.lua | 46 ++ lib/Ellyb/Tools/Threads.lua | 72 +++ lib/Ellyb/Tools/Tools.xml | 24 + lib/Ellyb/Tools/Transitionators.lua | 78 +++ lib/Ellyb/Tools/Unit.lua | 89 ++++ lib/Ellyb/UI/Cursor.lua | 130 +++++ lib/Ellyb/UI/EditBoxes.lua | 76 +++ lib/Ellyb/UI/Frames.lua | 62 +++ lib/Ellyb/UI/Popups.lua | 46 ++ lib/Ellyb/UI/Popups.xml | 137 +++++ lib/Ellyb/UI/Tooltip.lua | 201 ++++++++ lib/Ellyb/UI/Tooltips.lua | 54 ++ lib/Ellyb/UI/UI.xml | 14 + 55 files changed, 5150 insertions(+) create mode 100644 lib/Ellyb/Configuration/Configuration.lua create mode 100644 lib/Ellyb/Documentation/Assertions.lua create mode 100644 lib/Ellyb/Documentation/DeprecationWarnings.lua create mode 100644 lib/Ellyb/Documentation/GameEvents.lua create mode 100644 lib/Ellyb/Documentation/_Documentation.lua create mode 100644 lib/Ellyb/Documentation/_Documentation.xml create mode 100644 lib/Ellyb/Ellyb.lua create mode 100644 lib/Ellyb/Ellyb.toc create mode 100644 lib/Ellyb/Ellyb.xml create mode 100644 lib/Ellyb/Enum.lua create mode 100644 lib/Ellyb/Internals/Class.lua create mode 100644 lib/Ellyb/Internals/Internals.xml create mode 100644 lib/Ellyb/Internals/PooledObjectMixin.lua create mode 100644 lib/Ellyb/LICENSE create mode 100644 lib/Ellyb/Libraries/Libraries.xml create mode 100644 lib/Ellyb/Libraries/easings.lua create mode 100644 lib/Ellyb/Libraries/middleclass.lua create mode 100644 lib/Ellyb/Locales.lua create mode 100644 lib/Ellyb/Logs/Log.lua create mode 100644 lib/Ellyb/Logs/Logger.lua create mode 100644 lib/Ellyb/Logs/Logs.xml create mode 100644 lib/Ellyb/Logs/LogsManager.lua create mode 100644 lib/Ellyb/README.md create mode 100644 lib/Ellyb/Textures/Texture.lua create mode 100644 lib/Ellyb/Tools/Assertions.lua create mode 100644 lib/Ellyb/Tools/Colors.lua create mode 100644 lib/Ellyb/Tools/ColorsManager.lua create mode 100644 lib/Ellyb/Tools/DeprecationWarnings.lua create mode 100644 lib/Ellyb/Tools/EventsDispatcher.lua create mode 100644 lib/Ellyb/Tools/Functions.lua create mode 100644 lib/Ellyb/Tools/GameEvents.lua create mode 100644 lib/Ellyb/Tools/Icon.lua create mode 100644 lib/Ellyb/Tools/Locale.lua create mode 100644 lib/Ellyb/Tools/Localization.lua create mode 100644 lib/Ellyb/Tools/Maths.lua create mode 100644 lib/Ellyb/Tools/Promise.lua create mode 100644 lib/Ellyb/Tools/Promises.lua create mode 100644 lib/Ellyb/Tools/SlashCommand.lua create mode 100644 lib/Ellyb/Tools/Strings/Interpolate.lua create mode 100644 lib/Ellyb/Tools/Strings/Strings.lua create mode 100644 lib/Ellyb/Tools/System.lua create mode 100644 lib/Ellyb/Tools/Tables.lua create mode 100644 lib/Ellyb/Tools/Thread.lua create mode 100644 lib/Ellyb/Tools/Threads.lua create mode 100644 lib/Ellyb/Tools/Tools.xml create mode 100644 lib/Ellyb/Tools/Transitionators.lua create mode 100644 lib/Ellyb/Tools/Unit.lua create mode 100644 lib/Ellyb/UI/Cursor.lua create mode 100644 lib/Ellyb/UI/EditBoxes.lua create mode 100644 lib/Ellyb/UI/Frames.lua create mode 100644 lib/Ellyb/UI/Popups.lua create mode 100644 lib/Ellyb/UI/Popups.xml create mode 100644 lib/Ellyb/UI/Tooltip.lua create mode 100644 lib/Ellyb/UI/Tooltips.lua create mode 100644 lib/Ellyb/UI/UI.xml diff --git a/lib/Ellyb/Configuration/Configuration.lua b/lib/Ellyb/Configuration/Configuration.lua new file mode 100644 index 00000000..e23c7468 --- /dev/null +++ b/lib/Ellyb/Configuration/Configuration.lua @@ -0,0 +1,100 @@ +---@type Ellyb +local Ellyb = Ellyb(...); + +if Ellyb.Configuration then + return +end + +-- Lua imports +local format = format; +local type = type; +local pairs = pairs; + +---@class Configuration +local Configuration, _private = Ellyb.Class("Configuration"); + +local UNKNOWN_CONFIGURATION_KEY = [[Unknown configuration key %s.]]; +local CONFIGURATION_KEY_ALREADY_EXISTS = [[Configuration key %s has already been registered.]]; + +---Constructor +---@param savedVariablesName string @ The saved variable name, used to access the table from _G +function Configuration:initialize(savedVariablesName) + Ellyb.Assertions.isType(savedVariablesName, "string", "savedVariablesName"); + + _private[self] = {}; + _private[self].savedVariablesName = savedVariablesName; + _private[self].configCallbackRegistry = CreateFromMixins(CallbackRegistryBaseMixin); + _private[self].configCallbackRegistry:OnLoad(); + _private[self].defaultValues = {}; + + -- Initialize the saved variables global table if it has never been initialized before + if not _G[savedVariablesName] then + _G[savedVariablesName] = {}; + end +end + +--- Register a new configuration key with its default value +---@param configurationKey string @ A new configuration key +---@param defaultValue any @ The default value for this new configuration key +function Configuration:RegisterConfigKey(configurationKey, defaultValue) + Ellyb.Assertions.isType(configurationKey, "string", "configurationKey"); + assert(not self:IsConfigurationKeyRegistered(configurationKey), format(CONFIGURATION_KEY_ALREADY_EXISTS, configurationKey)); + + _private[self].defaultValues[configurationKey] = defaultValue; + + if self:GetValue(configurationKey) == nil then + self:SetValue(configurationKey, defaultValue); + end +end + +---IsConfigurationKeyRegistered +---@param configurationKey string @ A valid configuration key +---@return boolean isRegistered @ True if the configuration has already been registered +function Configuration:IsConfigurationKeyRegistered(configurationKey) + Ellyb.Assertions.isType(configurationKey, "string", "configurationKey"); + return _private[self].defaultValues[configurationKey] ~= nil; +end + +--- Get the value of a configuration key +---@param configurationKey string @ A valid configuration key, previously registered +function Configuration:GetValue(configurationKey) + return _G[_private[self].savedVariablesName][configurationKey]; +end + +--- Set the value of a configuration key +---@param configurationKey string @ A valid configuration key that has previously been registered +---@param value any @ The new value for the configuration key +function Configuration:SetValue(configurationKey, value) + Ellyb.Assertions.isType(configurationKey, "string", "configurationKey"); + assert(self:IsConfigurationKeyRegistered(configurationKey), format(UNKNOWN_CONFIGURATION_KEY, configurationKey)); + + local savedVariables = _G[_private[self].savedVariablesName]; + if savedVariables[configurationKey] ~= value then + savedVariables[configurationKey] = value; + _private[self].configCallbackRegistry:TriggerEvent(configurationKey, value); + end +end + +--- Reset the value of a configuration key to its default value +---@param configurationKey string @ A valid configuration key that has previously been registered +function Configuration:ResetValue(configurationKey) + Ellyb.Assertions.isType(configurationKey, "string", "configurationKey"); + assert(self:IsConfigurationKeyRegistered(configurationKey), format(UNKNOWN_CONFIGURATION_KEY, configurationKey)); + + self:SetValue(configurationKey, _private[self].defaultValues[configurationKey]); +end + +---OnChange +---@param key string|string[] @ A configuration key or a list of configuration keys to listen for change +---@param callback function @ A callback that will be called when the value of the given key changes. +function Configuration:OnChange(key, callback) + if type(key) == "table" then + for _, k in pairs(key) do + self:OnChange(k, callback); + end + else + _private[self].configCallbackRegistry:RegisterCallback(key, callback); + end +end + +Ellyb.Configuration = Configuration; diff --git a/lib/Ellyb/Documentation/Assertions.lua b/lib/Ellyb/Documentation/Assertions.lua new file mode 100644 index 00000000..b0c958fa --- /dev/null +++ b/lib/Ellyb/Documentation/Assertions.lua @@ -0,0 +1,96 @@ +---@type Ellyb +local Ellyb = Ellyb(...); + +-- IDE shortcut to quickly go to related module +local _ = Ellyb.Assertions; + +Ellyb.Documentation:AddDocumentationTable("Ellyb.Assertions", { + Name = "Ellyb.Assertions", + Type = "System", + Namespace = "Ellyb.Assertions", + + Functions = { + { + Name = "isType", + Type = "Function", + Documentation = { [[Check if a variable is of the expected type ("number", "boolean", "string") +Can also check for Widget type ("Frame", "Button", "Texture")]] }, + + Arguments = { + { Name = "variable", Type = "any", Documentation = { "Any kind of variable, to be tested for its type" } }, + { Name = "expectedType", Type = "string", Documentation = { "Expected type of the variable" } }, + { Name = "variableName", Type = "string", Documentation = { "The name of the variable being tested, will be visible in the error message" } }, + }, + }, + { + Name = "isOfTypes", + Type = "Function", + Documentation = { [[Check if a variable is of one of the types expected ("number", "boolean", "string") +Can also check for Widget types ("Frame", "Button", "Texture")]] }, + + Arguments = { + { Name = "variable", Type = "any", Documentation = { "Any kind of variable, to be tested for its type" } }, + { Name = "expectedTypes", Type = "table", Documentation = { "A list of expected types for the variable" } }, + { Name = "variableName", Type = "string", Documentation = { "The name of the variable being tested, will be visible in the error message" } }, + }, + }, + { + Name = "isNotNil", + Type = "Function", + Documentation = { [[Check if a variable is not nil]] }, + + Arguments = { + { Name = "variable", Type = "any", Documentation = { "Any kind of variable, to be tested for its type" } }, + { Name = "variableName", Type = "string", Documentation = { "The name of the variable being tested, will be visible in the error message" } }, + }, + }, + { + Name = "isNotEmpty", + Type = "Function", + Documentation = { [[Check if a variable is not empty]] }, + + Arguments = { + { Name = "variable", Type = "any", Documentation = { "Any kind of variable, to be tested for its type" } }, + { Name = "variableName", Type = "string", Documentation = { "The name of the variable being tested, will be visible in the error message" } }, + }, + + }, + { + Name = "isInstanceOf", + Type = "Function", + Documentation = { [[Check if a variable is an instance of a specified class, taking polymorphism into account, so inherited class will pass the test.]] }, + + Arguments = { + { Name = "variable", Type = "any", Documentation = { "Any kind of variable, to be tested for its type" } }, + { Name = "class", Type = "string", Documentation = { "A direct reference to the class definition" } }, + { Name = "variableName", Type = "string", Documentation = { "The name of the variable being tested, will be visible in the error message" } }, + }, + + }, + { + Name = "isOneOf", + Type = "Function", + Documentation = { [[Check if a variable value is one of the possible values.]] }, + + Arguments = { + { Name = "variable", Type = "any", Documentation = { "Any kind of variable, to be tested for its content" } }, + { Name = "possibleValues", Type = "table", Documentation = { "A table of the possible values accepted" } }, + { Name = "variableName", Type = "string", Documentation = { "The name of the variable being tested, will be visible in the error message" } }, + }, + + }, + { + Name = "numberIsBetween", + Type = "Function", + Documentation = { [[Check if a variable is a number between a maximum and a minimum.]] }, + + Arguments = { + { Name = "variable", Type = "number", Documentation = { "A number to check" } }, + { Name = "minimum", Type = "number", Documentation = { "The minimum value for the number" } }, + { Name = "maximum", Type = "number", Documentation = { "The maximum value for the number" } }, + { Name = "variableName", Type = "string", Documentation = { "The name of the variable being tested, will be visible in the error message" } }, + }, + + }, + }, +}); diff --git a/lib/Ellyb/Documentation/DeprecationWarnings.lua b/lib/Ellyb/Documentation/DeprecationWarnings.lua new file mode 100644 index 00000000..af93cc89 --- /dev/null +++ b/lib/Ellyb/Documentation/DeprecationWarnings.lua @@ -0,0 +1,57 @@ +---@type Ellyb +local Ellyb = Ellyb(...); + +-- IDE shortcut to go to module +local _ = Ellyb.DeprecationWarnings; + +Ellyb.Documentation:AddDocumentationTable("Ellyb.DeprecationWarnings", { + Name = "Ellyb.DeprecationWarnings", + Type = "System", + Namespace = "Ellyb.DeprecationWarnings", + + Functions = { + { + Name = "wrapAPI", + Type = "Function", + Documentation = { "Create a new table that will throw deprecation warnings and use a given new API table to map a previous API now deprecated." }, + + Arguments = { + { Name = "newAPITable", Type = "table", Nilable = false, Documentation = { "The table for the new API." } }, + { Name = "oldAPIName", Type = "string", Nilable = false, Documentation = { "The name of the deprecated API." } }, + { Name = "newAPIName", Type = "string", Nilable = false, Documentation = { "The name of the new API." } }, + { Name = "oldAPIReference", Type = "table", Nilable = true, Documentation = { "An existing table that should be used to wrap with the new API warnings." } }, + }, + + Returns = + { + { Name = "wrappedAPI", Type = "table", Nilable = false, Documentation = { "This table can be used to access the new API while throwing deprecation warnings." } }, + }, + }, + { + Name = "wrapFunction", + Type = "Function", + Documentation = { "Create a new function that will throw deprecation warnings and use a given new function to map a previous API functions now deprecated." }, + + Arguments = { + { Name = "newFunction", Type = "function", Nilable = false, Documentation = { "The new function that should be called instead of the deprecated one." } }, + { Name = "oldFunctionName", Type = "string", Nilable = false, Documentation = { "The name of the deprecated function." } }, + { Name = "newFunctionName", Type = "string", Nilable = false, Documentation = { "The name of the new function." } }, + }, + + Returns = + { + { Name = "wrappedFunction", Type = "function", Nilable = false, Documentation = { "Calling this function will call the new function and throw a deprecation warning." } }, + }, + }, + { + Name = "warn", + Type = "Function", + Documentation = { "Send a custom deprecation warning." }, + + Arguments = { + { Name = "customWarning", Type = "string", Nilable = false, Documentation = { "A custom message to display as a warning." } }, + + }, + }, + }, +}) diff --git a/lib/Ellyb/Documentation/GameEvents.lua b/lib/Ellyb/Documentation/GameEvents.lua new file mode 100644 index 00000000..aed9fbf8 --- /dev/null +++ b/lib/Ellyb/Documentation/GameEvents.lua @@ -0,0 +1,49 @@ +---@type Ellyb +local Ellyb = Ellyb(...); + +-- IDE shortcut to go to module +local _ = Ellyb.GameEvents; + +Ellyb.Documentation:AddDocumentationTable("Ellyb.GameEvents", { + Name = "Ellyb.GameEvents", + Type = "System", + Namespace = "Ellyb.GameEvents", + + Functions = { + { + Name = "registerCallback", + Type = "Function", + Documentation = { "Register a callback for a game event." }, + + Arguments = { + { Name = "event", Type = "string", Nilable = false, Documentation = { "A game event to listen to." } }, + { Name = "callback", Type = "function", Nilable = false, Documentation = { "A callback that will be called when the event is fired with its arguments." } }, + }, + + Returns = + { + { Name = "handlerID", Type = "string", Nilable = false, Documentation = { "A handler ID that can be used to unregister the callback later." } }, + }, + }, + { + Name = "unregisterCallback", + Type = "Function", + Documentation = { "Unregister a previously registered callback using the handler ID given at registration." }, + + Arguments = { + { Name = "handlerID", Type = "string", Nilable = false, Documentation = { "The handler ID of a previsouly registered callback that we want to unregister." } }, + }, + }, + + { + Name = "triggerEvent", + Type = "Function", + Documentation = { "Register a callback for a game event." }, + + Arguments = { + { Name = "event", Type = "string", Nilable = false, Documentation = { "A game event to manually trigger." } }, + { Name = "...", Type = "any", Nilable = false, Documentation = { "Arguments to pass to the listeners" } }, + }, + }, + }, +}) diff --git a/lib/Ellyb/Documentation/_Documentation.lua b/lib/Ellyb/Documentation/_Documentation.lua new file mode 100644 index 00000000..40a1b381 --- /dev/null +++ b/lib/Ellyb/Documentation/_Documentation.lua @@ -0,0 +1,50 @@ +---@type Ellyb +local Ellyb = Ellyb(...); + +if Ellyb.Documentation then + return +end + +local Documentation = {}; + +local documentedAPIs = {}; + +function Documentation:AddDocumentationTable(APIName, documentedAPI) + + -- Ignore documentation that already exists + if documentedAPIs[APIName] then + return false + end + + -- Since I always forget to add the other type of fields, we make them optional in our API declarations + -- and automatically add them here :P + if not documentedAPI.Events then + documentedAPI.Events = {}; + end + if not documentedAPI.Tables then + documentedAPI.Tables = {}; + end + if not documentedAPI.Functions then + documentedAPI.Functions = {}; + end + + documentedAPIs[APIName] = documentedAPI; + + if C_AddOns.IsAddOnLoaded("Blizzard_APIDocumentation") then + APIDocumentation:AddDocumentationTable(documentedAPI); + end +end + +function Documentation:APIDocumentationExists(APIName) + return documentedAPIs[APIName] ~= nil; +end + +Ellyb.GameEvents.registerCallback("ADDON_LOADED", function(addOnName) + if addOnName == "Blizzard_APIDocumentation" then + for _, documentedAPI in pairs(documentedAPIs) do + APIDocumentation:AddDocumentationTable(documentedAPI); + end + end +end) + +Ellyb.Documentation = Documentation; diff --git a/lib/Ellyb/Documentation/_Documentation.xml b/lib/Ellyb/Documentation/_Documentation.xml new file mode 100644 index 00000000..82c3f488 --- /dev/null +++ b/lib/Ellyb/Documentation/_Documentation.xml @@ -0,0 +1,8 @@ + + +