fixing test, making profiling
This commit is contained in:
220
profiling/__profiles__/animation_stress_profile.lua
Normal file
220
profiling/__profiles__/animation_stress_profile.lua
Normal file
@@ -0,0 +1,220 @@
|
||||
-- Animation Stress Profile
|
||||
-- Tests animation system with many concurrent animations
|
||||
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
local profile = {
|
||||
animationCount = 100,
|
||||
maxAnimations = 1000,
|
||||
minAnimations = 10,
|
||||
root = nil,
|
||||
animations = {},
|
||||
elements = {},
|
||||
easingFunctions = {
|
||||
"linear",
|
||||
"easeInQuad",
|
||||
"easeOutQuad",
|
||||
"easeInOutQuad",
|
||||
"easeInCubic",
|
||||
"easeOutCubic",
|
||||
"easeInOutCubic",
|
||||
},
|
||||
}
|
||||
|
||||
function profile.init()
|
||||
FlexLove.init({
|
||||
width = love.graphics.getWidth(),
|
||||
height = love.graphics.getHeight(),
|
||||
})
|
||||
|
||||
profile.buildLayout()
|
||||
end
|
||||
|
||||
function profile.buildLayout()
|
||||
profile.root = FlexLove.new({
|
||||
width = "100%",
|
||||
height = "100%",
|
||||
backgroundColor = {0.05, 0.05, 0.1, 1},
|
||||
flexDirection = "column",
|
||||
overflow = "scroll",
|
||||
padding = 20,
|
||||
gap = 10,
|
||||
})
|
||||
|
||||
-- Create animated elements container
|
||||
local animationContainer = FlexLove.new({
|
||||
width = "100%",
|
||||
flexDirection = "row",
|
||||
flexWrap = "wrap",
|
||||
gap = 10,
|
||||
marginBottom = 20,
|
||||
})
|
||||
|
||||
profile.animations = {}
|
||||
profile.elements = {}
|
||||
|
||||
for i = 1, profile.animationCount do
|
||||
local hue = (i / profile.animationCount) * 360
|
||||
local baseColor = {
|
||||
0.3 + 0.5 * math.sin(hue * math.pi / 180),
|
||||
0.3 + 0.5 * math.sin((hue + 120) * math.pi / 180),
|
||||
0.3 + 0.5 * math.sin((hue + 240) * math.pi / 180),
|
||||
1
|
||||
}
|
||||
|
||||
-- Choose random easing function
|
||||
local easingFunc = profile.easingFunctions[math.random(#profile.easingFunctions)]
|
||||
|
||||
local box = FlexLove.new({
|
||||
width = 60,
|
||||
height = 60,
|
||||
backgroundColor = baseColor,
|
||||
borderRadius = 8,
|
||||
margin = 5,
|
||||
})
|
||||
|
||||
-- Store base values for animation
|
||||
box._baseY = box.y
|
||||
box._baseOpacity = 1
|
||||
box._baseBorderRadius = 8
|
||||
box._baseColor = baseColor
|
||||
|
||||
-- Create animations manually since elements may not support automatic animation
|
||||
local animDuration = 1 + math.random() * 2 -- 1-3 seconds
|
||||
|
||||
-- Y position animation
|
||||
local yAnim = FlexLove.Animation.new({
|
||||
duration = animDuration,
|
||||
start = { offset = 0 },
|
||||
final = { offset = 20 + math.random() * 40 },
|
||||
easing = easingFunc,
|
||||
}):yoyo(true):repeatCount(0) -- 0 = infinite loop
|
||||
|
||||
-- Opacity animation
|
||||
local opacityAnim = FlexLove.Animation.new({
|
||||
duration = animDuration * 0.8,
|
||||
start = { opacity = 1 },
|
||||
final = { opacity = 0.3 },
|
||||
easing = easingFunc,
|
||||
}):yoyo(true):repeatCount(0)
|
||||
|
||||
-- Border radius animation
|
||||
local radiusAnim = FlexLove.Animation.new({
|
||||
duration = animDuration * 1.2,
|
||||
start = { borderRadius = 8 },
|
||||
final = { borderRadius = 30 },
|
||||
easing = easingFunc,
|
||||
}):yoyo(true):repeatCount(0)
|
||||
|
||||
-- Store animations with element reference
|
||||
table.insert(profile.animations, { element = box, animation = yAnim, property = "y" })
|
||||
table.insert(profile.animations, { element = box, animation = opacityAnim, property = "opacity" })
|
||||
table.insert(profile.animations, { element = box, animation = radiusAnim, property = "borderRadius" })
|
||||
|
||||
table.insert(profile.elements, box)
|
||||
animationContainer:addChild(box)
|
||||
end
|
||||
|
||||
profile.root:addChild(animationContainer)
|
||||
|
||||
-- Info panel
|
||||
local infoPanel = FlexLove.new({
|
||||
width = "100%",
|
||||
padding = 15,
|
||||
backgroundColor = {0.1, 0.1, 0.2, 0.9},
|
||||
borderRadius = 8,
|
||||
flexDirection = "column",
|
||||
gap = 5,
|
||||
})
|
||||
|
||||
infoPanel:addChild(FlexLove.new({
|
||||
textContent = string.format("Animated Elements: %d (Press +/- to adjust)", profile.animationCount),
|
||||
fontSize = 18,
|
||||
color = {1, 1, 1, 1},
|
||||
}))
|
||||
|
||||
infoPanel:addChild(FlexLove.new({
|
||||
textContent = string.format("Active Animations: %d", #profile.animations),
|
||||
fontSize = 14,
|
||||
color = {0.8, 0.8, 0.8, 1},
|
||||
}))
|
||||
|
||||
infoPanel:addChild(FlexLove.new({
|
||||
textContent = "Animating: position, opacity, borderRadius",
|
||||
fontSize = 14,
|
||||
color = {0.8, 0.8, 0.8, 1},
|
||||
}))
|
||||
|
||||
infoPanel:addChild(FlexLove.new({
|
||||
textContent = string.format("Easing Functions: %d variations", #profile.easingFunctions),
|
||||
fontSize = 14,
|
||||
color = {0.8, 0.8, 0.8, 1},
|
||||
}))
|
||||
|
||||
profile.root:addChild(infoPanel)
|
||||
end
|
||||
|
||||
function profile.update(dt)
|
||||
-- Update all animations and apply to elements
|
||||
for _, animData in ipairs(profile.animations) do
|
||||
animData.animation:update(dt)
|
||||
local values = animData.animation:interpolate()
|
||||
|
||||
if animData.property == "y" and values.offset then
|
||||
animData.element.y = (animData.element._baseY or animData.element.y) + values.offset
|
||||
elseif animData.property == "opacity" and values.opacity then
|
||||
animData.element.opacity = values.opacity
|
||||
elseif animData.property == "borderRadius" and values.borderRadius then
|
||||
animData.element.borderRadius = values.borderRadius
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function profile.draw()
|
||||
if profile.root then
|
||||
profile.root:draw()
|
||||
end
|
||||
|
||||
-- Overlay info
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
love.graphics.print("Animation Stress Test", 10, love.graphics.getHeight() - 100)
|
||||
love.graphics.print(
|
||||
string.format("Animations: %d | Range: %d-%d",
|
||||
#profile.animations,
|
||||
profile.minAnimations * 3,
|
||||
profile.maxAnimations * 3
|
||||
),
|
||||
10,
|
||||
love.graphics.getHeight() - 80
|
||||
)
|
||||
love.graphics.print("Press + to add 10 animated elements", 10, love.graphics.getHeight() - 60)
|
||||
love.graphics.print("Press - to remove 10 animated elements", 10, love.graphics.getHeight() - 45)
|
||||
end
|
||||
|
||||
function profile.keypressed(key)
|
||||
if key == "=" or key == "+" then
|
||||
profile.animationCount = math.min(profile.maxAnimations, profile.animationCount + 10)
|
||||
profile.buildLayout()
|
||||
elseif key == "-" or key == "_" then
|
||||
profile.animationCount = math.max(profile.minAnimations, profile.animationCount - 10)
|
||||
profile.buildLayout()
|
||||
end
|
||||
end
|
||||
|
||||
function profile.resize(w, h)
|
||||
FlexLove.resize(w, h)
|
||||
profile.buildLayout()
|
||||
end
|
||||
|
||||
function profile.reset()
|
||||
profile.animationCount = 100
|
||||
profile.buildLayout()
|
||||
end
|
||||
|
||||
function profile.cleanup()
|
||||
profile.animations = {}
|
||||
profile.elements = {}
|
||||
profile.root = nil
|
||||
end
|
||||
|
||||
return profile
|
||||
219
profiling/__profiles__/event_stress_profile.lua
Normal file
219
profiling/__profiles__/event_stress_profile.lua
Normal file
@@ -0,0 +1,219 @@
|
||||
-- Event Stress Profile
|
||||
-- Tests event handling at scale
|
||||
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
local profile = {
|
||||
elementCount = 200,
|
||||
maxElements = 1000,
|
||||
minElements = 50,
|
||||
root = nil,
|
||||
eventMetrics = {
|
||||
hoverCount = 0,
|
||||
clickCount = 0,
|
||||
eventsThisFrame = 0,
|
||||
},
|
||||
metricsTimer = 0,
|
||||
}
|
||||
|
||||
function profile.init()
|
||||
FlexLove.init({
|
||||
width = love.graphics.getWidth(),
|
||||
height = love.graphics.getHeight(),
|
||||
})
|
||||
|
||||
profile.buildLayout()
|
||||
end
|
||||
|
||||
function profile.buildLayout()
|
||||
profile.root = FlexLove.new({
|
||||
width = "100%",
|
||||
height = "100%",
|
||||
backgroundColor = {0.05, 0.05, 0.1, 1},
|
||||
flexDirection = "column",
|
||||
overflow = "scroll",
|
||||
padding = 20,
|
||||
gap = 10,
|
||||
})
|
||||
|
||||
-- Interactive elements container
|
||||
local interactiveContainer = FlexLove.new({
|
||||
width = "100%",
|
||||
flexDirection = "row",
|
||||
flexWrap = "wrap",
|
||||
gap = 5,
|
||||
marginBottom = 20,
|
||||
})
|
||||
|
||||
for i = 1, profile.elementCount do
|
||||
local hue = (i / profile.elementCount) * 360
|
||||
local baseColor = {
|
||||
0.3 + 0.5 * math.sin(hue * math.pi / 180),
|
||||
0.3 + 0.5 * math.sin((hue + 120) * math.pi / 180),
|
||||
0.3 + 0.5 * math.sin((hue + 240) * math.pi / 180),
|
||||
1
|
||||
}
|
||||
|
||||
-- Create nested interactive hierarchy
|
||||
local outerBox = FlexLove.new({
|
||||
width = 60,
|
||||
height = 60,
|
||||
backgroundColor = baseColor,
|
||||
borderRadius = 8,
|
||||
margin = 2,
|
||||
justifyContent = "center",
|
||||
alignItems = "center",
|
||||
onEvent = function(element, event)
|
||||
if event.type == "hover" then
|
||||
profile.eventMetrics.hoverCount = profile.eventMetrics.hoverCount + 1
|
||||
profile.eventMetrics.eventsThisFrame = profile.eventMetrics.eventsThisFrame + 1
|
||||
element.backgroundColor = {
|
||||
math.min(1, baseColor[1] * 1.3),
|
||||
math.min(1, baseColor[2] * 1.3),
|
||||
math.min(1, baseColor[3] * 1.3),
|
||||
1
|
||||
}
|
||||
elseif event.type == "unhover" then
|
||||
element.backgroundColor = baseColor
|
||||
elseif event.type == "press" then
|
||||
element.borderRadius = 15
|
||||
elseif event.type == "release" then
|
||||
profile.eventMetrics.clickCount = profile.eventMetrics.clickCount + 1
|
||||
profile.eventMetrics.eventsThisFrame = profile.eventMetrics.eventsThisFrame + 1
|
||||
element.borderRadius = 8
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-- Add nested button for event propagation testing
|
||||
local innerBox = FlexLove.new({
|
||||
width = "60%",
|
||||
height = "60%",
|
||||
backgroundColor = {baseColor[1] * 0.6, baseColor[2] * 0.6, baseColor[3] * 0.6, 1},
|
||||
borderRadius = 5,
|
||||
onEvent = function(element, event)
|
||||
if event.type == "hover" then
|
||||
profile.eventMetrics.eventsThisFrame = profile.eventMetrics.eventsThisFrame + 1
|
||||
element.backgroundColor = {
|
||||
math.min(1, baseColor[1] * 1.5),
|
||||
math.min(1, baseColor[2] * 1.5),
|
||||
math.min(1, baseColor[3] * 1.5),
|
||||
1
|
||||
}
|
||||
elseif event.type == "unhover" then
|
||||
element.backgroundColor = {baseColor[1] * 0.6, baseColor[2] * 0.6, baseColor[3] * 0.6, 1}
|
||||
elseif event.type == "release" then
|
||||
profile.eventMetrics.eventsThisFrame = profile.eventMetrics.eventsThisFrame + 1
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
outerBox:addChild(innerBox)
|
||||
interactiveContainer:addChild(outerBox)
|
||||
end
|
||||
|
||||
profile.root:addChild(interactiveContainer)
|
||||
|
||||
-- Metrics panel
|
||||
local metricsPanel = FlexLove.new({
|
||||
width = "100%",
|
||||
padding = 15,
|
||||
backgroundColor = {0.1, 0.1, 0.2, 0.9},
|
||||
borderRadius = 8,
|
||||
flexDirection = "column",
|
||||
gap = 5,
|
||||
})
|
||||
|
||||
metricsPanel:addChild(FlexLove.new({
|
||||
textContent = string.format("Interactive Elements: %d (Press +/- to adjust)", profile.elementCount),
|
||||
fontSize = 18,
|
||||
color = {1, 1, 1, 1},
|
||||
}))
|
||||
|
||||
metricsPanel:addChild(FlexLove.new({
|
||||
textContent = string.format("Total Hovers: %d", profile.eventMetrics.hoverCount),
|
||||
fontSize = 14,
|
||||
color = {0.8, 0.8, 0.8, 1},
|
||||
}))
|
||||
|
||||
metricsPanel:addChild(FlexLove.new({
|
||||
textContent = string.format("Total Clicks: %d", profile.eventMetrics.clickCount),
|
||||
fontSize = 14,
|
||||
color = {0.8, 0.8, 0.8, 1},
|
||||
}))
|
||||
|
||||
metricsPanel:addChild(FlexLove.new({
|
||||
textContent = string.format("Events/Frame: %d", profile.eventMetrics.eventsThisFrame),
|
||||
fontSize = 14,
|
||||
color = {0.8, 0.8, 0.8, 1},
|
||||
}))
|
||||
|
||||
profile.root:addChild(metricsPanel)
|
||||
end
|
||||
|
||||
function profile.update(dt)
|
||||
-- Reset per-frame event counter
|
||||
profile.metricsTimer = profile.metricsTimer + dt
|
||||
if profile.metricsTimer >= 0.1 then -- Update metrics display every 100ms
|
||||
profile.eventMetrics.eventsThisFrame = 0
|
||||
profile.metricsTimer = 0
|
||||
-- Rebuild to update metrics display
|
||||
if profile.root then
|
||||
profile.buildLayout()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function profile.draw()
|
||||
if profile.root then
|
||||
profile.root:draw()
|
||||
end
|
||||
|
||||
-- Overlay info
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
love.graphics.print("Event Stress Test", 10, love.graphics.getHeight() - 120)
|
||||
love.graphics.print(
|
||||
string.format("Elements: %d | Range: %d-%d",
|
||||
profile.elementCount,
|
||||
profile.minElements,
|
||||
profile.maxElements
|
||||
),
|
||||
10,
|
||||
love.graphics.getHeight() - 100
|
||||
)
|
||||
love.graphics.print("Press + to add 25 interactive elements", 10, love.graphics.getHeight() - 80)
|
||||
love.graphics.print("Press - to remove 25 interactive elements", 10, love.graphics.getHeight() - 65)
|
||||
love.graphics.print("Hover and click elements to test event handling", 10, love.graphics.getHeight() - 50)
|
||||
end
|
||||
|
||||
function profile.keypressed(key)
|
||||
if key == "=" or key == "+" then
|
||||
profile.elementCount = math.min(profile.maxElements, profile.elementCount + 25)
|
||||
profile.buildLayout()
|
||||
elseif key == "-" or key == "_" then
|
||||
profile.elementCount = math.max(profile.minElements, profile.elementCount - 25)
|
||||
profile.buildLayout()
|
||||
end
|
||||
end
|
||||
|
||||
function profile.resize(w, h)
|
||||
FlexLove.resize(w, h)
|
||||
profile.buildLayout()
|
||||
end
|
||||
|
||||
function profile.reset()
|
||||
profile.elementCount = 200
|
||||
profile.eventMetrics = {
|
||||
hoverCount = 0,
|
||||
clickCount = 0,
|
||||
eventsThisFrame = 0,
|
||||
}
|
||||
profile.metricsTimer = 0
|
||||
profile.buildLayout()
|
||||
end
|
||||
|
||||
function profile.cleanup()
|
||||
profile.root = nil
|
||||
end
|
||||
|
||||
return profile
|
||||
189
profiling/__profiles__/immediate_mode_profile.lua
Normal file
189
profiling/__profiles__/immediate_mode_profile.lua
Normal file
@@ -0,0 +1,189 @@
|
||||
-- Immediate Mode Profile
|
||||
-- Tests immediate mode where UI recreates each frame
|
||||
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
local profile = {
|
||||
elementCount = 50,
|
||||
maxElements = 300,
|
||||
minElements = 10,
|
||||
frameCount = 0,
|
||||
}
|
||||
|
||||
function profile.init()
|
||||
FlexLove.init({
|
||||
width = love.graphics.getWidth(),
|
||||
height = love.graphics.getHeight(),
|
||||
immediateMode = true,
|
||||
})
|
||||
end
|
||||
|
||||
function profile.buildUI()
|
||||
-- In immediate mode, we recreate the UI every frame
|
||||
local root = FlexLove.new({
|
||||
id = "root", -- ID required for state persistence
|
||||
width = "100%",
|
||||
height = "100%",
|
||||
backgroundColor = {0.05, 0.05, 0.1, 1},
|
||||
flexDirection = "column",
|
||||
overflow = "scroll",
|
||||
padding = 20,
|
||||
gap = 10,
|
||||
})
|
||||
|
||||
-- Dynamic content container
|
||||
local content = FlexLove.new({
|
||||
id = "content",
|
||||
width = "100%",
|
||||
flexDirection = "row",
|
||||
flexWrap = "wrap",
|
||||
gap = 5,
|
||||
marginBottom = 20,
|
||||
})
|
||||
|
||||
for i = 1, profile.elementCount do
|
||||
local hue = (i / profile.elementCount) * 360
|
||||
local baseColor = {
|
||||
0.3 + 0.5 * math.sin(hue * math.pi / 180),
|
||||
0.3 + 0.5 * math.sin((hue + 120) * math.pi / 180),
|
||||
0.3 + 0.5 * math.sin((hue + 240) * math.pi / 180),
|
||||
1
|
||||
}
|
||||
|
||||
-- Each element needs a unique ID for state persistence
|
||||
local box = FlexLove.new({
|
||||
id = string.format("box_%d", i),
|
||||
width = 60,
|
||||
height = 60,
|
||||
backgroundColor = baseColor,
|
||||
borderRadius = 8,
|
||||
margin = 2,
|
||||
onEvent = function(element, event)
|
||||
if event.type == "hover" then
|
||||
element.backgroundColor = {
|
||||
math.min(1, baseColor[1] * 1.3),
|
||||
math.min(1, baseColor[2] * 1.3),
|
||||
math.min(1, baseColor[3] * 1.3),
|
||||
1
|
||||
}
|
||||
elseif event.type == "unhover" then
|
||||
element.backgroundColor = baseColor
|
||||
elseif event.type == "press" then
|
||||
element.borderRadius = 15
|
||||
elseif event.type == "release" then
|
||||
element.borderRadius = 8
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
content:addChild(box)
|
||||
end
|
||||
|
||||
root:addChild(content)
|
||||
|
||||
-- Info panel (also recreated each frame)
|
||||
local infoPanel = FlexLove.new({
|
||||
id = "infoPanel",
|
||||
width = "100%",
|
||||
padding = 15,
|
||||
backgroundColor = {0.1, 0.1, 0.2, 0.9},
|
||||
borderRadius = 8,
|
||||
flexDirection = "column",
|
||||
gap = 5,
|
||||
})
|
||||
|
||||
infoPanel:addChild(FlexLove.new({
|
||||
id = "info_title",
|
||||
textContent = string.format("Immediate Mode: %d Elements", profile.elementCount),
|
||||
fontSize = 18,
|
||||
color = {1, 1, 1, 1},
|
||||
}))
|
||||
|
||||
infoPanel:addChild(FlexLove.new({
|
||||
id = "info_frame",
|
||||
textContent = string.format("Frame: %d", profile.frameCount),
|
||||
fontSize = 14,
|
||||
color = {0.8, 0.8, 0.8, 1},
|
||||
}))
|
||||
|
||||
infoPanel:addChild(FlexLove.new({
|
||||
id = "info_states",
|
||||
textContent = string.format("Active States: %d", FlexLove.getStateCount()),
|
||||
fontSize = 14,
|
||||
color = {0.8, 0.8, 0.8, 1},
|
||||
}))
|
||||
|
||||
infoPanel:addChild(FlexLove.new({
|
||||
id = "info_help",
|
||||
textContent = "Press +/- to adjust element count",
|
||||
fontSize = 12,
|
||||
color = {0.7, 0.7, 0.7, 1},
|
||||
}))
|
||||
|
||||
root:addChild(infoPanel)
|
||||
|
||||
return root
|
||||
end
|
||||
|
||||
function profile.update(dt)
|
||||
profile.frameCount = profile.frameCount + 1
|
||||
end
|
||||
|
||||
function profile.draw()
|
||||
-- Immediate mode: rebuild UI every frame
|
||||
FlexLove.beginFrame()
|
||||
local root = profile.buildUI()
|
||||
FlexLove.endFrame()
|
||||
|
||||
-- Draw the UI
|
||||
if root then
|
||||
root:draw()
|
||||
end
|
||||
|
||||
-- Overlay info
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
love.graphics.print("Immediate Mode Stress Test", 10, love.graphics.getHeight() - 120)
|
||||
love.graphics.print(
|
||||
string.format("Elements: %d | Range: %d-%d",
|
||||
profile.elementCount,
|
||||
profile.minElements,
|
||||
profile.maxElements
|
||||
),
|
||||
10,
|
||||
love.graphics.getHeight() - 100
|
||||
)
|
||||
love.graphics.print(
|
||||
string.format("Frames: %d | States: %d",
|
||||
profile.frameCount,
|
||||
FlexLove.getStateCount()
|
||||
),
|
||||
10,
|
||||
love.graphics.getHeight() - 80
|
||||
)
|
||||
love.graphics.print("Press + to add 10 elements", 10, love.graphics.getHeight() - 60)
|
||||
love.graphics.print("Press - to remove 10 elements", 10, love.graphics.getHeight() - 45)
|
||||
end
|
||||
|
||||
function profile.keypressed(key)
|
||||
if key == "=" or key == "+" then
|
||||
profile.elementCount = math.min(profile.maxElements, profile.elementCount + 10)
|
||||
elseif key == "-" or key == "_" then
|
||||
profile.elementCount = math.max(profile.minElements, profile.elementCount - 10)
|
||||
end
|
||||
end
|
||||
|
||||
function profile.resize(w, h)
|
||||
FlexLove.resize(w, h)
|
||||
end
|
||||
|
||||
function profile.reset()
|
||||
profile.elementCount = 50
|
||||
profile.frameCount = 0
|
||||
FlexLove.clearAllStates()
|
||||
end
|
||||
|
||||
function profile.cleanup()
|
||||
FlexLove.clearAllStates()
|
||||
end
|
||||
|
||||
return profile
|
||||
149
profiling/__profiles__/layout_stress_profile.lua
Normal file
149
profiling/__profiles__/layout_stress_profile.lua
Normal file
@@ -0,0 +1,149 @@
|
||||
-- Layout Stress Profile
|
||||
-- Tests layout engine performance with large element hierarchies
|
||||
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
local profile = {
|
||||
elementCount = 100,
|
||||
maxElements = 5000,
|
||||
nestingDepth = 5,
|
||||
root = nil,
|
||||
}
|
||||
|
||||
function profile.init()
|
||||
FlexLove.init({
|
||||
width = love.graphics.getWidth(),
|
||||
height = love.graphics.getHeight(),
|
||||
})
|
||||
|
||||
profile.buildLayout()
|
||||
end
|
||||
|
||||
function profile.buildLayout()
|
||||
local width = love.graphics.getWidth()
|
||||
local height = love.graphics.getHeight()
|
||||
|
||||
profile.root = FlexLove.new({
|
||||
width = "100%",
|
||||
height = "100%",
|
||||
backgroundColor = {0.05, 0.05, 0.1, 1},
|
||||
flexDirection = "column",
|
||||
overflow = "scroll",
|
||||
padding = 20,
|
||||
gap = 10,
|
||||
})
|
||||
|
||||
local elementsPerRow = math.floor(math.sqrt(profile.elementCount))
|
||||
local rows = math.ceil(profile.elementCount / elementsPerRow)
|
||||
|
||||
for r = 1, rows do
|
||||
local row = FlexLove.new({
|
||||
flexDirection = "row",
|
||||
gap = 10,
|
||||
flexWrap = "wrap",
|
||||
})
|
||||
|
||||
local itemsInRow = math.min(elementsPerRow, profile.elementCount - (r - 1) * elementsPerRow)
|
||||
for c = 1, itemsInRow do
|
||||
local hue = ((r - 1) * elementsPerRow + c) / profile.elementCount
|
||||
local color = {
|
||||
0.3 + 0.5 * math.sin(hue * math.pi * 2),
|
||||
0.3 + 0.5 * math.sin((hue + 0.33) * math.pi * 2),
|
||||
0.3 + 0.5 * math.sin((hue + 0.66) * math.pi * 2),
|
||||
1
|
||||
}
|
||||
|
||||
local box = FlexLove.new({
|
||||
width = 80,
|
||||
height = 80,
|
||||
backgroundColor = color,
|
||||
borderRadius = 8,
|
||||
justifyContent = "center",
|
||||
alignItems = "center",
|
||||
})
|
||||
|
||||
local nested = box
|
||||
for d = 1, math.min(profile.nestingDepth, 3) do
|
||||
local innerBox = FlexLove.new({
|
||||
width = "80%",
|
||||
height = "80%",
|
||||
backgroundColor = {color[1] * 0.8, color[2] * 0.8, color[3] * 0.8, color[4]},
|
||||
borderRadius = 6,
|
||||
justifyContent = "center",
|
||||
alignItems = "center",
|
||||
})
|
||||
nested:addChild(innerBox)
|
||||
nested = innerBox
|
||||
end
|
||||
|
||||
row:addChild(box)
|
||||
end
|
||||
|
||||
profile.root:addChild(row)
|
||||
end
|
||||
|
||||
local infoPanel = FlexLove.new({
|
||||
width = "100%",
|
||||
padding = 15,
|
||||
backgroundColor = {0.1, 0.1, 0.2, 0.9},
|
||||
borderRadius = 8,
|
||||
marginTop = 20,
|
||||
flexDirection = "column",
|
||||
gap = 5,
|
||||
})
|
||||
|
||||
infoPanel:addChild(FlexLove.new({
|
||||
textContent = string.format("Elements: %d (Press +/- to adjust)", profile.elementCount),
|
||||
fontSize = 18,
|
||||
color = {1, 1, 1, 1},
|
||||
}))
|
||||
|
||||
infoPanel:addChild(FlexLove.new({
|
||||
textContent = string.format("Nesting Depth: %d", profile.nestingDepth),
|
||||
fontSize = 14,
|
||||
color = {0.8, 0.8, 0.8, 1},
|
||||
}))
|
||||
|
||||
profile.root:addChild(infoPanel)
|
||||
end
|
||||
|
||||
function profile.update(dt)
|
||||
end
|
||||
|
||||
function profile.draw()
|
||||
if profile.root then
|
||||
profile.root:draw()
|
||||
end
|
||||
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
love.graphics.print("Layout Stress Test", 10, love.graphics.getHeight() - 100)
|
||||
love.graphics.print(string.format("Elements: %d | Max: %d", profile.elementCount, profile.maxElements), 10, love.graphics.getHeight() - 80)
|
||||
love.graphics.print("Press + to add 50 elements", 10, love.graphics.getHeight() - 60)
|
||||
love.graphics.print("Press - to remove 50 elements", 10, love.graphics.getHeight() - 45)
|
||||
end
|
||||
|
||||
function profile.keypressed(key)
|
||||
if key == "=" or key == "+" then
|
||||
profile.elementCount = math.min(profile.maxElements, profile.elementCount + 50)
|
||||
profile.buildLayout()
|
||||
elseif key == "-" or key == "_" then
|
||||
profile.elementCount = math.max(10, profile.elementCount - 50)
|
||||
profile.buildLayout()
|
||||
end
|
||||
end
|
||||
|
||||
function profile.resize(w, h)
|
||||
FlexLove.resize(w, h)
|
||||
profile.buildLayout()
|
||||
end
|
||||
|
||||
function profile.reset()
|
||||
profile.elementCount = 100
|
||||
profile.buildLayout()
|
||||
end
|
||||
|
||||
function profile.cleanup()
|
||||
profile.root = nil
|
||||
end
|
||||
|
||||
return profile
|
||||
239
profiling/__profiles__/memory_profile.lua
Normal file
239
profiling/__profiles__/memory_profile.lua
Normal file
@@ -0,0 +1,239 @@
|
||||
-- Memory Profile
|
||||
-- Tests memory usage and GC patterns
|
||||
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
local profile = {
|
||||
elementCount = 100,
|
||||
maxElements = 500,
|
||||
minElements = 50,
|
||||
root = nil,
|
||||
memoryStats = {
|
||||
startMemory = 0,
|
||||
currentMemory = 0,
|
||||
peakMemory = 0,
|
||||
gcCount = 0,
|
||||
lastGCTime = 0,
|
||||
},
|
||||
updateTimer = 0,
|
||||
createDestroyTimer = 0,
|
||||
createDestroyInterval = 2, -- seconds between create/destroy cycles
|
||||
}
|
||||
|
||||
function profile.init()
|
||||
FlexLove.init({
|
||||
width = love.graphics.getWidth(),
|
||||
height = love.graphics.getHeight(),
|
||||
gcStrategy = "manual", -- Manual GC for testing
|
||||
})
|
||||
|
||||
-- Record starting memory
|
||||
collectgarbage("collect")
|
||||
collectgarbage("collect")
|
||||
profile.memoryStats.startMemory = collectgarbage("count") / 1024 -- MB
|
||||
profile.memoryStats.peakMemory = profile.memoryStats.startMemory
|
||||
|
||||
profile.buildLayout()
|
||||
end
|
||||
|
||||
function profile.buildLayout()
|
||||
-- Clear existing root
|
||||
if profile.root then
|
||||
profile.root = nil
|
||||
end
|
||||
|
||||
profile.root = FlexLove.new({
|
||||
width = "100%",
|
||||
height = "100%",
|
||||
backgroundColor = {0.05, 0.05, 0.1, 1},
|
||||
flexDirection = "column",
|
||||
overflow = "scroll",
|
||||
padding = 20,
|
||||
gap = 10,
|
||||
})
|
||||
|
||||
-- Create elements container
|
||||
local elementsContainer = FlexLove.new({
|
||||
width = "100%",
|
||||
flexDirection = "row",
|
||||
flexWrap = "wrap",
|
||||
gap = 5,
|
||||
marginBottom = 20,
|
||||
})
|
||||
|
||||
for i = 1, profile.elementCount do
|
||||
local hue = (i / profile.elementCount) * 360
|
||||
local color = {
|
||||
0.3 + 0.5 * math.sin(hue * math.pi / 180),
|
||||
0.3 + 0.5 * math.sin((hue + 120) * math.pi / 180),
|
||||
0.3 + 0.5 * math.sin((hue + 240) * math.pi / 180),
|
||||
1
|
||||
}
|
||||
|
||||
local box = FlexLove.new({
|
||||
width = 50,
|
||||
height = 50,
|
||||
backgroundColor = color,
|
||||
borderRadius = 8,
|
||||
margin = 2,
|
||||
})
|
||||
|
||||
elementsContainer:addChild(box)
|
||||
end
|
||||
|
||||
profile.root:addChild(elementsContainer)
|
||||
|
||||
-- Memory stats panel
|
||||
local statsPanel = FlexLove.new({
|
||||
width = "100%",
|
||||
padding = 15,
|
||||
backgroundColor = {0.1, 0.1, 0.2, 0.9},
|
||||
borderRadius = 8,
|
||||
flexDirection = "column",
|
||||
gap = 5,
|
||||
})
|
||||
|
||||
local currentMem = collectgarbage("count") / 1024
|
||||
local memGrowth = currentMem - profile.memoryStats.startMemory
|
||||
|
||||
statsPanel:addChild(FlexLove.new({
|
||||
textContent = string.format("Memory Profile | Elements: %d", profile.elementCount),
|
||||
fontSize = 18,
|
||||
color = {1, 1, 1, 1},
|
||||
}))
|
||||
|
||||
statsPanel:addChild(FlexLove.new({
|
||||
textContent = string.format("Current: %.2f MB | Peak: %.2f MB", currentMem, profile.memoryStats.peakMemory),
|
||||
fontSize = 14,
|
||||
color = {0.8, 0.8, 0.8, 1},
|
||||
}))
|
||||
|
||||
statsPanel:addChild(FlexLove.new({
|
||||
textContent = string.format("Growth: %.2f MB | GC Count: %d", memGrowth, profile.memoryStats.gcCount),
|
||||
fontSize = 14,
|
||||
color = {0.8, 0.8, 0.8, 1},
|
||||
}))
|
||||
|
||||
statsPanel:addChild(FlexLove.new({
|
||||
textContent = "Press G to force GC | Press +/- to adjust elements",
|
||||
fontSize = 12,
|
||||
color = {0.7, 0.7, 0.7, 1},
|
||||
}))
|
||||
|
||||
profile.root:addChild(statsPanel)
|
||||
end
|
||||
|
||||
function profile.update(dt)
|
||||
profile.updateTimer = profile.updateTimer + dt
|
||||
profile.createDestroyTimer = profile.createDestroyTimer + dt
|
||||
|
||||
-- Update memory stats every 0.5 seconds
|
||||
if profile.updateTimer >= 0.5 then
|
||||
profile.updateTimer = 0
|
||||
profile.memoryStats.currentMemory = collectgarbage("count") / 1024
|
||||
|
||||
if profile.memoryStats.currentMemory > profile.memoryStats.peakMemory then
|
||||
profile.memoryStats.peakMemory = profile.memoryStats.currentMemory
|
||||
end
|
||||
|
||||
-- Rebuild to update stats display
|
||||
profile.buildLayout()
|
||||
end
|
||||
|
||||
-- Automatically create and destroy elements to stress GC
|
||||
if profile.createDestroyTimer >= profile.createDestroyInterval then
|
||||
profile.createDestroyTimer = 0
|
||||
|
||||
-- Destroy old elements
|
||||
profile.root = nil
|
||||
|
||||
-- Create new elements
|
||||
profile.buildLayout()
|
||||
end
|
||||
end
|
||||
|
||||
function profile.draw()
|
||||
if profile.root then
|
||||
profile.root:draw()
|
||||
end
|
||||
|
||||
-- Overlay info
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
love.graphics.print("Memory Stress Test", 10, love.graphics.getHeight() - 140)
|
||||
love.graphics.print(
|
||||
string.format("Elements: %d | Range: %d-%d",
|
||||
profile.elementCount,
|
||||
profile.minElements,
|
||||
profile.maxElements
|
||||
),
|
||||
10,
|
||||
love.graphics.getHeight() - 120
|
||||
)
|
||||
love.graphics.print(
|
||||
string.format("Memory: %.2f MB | Peak: %.2f MB",
|
||||
collectgarbage("count") / 1024,
|
||||
profile.memoryStats.peakMemory
|
||||
),
|
||||
10,
|
||||
love.graphics.getHeight() - 100
|
||||
)
|
||||
love.graphics.print(
|
||||
string.format("GC Count: %d | Strategy: manual",
|
||||
profile.memoryStats.gcCount
|
||||
),
|
||||
10,
|
||||
love.graphics.getHeight() - 80
|
||||
)
|
||||
love.graphics.print("Press G to force garbage collection", 10, love.graphics.getHeight() - 60)
|
||||
love.graphics.print("Press + to add 25 elements", 10, love.graphics.getHeight() - 45)
|
||||
love.graphics.print("Press - to remove 25 elements", 10, love.graphics.getHeight() - 30)
|
||||
end
|
||||
|
||||
function profile.keypressed(key)
|
||||
if key == "=" or key == "+" then
|
||||
profile.elementCount = math.min(profile.maxElements, profile.elementCount + 25)
|
||||
profile.buildLayout()
|
||||
elseif key == "-" or key == "_" then
|
||||
profile.elementCount = math.max(profile.minElements, profile.elementCount - 25)
|
||||
profile.buildLayout()
|
||||
elseif key == "g" then
|
||||
-- Force garbage collection
|
||||
local beforeGC = collectgarbage("count") / 1024
|
||||
collectgarbage("collect")
|
||||
collectgarbage("collect") -- Run twice for thorough cleanup
|
||||
local afterGC = collectgarbage("count") / 1024
|
||||
profile.memoryStats.gcCount = profile.memoryStats.gcCount + 1
|
||||
profile.memoryStats.lastGCTime = love.timer.getTime()
|
||||
|
||||
print(string.format("Manual GC: %.2f MB -> %.2f MB (freed %.2f MB)",
|
||||
beforeGC, afterGC, beforeGC - afterGC))
|
||||
|
||||
profile.buildLayout() -- Update stats display
|
||||
end
|
||||
end
|
||||
|
||||
function profile.resize(w, h)
|
||||
FlexLove.resize(w, h)
|
||||
profile.buildLayout()
|
||||
end
|
||||
|
||||
function profile.reset()
|
||||
profile.elementCount = 100
|
||||
collectgarbage("collect")
|
||||
collectgarbage("collect")
|
||||
profile.memoryStats.startMemory = collectgarbage("count") / 1024
|
||||
profile.memoryStats.peakMemory = profile.memoryStats.startMemory
|
||||
profile.memoryStats.gcCount = 0
|
||||
profile.memoryStats.lastGCTime = 0
|
||||
profile.updateTimer = 0
|
||||
profile.createDestroyTimer = 0
|
||||
profile.buildLayout()
|
||||
end
|
||||
|
||||
function profile.cleanup()
|
||||
profile.root = nil
|
||||
collectgarbage("collect")
|
||||
collectgarbage("collect")
|
||||
end
|
||||
|
||||
return profile
|
||||
187
profiling/__profiles__/render_stress_profile.lua
Normal file
187
profiling/__profiles__/render_stress_profile.lua
Normal file
@@ -0,0 +1,187 @@
|
||||
-- Render Stress Profile
|
||||
-- Tests rendering with heavy draw operations
|
||||
|
||||
local FlexLove = require("FlexLove")
|
||||
|
||||
local profile = {
|
||||
elementCount = 200,
|
||||
maxElements = 2000,
|
||||
minElements = 50,
|
||||
root = nil,
|
||||
showRounded = true,
|
||||
showText = true,
|
||||
showLayering = true,
|
||||
}
|
||||
|
||||
function profile.init()
|
||||
FlexLove.init({
|
||||
width = love.graphics.getWidth(),
|
||||
height = love.graphics.getHeight(),
|
||||
})
|
||||
|
||||
profile.buildLayout()
|
||||
end
|
||||
|
||||
function profile.buildLayout()
|
||||
profile.root = FlexLove.new({
|
||||
width = "100%",
|
||||
height = "100%",
|
||||
backgroundColor = {0.05, 0.05, 0.1, 1},
|
||||
flexDirection = "column",
|
||||
overflow = "scroll",
|
||||
padding = 20,
|
||||
gap = 10,
|
||||
})
|
||||
|
||||
-- Render container
|
||||
local renderContainer = FlexLove.new({
|
||||
width = "100%",
|
||||
flexDirection = "row",
|
||||
flexWrap = "wrap",
|
||||
gap = 5,
|
||||
marginBottom = 20,
|
||||
})
|
||||
|
||||
for i = 1, profile.elementCount do
|
||||
local hue = (i / profile.elementCount) * 360
|
||||
local color = {
|
||||
0.3 + 0.5 * math.sin(hue * math.pi / 180),
|
||||
0.3 + 0.5 * math.sin((hue + 120) * math.pi / 180),
|
||||
0.3 + 0.5 * math.sin((hue + 240) * math.pi / 180),
|
||||
1
|
||||
}
|
||||
|
||||
local box = FlexLove.new({
|
||||
width = 50,
|
||||
height = 50,
|
||||
backgroundColor = color,
|
||||
borderRadius = profile.showRounded and (5 + math.random(20)) or 0,
|
||||
margin = 2,
|
||||
})
|
||||
|
||||
-- Add text rendering if enabled
|
||||
if profile.showText then
|
||||
box:addChild(FlexLove.new({
|
||||
textContent = tostring(i),
|
||||
fontSize = 12,
|
||||
color = {1, 1, 1, 0.8},
|
||||
}))
|
||||
end
|
||||
|
||||
-- Add layering (nested elements) if enabled
|
||||
if profile.showLayering and i % 3 == 0 then
|
||||
local innerBox = FlexLove.new({
|
||||
width = "80%",
|
||||
height = "80%",
|
||||
backgroundColor = {color[1] * 0.5, color[2] * 0.5, color[3] * 0.5, 0.7},
|
||||
borderRadius = profile.showRounded and 8 or 0,
|
||||
justifyContent = "center",
|
||||
alignItems = "center",
|
||||
})
|
||||
box:addChild(innerBox)
|
||||
end
|
||||
|
||||
renderContainer:addChild(box)
|
||||
end
|
||||
|
||||
profile.root:addChild(renderContainer)
|
||||
|
||||
-- Controls panel
|
||||
local controlsPanel = FlexLove.new({
|
||||
width = "100%",
|
||||
padding = 15,
|
||||
backgroundColor = {0.1, 0.1, 0.2, 0.9},
|
||||
borderRadius = 8,
|
||||
flexDirection = "column",
|
||||
gap = 8,
|
||||
})
|
||||
|
||||
controlsPanel:addChild(FlexLove.new({
|
||||
textContent = string.format("Render Elements: %d (Press +/- to adjust)", profile.elementCount),
|
||||
fontSize = 18,
|
||||
color = {1, 1, 1, 1},
|
||||
}))
|
||||
|
||||
controlsPanel:addChild(FlexLove.new({
|
||||
textContent = string.format("[R] Rounded Rectangles: %s", profile.showRounded and "ON" or "OFF"),
|
||||
fontSize = 14,
|
||||
color = {0.8, 0.8, 0.8, 1},
|
||||
}))
|
||||
|
||||
controlsPanel:addChild(FlexLove.new({
|
||||
textContent = string.format("[T] Text Rendering: %s", profile.showText and "ON" or "OFF"),
|
||||
fontSize = 14,
|
||||
color = {0.8, 0.8, 0.8, 1},
|
||||
}))
|
||||
|
||||
controlsPanel:addChild(FlexLove.new({
|
||||
textContent = string.format("[L] Layering/Overdraw: %s", profile.showLayering and "ON" or "OFF"),
|
||||
fontSize = 14,
|
||||
color = {0.8, 0.8, 0.8, 1},
|
||||
}))
|
||||
|
||||
profile.root:addChild(controlsPanel)
|
||||
end
|
||||
|
||||
function profile.update(dt)
|
||||
end
|
||||
|
||||
function profile.draw()
|
||||
if profile.root then
|
||||
profile.root:draw()
|
||||
end
|
||||
|
||||
-- Overlay info
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
love.graphics.print("Render Stress Test", 10, love.graphics.getHeight() - 120)
|
||||
love.graphics.print(
|
||||
string.format("Elements: %d | Range: %d-%d",
|
||||
profile.elementCount,
|
||||
profile.minElements,
|
||||
profile.maxElements
|
||||
),
|
||||
10,
|
||||
love.graphics.getHeight() - 100
|
||||
)
|
||||
love.graphics.print("Press + to add 50 elements", 10, love.graphics.getHeight() - 80)
|
||||
love.graphics.print("Press - to remove 50 elements", 10, love.graphics.getHeight() - 65)
|
||||
love.graphics.print("Press R/T/L to toggle features", 10, love.graphics.getHeight() - 50)
|
||||
end
|
||||
|
||||
function profile.keypressed(key)
|
||||
if key == "=" or key == "+" then
|
||||
profile.elementCount = math.min(profile.maxElements, profile.elementCount + 50)
|
||||
profile.buildLayout()
|
||||
elseif key == "-" or key == "_" then
|
||||
profile.elementCount = math.max(profile.minElements, profile.elementCount - 50)
|
||||
profile.buildLayout()
|
||||
elseif key == "r" then
|
||||
profile.showRounded = not profile.showRounded
|
||||
profile.buildLayout()
|
||||
elseif key == "t" then
|
||||
profile.showText = not profile.showText
|
||||
profile.buildLayout()
|
||||
elseif key == "l" then
|
||||
profile.showLayering = not profile.showLayering
|
||||
profile.buildLayout()
|
||||
end
|
||||
end
|
||||
|
||||
function profile.resize(w, h)
|
||||
FlexLove.resize(w, h)
|
||||
profile.buildLayout()
|
||||
end
|
||||
|
||||
function profile.reset()
|
||||
profile.elementCount = 200
|
||||
profile.showRounded = true
|
||||
profile.showText = true
|
||||
profile.showLayering = true
|
||||
profile.buildLayout()
|
||||
end
|
||||
|
||||
function profile.cleanup()
|
||||
profile.root = nil
|
||||
end
|
||||
|
||||
return profile
|
||||
Reference in New Issue
Block a user