This commit is contained in:
Michael Freno
2025-11-19 14:42:58 -05:00
parent 32eda9ff8b
commit 8025d29ab6
3 changed files with 58 additions and 45 deletions

View File

@@ -86,7 +86,7 @@ flexlove._deferredCallbacks = {}
--- Set up FlexLove for your application's specific needs - configure responsive scaling, theming, rendering mode, and debugging tools --- Set up FlexLove for your application's specific needs - configure responsive scaling, theming, rendering mode, and debugging tools
--- Use this to establish a consistent UI foundation that adapts to different screen sizes and provides performance insights --- Use this to establish a consistent UI foundation that adapts to different screen sizes and provides performance insights
---@param config {baseScale?: {width?:number, height?:number}, theme?: string|ThemeDefinition, immediateMode?: boolean, stateRetentionFrames?: number, maxStateEntries?: number, autoFrameManagement?: boolean, errorLogFile?: string, enableErrorLogging?: boolean, performanceMonitoring?: boolean, performanceWarnings?: boolean, performanceHudKey?: string, performanceHudPosition?: {x: number, y: number} } ---@param config FlexLoveConfig?
function flexlove.init(config) function flexlove.init(config)
config = config or {} config = config or {}
@@ -100,6 +100,24 @@ function flexlove.init(config)
enableRotation = config.errorLogRotateEnabled, enableRotation = config.errorLogRotateEnabled,
}) })
flexlove._Performance = Performance.init({
enabled = config.performanceMonitoring or true,
hudEnabled = false, -- Start with HUD disabled
hudToggleKey = config.performanceHudKey or "f3",
hudPosition = config.performanceHudPosition or { x = 10, y = 10 },
warningThresholdMs = config.performanceWarningThreshold or 13.0,
criticalThresholdMs = config.performanceCriticalThreshold or 16.67,
logToConsole = config.performanceLogToConsole or false,
logWarnings = config.performanceWarnings or false,
warningsEnabled = config.performanceWarnings or false,
memoryProfiling = config.memoryProfiling or config.immediateMode and true or false,
}, { ErrorHandler = flexlove._ErrorHandler })
if config.immediateMode then
flexlove._Performance:registerTableForMonitoring("StateManager.stateStore", StateManager._getInternalState().stateStore)
flexlove._Performance:registerTableForMonitoring("StateManager.stateMetadata", StateManager._getInternalState().stateMetadata)
end
ImageRenderer.init({ ErrorHandler = flexlove._ErrorHandler }) ImageRenderer.init({ ErrorHandler = flexlove._ErrorHandler })
ImageScaler.init({ ErrorHandler = flexlove._ErrorHandler }) ImageScaler.init({ ErrorHandler = flexlove._ErrorHandler })
@@ -136,42 +154,6 @@ function flexlove.init(config)
ErrorHandler = flexlove._ErrorHandler, ErrorHandler = flexlove._ErrorHandler,
} }
local enablePerfMonitoring = config.performanceMonitoring
if enablePerfMonitoring == nil then
enablePerfMonitoring = true
end
if enablePerfMonitoring then
Performance.enable()
else
Performance.disable()
end
local enablePerfWarnings = config.performanceWarnings or true
Performance.setConfig("warningsEnabled", enablePerfWarnings)
if enablePerfWarnings then
Performance.setConfig("logWarnings", true)
end
-- Configure performance HUD toggle key (default: "f3")
if config.performanceHudKey then
Performance.setConfig("hudToggleKey", config.performanceHudKey)
end
-- Configure performance HUD position (default: {x = 10, y = 10})
if config.performanceHudPosition then
Performance.setConfig("hudPosition", config.performanceHudPosition)
end
-- Configure memory profiling (default: false)
if config.memoryProfiling then
Performance.enableMemoryProfiling()
-- Register key tables for leak detection
Performance.registerTableForMonitoring("StateManager.stateStore", StateManager._getInternalState().stateStore)
Performance.registerTableForMonitoring("StateManager.stateMetadata", StateManager._getInternalState().stateMetadata)
Performance.registerTableForMonitoring("FONT_CACHE", utils.FONT_CACHE)
end
if config.baseScale then if config.baseScale then
flexlove.baseScale = { flexlove.baseScale = {
width = config.baseScale.width or 1920, width = config.baseScale.width or 1920,
@@ -331,7 +313,7 @@ function flexlove.beginFrame()
end end
-- Start performance frame timing -- Start performance frame timing
Performance.startFrame() flexlove._Performance:startFrame()
flexlove._frameNumber = flexlove._frameNumber + 1 flexlove._frameNumber = flexlove._frameNumber + 1
StateManager.incrementFrame() StateManager.incrementFrame()
@@ -405,8 +387,8 @@ function flexlove.endFrame()
flexlove._frameStarted = false flexlove._frameStarted = false
-- End performance frame timing -- End performance frame timing
Performance.endFrame() flexlove._Performance:endFrame()
Performance.resetFrameCounters() flexlove._Performance:resetFrameCounters()
end end
flexlove._gameCanvas = nil flexlove._gameCanvas = nil
@@ -521,7 +503,7 @@ function flexlove.draw(gameDrawFunc, postDrawFunc)
end end
-- Render performance HUD if enabled -- Render performance HUD if enabled
Performance.renderHUD() flexlove._Performance:renderHUD()
love.graphics.setCanvas(outerCanvas) love.graphics.setCanvas(outerCanvas)
@@ -647,7 +629,7 @@ end
---@param dt number ---@param dt number
function flexlove.update(dt) function flexlove.update(dt)
-- Update Performance module with actual delta time for accurate FPS -- Update Performance module with actual delta time for accurate FPS
Performance.updateDeltaTime(dt) flexlove._Performance:updateDeltaTime(dt)
-- Garbage collection management -- Garbage collection management
flexlove._manageGC() flexlove._manageGC()
@@ -783,7 +765,7 @@ end
---@param isrepeat boolean ---@param isrepeat boolean
function flexlove.keypressed(key, scancode, isrepeat) function flexlove.keypressed(key, scancode, isrepeat)
-- Handle performance HUD toggle -- Handle performance HUD toggle
Performance.keypressed(key) flexlove._Performance:keypressed(key)
if flexlove._focusedElement then if flexlove._focusedElement then
flexlove._focusedElement:keypressed(key, scancode, isrepeat) flexlove._focusedElement:keypressed(key, scancode, isrepeat)
end end

View File

@@ -29,7 +29,7 @@ local METRICS_RETENTION_TIME = 10
local MAX_METRICS_COUNT = 500 local MAX_METRICS_COUNT = 500
local CORE_METRICS = { frame = true, layout = true, render = true } local CORE_METRICS = { frame = true, layout = true, render = true }
---@param config {enabled?: boolean, hudEnabled?: boolean, hudToggleKey?: string, hudPosition?: {x: number, y: number}, warningThresholdMs?: number, criticalThresholdMs?: number, logToConsole?: boolean, logWarnings?: boolean, warningsEnabled?: boolean}? ---@param config {enabled?: boolean, hudEnabled?: boolean, hudToggleKey?: string, hudPosition?: {x: number, y: number}, warningThresholdMs?: number, criticalThresholdMs?: number, logToConsole?: boolean, logWarnings?: boolean, warningsEnabled?: boolean, memoryProfiling?: boolean}?
---@param deps {ErrorHandler: ErrorHandler} ---@param deps {ErrorHandler: ErrorHandler}
---@return Performance ---@return Performance
function Performance.init(config, deps) function Performance.init(config, deps)
@@ -70,7 +70,7 @@ function Performance.init(config, deps)
self._lastFrameStart = nil self._lastFrameStart = nil
self._shownWarnings = {} self._shownWarnings = {}
self._memoryProfiler = { self._memoryProfiler = {
enabled = false, enabled = config and config.memoryProfiling or false,
sampleInterval = 60, sampleInterval = 60,
framesSinceLastSample = 0, framesSinceLastSample = 0,
samples = {}, samples = {},

View File

@@ -155,3 +155,34 @@ local Border = {}
---@field originX number? Transform origin X (0-1, default: 0.5) ---@field originX number? Transform origin X (0-1, default: 0.5)
---@field originY number? Transform origin Y (0-1, default: 0.5) ---@field originY number? Transform origin Y (0-1, default: 0.5)
local TransformProps local TransformProps
--=====================================--
-- For FlexLove.init()
--=====================================--
---@class FlexLoveConfig
---@field baseScale {width:number?, height:number?}? -- Base resolution for responsive scaling (default: nil, no scaling)
---@field theme string|table? -- Theme name (string) or ThemeDefinition (table) to use (default: nil, no theme)
---@field immediateMode boolean? -- Enable immediate mode (React-like, recreates UI each frame) vs retained mode (default: false)
---@field autoFrameManagement boolean? -- Automatically call beginFrame/endFrame (default: false)
---@field stateRetentionFrames number? -- Number of frames to retain unused state in immediate mode (default: 60)
---@field maxStateEntries number? -- Maximum number of state entries before forcing cleanup (default: 1000)
---@field includeStackTrace boolean? -- Include stack traces in error messages (default: true)
---@field reportingLogLevel LOG_LEVEL? -- Error log level: 1: critical, 2: error, 3: warn, 4: info, 5: debug/all (default: 3:warn)
---@field errorLogTarget string? -- Error log target: "console", "file", "both" (default: "console")
---@field errorLogFile string? -- Path to error log file (default: "flexlove_errors.log")
---@field errorLogMaxSize number? -- Maximum error log file size in bytes (default: 1048576, 1MB)
---@field maxErrorLogFiles number? -- Maximum number of rotated error log files (default: 5)
---@field errorLogRotateEnabled boolean? -- Enable error log rotation (default: true)
---@field performanceMonitoring boolean? -- Enable performance monitoring (default: true)
---@field performanceHudKey string? -- Key to toggle performance HUD (default: "f3")
---@field performanceHudPosition {x:number, y:number}? -- Position of performance HUD (default: {x=10, y=10})
---@field performanceWarningThreshold number? -- Frame time warning threshold in ms (default: 13.0)
---@field performanceCriticalThreshold number? -- Frame time critical threshold in ms (default: 16.67)
---@field performanceLogToConsole boolean? -- Log performance metrics to console (default: false)
---@field performanceWarnings boolean? -- Enable performance warnings (default: false)
---@field memoryProfiling boolean? -- Enable memory profiling (default: false, auto-enabled in immediate mode)
---@field gcStrategy string? -- Garbage collection strategy: "auto", "periodic", "manual", "disabled" (default: "auto")
---@field gcMemoryThreshold number? -- Memory threshold in MB before forcing GC (default: 100)
---@field gcInterval number? -- Frames between GC steps in periodic mode (default: 60)
---@field gcStepSize number? -- Work units per GC step, higher = more aggressive (default: 200)
local FlexLoveConfig = {}