consolidated patterns
This commit is contained in:
23
FlexLove.lua
23
FlexLove.lua
@@ -89,25 +89,16 @@ if ImageDataReader.init then
|
||||
ImageDataReader.init(errorHandlerDeps)
|
||||
end
|
||||
|
||||
-- Initialize Units module with Context dependency
|
||||
Units.initialize(Context)
|
||||
Units.initializeErrorHandler(ErrorHandler)
|
||||
|
||||
-- Initialize ErrorHandler for Color module
|
||||
Color.initializeErrorHandler(ErrorHandler)
|
||||
|
||||
-- Initialize ErrorHandler for utils
|
||||
utils.initializeErrorHandler(ErrorHandler)
|
||||
|
||||
-- Initialize ErrorHandler for Animation module
|
||||
Animation.initializeErrorHandler(ErrorHandler)
|
||||
|
||||
-- Initialize ErrorHandler for AnimationGroup module
|
||||
AnimationGroup.initializeErrorHandler(ErrorHandler)
|
||||
-- Initialize modules with dependencies
|
||||
Units.init({ Context = Context, ErrorHandler = ErrorHandler })
|
||||
Color.init({ ErrorHandler = ErrorHandler })
|
||||
utils.init({ ErrorHandler = ErrorHandler })
|
||||
Animation.init({ ErrorHandler = ErrorHandler, Easing = Easing, Color = Color })
|
||||
AnimationGroup.init({ ErrorHandler = ErrorHandler })
|
||||
|
||||
-- Add version and metadata
|
||||
flexlove._VERSION = "0.2.3"
|
||||
flexlove._DESCRIPTION = "0I Library for LÖVE Framework based on flexbox"
|
||||
flexlove._DESCRIPTION = "UI Library for LÖVE Framework based on flexbox"
|
||||
flexlove._URL = "https://github.com/mikefreno/FlexLove"
|
||||
flexlove._LICENSE = [[
|
||||
MIT License
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
--- Easing function type
|
||||
---@alias EasingFunction fun(t: number): number
|
||||
|
||||
-- ErrorHandler dependency (injected via initializeErrorHandler)
|
||||
local ErrorHandler = nil
|
||||
|
||||
-- Easing module for easing functions
|
||||
local Easing = require("modules.Easing")
|
||||
local Easing = nil
|
||||
local Color = nil
|
||||
---@class Keyframe
|
||||
---@field at number Normalized time position (0-1)
|
||||
---@field values table Property values at this keyframe
|
||||
@@ -231,15 +226,21 @@ end
|
||||
---@param ColorModule table Color module reference
|
||||
---@return any interpolated Interpolated Color instance
|
||||
local function lerpColor(startColor, finalColor, easedT, ColorModule)
|
||||
if not ColorModule then
|
||||
return nil
|
||||
-- Use provided ColorModule or fall back to module-level Color or static _ColorModule
|
||||
local CM = ColorModule or Color or Animation._ColorModule
|
||||
|
||||
if not CM or not CM.parse or not CM.lerp then
|
||||
if ErrorHandler then
|
||||
ErrorHandler.warn("Animation", "Color module not properly initialized. Cannot interpolate colors.")
|
||||
end
|
||||
return startColor -- Return start color as fallback
|
||||
end
|
||||
|
||||
-- Parse colors if needed
|
||||
local colorA = ColorModule.parse(startColor)
|
||||
local colorB = ColorModule.parse(finalColor)
|
||||
local colorA = CM.parse(startColor)
|
||||
local colorB = CM.parse(finalColor)
|
||||
|
||||
return ColorModule.lerp(colorA, colorB, easedT)
|
||||
return CM.lerp(colorA, colorB, easedT)
|
||||
end
|
||||
|
||||
--- Helper function to interpolate table values (padding, margin, cornerRadius)
|
||||
@@ -252,8 +253,12 @@ local function lerpTable(startTable, finalTable, easedT)
|
||||
|
||||
-- Iterate through all keys in both tables
|
||||
local keys = {}
|
||||
for k in pairs(startTable) do keys[k] = true end
|
||||
for k in pairs(finalTable) do keys[k] = true end
|
||||
for k in pairs(startTable) do
|
||||
keys[k] = true
|
||||
end
|
||||
for k in pairs(finalTable) do
|
||||
keys[k] = true
|
||||
end
|
||||
|
||||
for key in pairs(keys) do
|
||||
local startVal = startTable[key]
|
||||
@@ -305,36 +310,60 @@ function Animation:lerpKeyframes(prevFrame, nextFrame, easedT)
|
||||
|
||||
-- Get all unique property keys
|
||||
local keys = {}
|
||||
for k in pairs(prevFrame.values) do keys[k] = true end
|
||||
for k in pairs(nextFrame.values) do keys[k] = true end
|
||||
for k in pairs(prevFrame.values) do
|
||||
keys[k] = true
|
||||
end
|
||||
for k in pairs(nextFrame.values) do
|
||||
keys[k] = true
|
||||
end
|
||||
|
||||
-- Define properties that should be animated as numbers
|
||||
local numericProperties = {
|
||||
"width", "height", "opacity", "x", "y",
|
||||
"gap", "imageOpacity", "scrollbarWidth",
|
||||
"borderWidth", "fontSize", "lineHeight"
|
||||
"width",
|
||||
"height",
|
||||
"opacity",
|
||||
"x",
|
||||
"y",
|
||||
"gap",
|
||||
"imageOpacity",
|
||||
"scrollbarWidth",
|
||||
"borderWidth",
|
||||
"fontSize",
|
||||
"lineHeight",
|
||||
}
|
||||
|
||||
-- Define properties that should be animated as Colors
|
||||
local colorProperties = {
|
||||
"backgroundColor", "borderColor", "textColor",
|
||||
"scrollbarColor", "scrollbarBackgroundColor", "imageTint"
|
||||
"backgroundColor",
|
||||
"borderColor",
|
||||
"textColor",
|
||||
"scrollbarColor",
|
||||
"scrollbarBackgroundColor",
|
||||
"imageTint",
|
||||
}
|
||||
|
||||
-- Define properties that should be animated as tables
|
||||
local tableProperties = {
|
||||
"padding", "margin", "cornerRadius"
|
||||
"padding",
|
||||
"margin",
|
||||
"cornerRadius",
|
||||
}
|
||||
|
||||
-- Create lookup sets for faster property type checking
|
||||
local numericSet = {}
|
||||
for _, prop in ipairs(numericProperties) do numericSet[prop] = true end
|
||||
for _, prop in ipairs(numericProperties) do
|
||||
numericSet[prop] = true
|
||||
end
|
||||
|
||||
local colorSet = {}
|
||||
for _, prop in ipairs(colorProperties) do colorSet[prop] = true end
|
||||
for _, prop in ipairs(colorProperties) do
|
||||
colorSet[prop] = true
|
||||
end
|
||||
|
||||
local tableSet = {}
|
||||
for _, prop in ipairs(tableProperties) do tableSet[prop] = true end
|
||||
for _, prop in ipairs(tableProperties) do
|
||||
tableSet[prop] = true
|
||||
end
|
||||
|
||||
-- Interpolate each property
|
||||
for key in pairs(keys) do
|
||||
@@ -343,9 +372,9 @@ function Animation:lerpKeyframes(prevFrame, nextFrame, easedT)
|
||||
|
||||
if numericSet[key] and type(startVal) == "number" and type(finalVal) == "number" then
|
||||
result[key] = lerpNumber(startVal, finalVal, easedT)
|
||||
elseif colorSet[key] and self._Color then
|
||||
elseif colorSet[key] and (self._Color or Animation._ColorModule) then
|
||||
if startVal ~= nil and finalVal ~= nil then
|
||||
result[key] = lerpColor(startVal, finalVal, easedT, self._Color)
|
||||
result[key] = lerpColor(startVal, finalVal, easedT, self._Color or Animation._ColorModule)
|
||||
end
|
||||
elseif tableSet[key] and type(startVal) == "table" and type(finalVal) == "table" then
|
||||
result[key] = lerpTable(startVal, finalVal, easedT)
|
||||
@@ -375,7 +404,7 @@ function Animation:interpolate()
|
||||
local t = math.min(self.elapsed / self.duration, 1)
|
||||
|
||||
-- Handle keyframe animations
|
||||
if self.keyframes and #self.keyframes >= 2 then
|
||||
if self.keyframes and type(self.keyframes) == "table" and #self.keyframes >= 2 then
|
||||
local prevFrame, nextFrame = self:findKeyframes(t)
|
||||
|
||||
if prevFrame and nextFrame then
|
||||
@@ -433,20 +462,34 @@ function Animation:interpolate()
|
||||
|
||||
-- Define properties that should be animated as numbers
|
||||
local numericProperties = {
|
||||
"width", "height", "opacity", "x", "y",
|
||||
"gap", "imageOpacity", "scrollbarWidth",
|
||||
"borderWidth", "fontSize", "lineHeight"
|
||||
"width",
|
||||
"height",
|
||||
"opacity",
|
||||
"x",
|
||||
"y",
|
||||
"gap",
|
||||
"imageOpacity",
|
||||
"scrollbarWidth",
|
||||
"borderWidth",
|
||||
"fontSize",
|
||||
"lineHeight",
|
||||
}
|
||||
|
||||
-- Define properties that should be animated as Colors
|
||||
local colorProperties = {
|
||||
"backgroundColor", "borderColor", "textColor",
|
||||
"scrollbarColor", "scrollbarBackgroundColor", "imageTint"
|
||||
"backgroundColor",
|
||||
"borderColor",
|
||||
"textColor",
|
||||
"scrollbarColor",
|
||||
"scrollbarBackgroundColor",
|
||||
"imageTint",
|
||||
}
|
||||
|
||||
-- Define properties that should be animated as tables
|
||||
local tableProperties = {
|
||||
"padding", "margin", "cornerRadius"
|
||||
"padding",
|
||||
"margin",
|
||||
"cornerRadius",
|
||||
}
|
||||
|
||||
-- Interpolate numeric properties
|
||||
@@ -460,13 +503,14 @@ function Animation:interpolate()
|
||||
end
|
||||
|
||||
-- Interpolate color properties (if Color module is available)
|
||||
if self._Color then
|
||||
local ColorModule = self._Color or Animation._ColorModule
|
||||
if ColorModule then
|
||||
for _, prop in ipairs(colorProperties) do
|
||||
local startVal = self.start[prop]
|
||||
local finalVal = self.final[prop]
|
||||
|
||||
if startVal ~= nil and finalVal ~= nil then
|
||||
result[prop] = lerpColor(startVal, finalVal, easedT, self._Color)
|
||||
result[prop] = lerpColor(startVal, finalVal, easedT, ColorModule)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -778,7 +822,7 @@ function Animation.keyframes(props)
|
||||
ErrorHandler.warn("Animation", "Keyframe animation requires at least 2 keyframes. Using empty animation.")
|
||||
props.keyframes = {
|
||||
{ at = 0, values = {} },
|
||||
{at = 1, values = {}}
|
||||
{ at = 1, values = {} },
|
||||
}
|
||||
end
|
||||
|
||||
@@ -790,7 +834,9 @@ function Animation.keyframes(props)
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(sortedKeyframes, function(a, b) return a.at < b.at end)
|
||||
table.sort(sortedKeyframes, function(a, b)
|
||||
return a.at < b.at
|
||||
end)
|
||||
|
||||
-- Ensure keyframes start at 0 and end at 1
|
||||
if #sortedKeyframes > 0 then
|
||||
@@ -815,13 +861,22 @@ function Animation.keyframes(props)
|
||||
})
|
||||
end
|
||||
|
||||
--- Initialize ErrorHandler dependency
|
||||
---@param errorHandler table The ErrorHandler module
|
||||
local function initializeErrorHandler(errorHandler)
|
||||
ErrorHandler = errorHandler
|
||||
--- Initialize dependencies
|
||||
---@param deps table Dependencies: { ErrorHandler = ErrorHandler, Easing = Easing, Color = Color? }
|
||||
function Animation.init(deps)
|
||||
if type(deps) == "table" then
|
||||
ErrorHandler = deps.ErrorHandler
|
||||
Easing = deps.Easing
|
||||
if deps.Color then
|
||||
Color = deps.Color
|
||||
Animation._ColorModule = deps.Color
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Export ErrorHandler initializer
|
||||
Animation.initializeErrorHandler = initializeErrorHandler
|
||||
-- Static method for Color module injection (for per-instance Color override)
|
||||
function Animation.setColorModule(ColorModule)
|
||||
Animation._ColorModule = ColorModule
|
||||
end
|
||||
|
||||
return Animation
|
||||
|
||||
@@ -327,13 +327,12 @@ function AnimationGroup:apply(element)
|
||||
element.animationGroup = self
|
||||
end
|
||||
|
||||
--- Initialize ErrorHandler dependency
|
||||
---@param errorHandler table The ErrorHandler module
|
||||
local function initializeErrorHandler(errorHandler)
|
||||
ErrorHandler = errorHandler
|
||||
--- Initialize dependencies
|
||||
---@param deps table Dependencies: { ErrorHandler = ErrorHandler }
|
||||
function AnimationGroup.init(deps)
|
||||
if type(deps) == "table" then
|
||||
ErrorHandler = deps.ErrorHandler
|
||||
end
|
||||
end
|
||||
|
||||
-- Export ErrorHandler initializer
|
||||
AnimationGroup.initializeErrorHandler = initializeErrorHandler
|
||||
|
||||
return AnimationGroup
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
local ErrorHandler = nil
|
||||
|
||||
--- Initialize ErrorHandler dependency
|
||||
---@param errorHandler table The ErrorHandler module
|
||||
local function initializeErrorHandler(errorHandler)
|
||||
ErrorHandler = errorHandler
|
||||
end
|
||||
|
||||
--- Standardized error message formatter (fallback for when ErrorHandler not available)
|
||||
---@param module string -- Module name (e.g., "Color", "Theme", "Units")
|
||||
---@param message string
|
||||
@@ -461,7 +455,12 @@ function Color.lerp(colorA, colorB, t)
|
||||
return Color.new(r, g, b, a)
|
||||
end
|
||||
|
||||
-- Export ErrorHandler initializer
|
||||
Color.initializeErrorHandler = initializeErrorHandler
|
||||
--- Initialize dependencies
|
||||
---@param deps table Dependencies: { ErrorHandler = ErrorHandler }
|
||||
function Color.init(deps)
|
||||
if type(deps) == "table" then
|
||||
ErrorHandler = deps.ErrorHandler
|
||||
end
|
||||
end
|
||||
|
||||
return Color
|
||||
|
||||
@@ -5,14 +5,17 @@ local ErrorHandler = nil
|
||||
|
||||
--- Initialize Units module with Context dependency
|
||||
---@param context table The Context module
|
||||
function Units.initialize(context)
|
||||
Context = context
|
||||
--- Initialize dependencies
|
||||
---@param deps table Dependencies: { Context = Context?, ErrorHandler = ErrorHandler? }
|
||||
function Units.init(deps)
|
||||
if type(deps) == "table" then
|
||||
if deps.Context then
|
||||
Context = deps.Context
|
||||
end
|
||||
if deps.ErrorHandler then
|
||||
ErrorHandler = deps.ErrorHandler
|
||||
end
|
||||
end
|
||||
|
||||
--- Initialize ErrorHandler dependency
|
||||
---@param errorHandler table The ErrorHandler module
|
||||
function Units.initializeErrorHandler(errorHandler)
|
||||
ErrorHandler = errorHandler
|
||||
end
|
||||
|
||||
---@param value string|number
|
||||
|
||||
@@ -300,10 +300,12 @@ end
|
||||
-- Validation utilities
|
||||
local ErrorHandler = nil
|
||||
|
||||
--- Initialize ErrorHandler dependency for validation utilities
|
||||
---@param errorHandler table The ErrorHandler module
|
||||
local function initializeErrorHandler(errorHandler)
|
||||
ErrorHandler = errorHandler
|
||||
--- Initialize dependencies
|
||||
---@param deps table Dependencies: { ErrorHandler = ErrorHandler }
|
||||
local function init(deps)
|
||||
if type(deps) == "table" then
|
||||
ErrorHandler = deps.ErrorHandler
|
||||
end
|
||||
end
|
||||
|
||||
--- Validate that a value is in an enum table
|
||||
@@ -1104,7 +1106,7 @@ return {
|
||||
resolveTextSizePreset = resolveTextSizePreset,
|
||||
getModifiers = getModifiers,
|
||||
TEXT_SIZE_PRESETS = TEXT_SIZE_PRESETS,
|
||||
initializeErrorHandler = initializeErrorHandler,
|
||||
init = init,
|
||||
validateEnum = validateEnum,
|
||||
validateRange = validateRange,
|
||||
validateType = validateType,
|
||||
|
||||
@@ -2,18 +2,16 @@ local luaunit = require("testing.luaunit")
|
||||
require("testing.loveStub")
|
||||
|
||||
local Animation = require("modules.Animation")
|
||||
local Easing = require("modules.Easing")
|
||||
local Color = require("modules.Color")
|
||||
local Transform = require("modules.Transform")
|
||||
local ErrorHandler = require("modules.ErrorHandler")
|
||||
local ErrorCodes = require("modules.ErrorCodes")
|
||||
|
||||
-- Initialize ErrorHandler
|
||||
-- Initialize modules
|
||||
ErrorHandler.init({ ErrorCodes = ErrorCodes })
|
||||
Animation.initializeErrorHandler(ErrorHandler)
|
||||
Color.initializeErrorHandler(ErrorHandler)
|
||||
|
||||
-- Make Color module available to Animation
|
||||
Animation.setColorModule(Color)
|
||||
Color.init({ ErrorHandler = ErrorHandler })
|
||||
Animation.init({ ErrorHandler = ErrorHandler, Easing = Easing, Color = Color })
|
||||
|
||||
TestAnimationProperties = {}
|
||||
|
||||
|
||||
@@ -2,12 +2,13 @@ local luaunit = require("testing.luaunit")
|
||||
require("testing.loveStub")
|
||||
|
||||
local Animation = require("modules.Animation")
|
||||
local Easing = require("modules.Easing")
|
||||
local ErrorHandler = require("modules.ErrorHandler")
|
||||
local ErrorCodes = require("modules.ErrorCodes")
|
||||
|
||||
-- Initialize ErrorHandler for Animation module
|
||||
-- Initialize modules
|
||||
ErrorHandler.init({ ErrorCodes = ErrorCodes })
|
||||
Animation.initializeErrorHandler(ErrorHandler)
|
||||
Animation.init({ ErrorHandler = ErrorHandler, Easing = Easing })
|
||||
|
||||
TestAnimation = {}
|
||||
|
||||
|
||||
@@ -2,12 +2,13 @@ local luaunit = require("testing.luaunit")
|
||||
require("testing.loveStub")
|
||||
|
||||
local Animation = require("modules.Animation")
|
||||
local Easing = require("modules.Easing")
|
||||
local ErrorHandler = require("modules.ErrorHandler")
|
||||
local ErrorCodes = require("modules.ErrorCodes")
|
||||
|
||||
-- Initialize ErrorHandler for Animation module
|
||||
-- Initialize modules
|
||||
ErrorHandler.init({ ErrorCodes = ErrorCodes })
|
||||
Animation.initializeErrorHandler(ErrorHandler)
|
||||
Animation.init({ ErrorHandler = ErrorHandler, Easing = Easing })
|
||||
|
||||
TestKeyframeAnimation = {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user