104 lines
3.0 KiB
Lua
104 lines
3.0 KiB
Lua
--[[
|
|
An optional instrumentation layer that the reconciler calls into to record
|
|
various events.
|
|
|
|
Tracks a number of stats, including:
|
|
Recorded stats:
|
|
- Render count by component
|
|
- Update request count by component
|
|
- Actual update count by component
|
|
- shouldUpdate returned true count by component
|
|
- Time taken to run shouldUpdate
|
|
- Time taken to render by component
|
|
Derivable stats (for profiling manually or with a future tool):
|
|
- Average render time by component
|
|
- Percent of total render time by component
|
|
- Percent of time shouldUpdate returns true
|
|
- Average shouldUpdate time by component
|
|
- Percent of total shouldUpdate time by component
|
|
]]
|
|
|
|
local Instrumentation = {}
|
|
|
|
local componentStats = {}
|
|
|
|
--[[
|
|
Determines name of component from the given instance handle and returns a
|
|
stat object from the componentStats table, generating a new one if needed
|
|
]]
|
|
local function getStatEntry(handle)
|
|
local name
|
|
if handle and handle._element and handle._element.component then
|
|
name = tostring(handle._element.component)
|
|
else
|
|
warn("Component name not valid for " .. tostring(handle._key))
|
|
return nil
|
|
end
|
|
local entry = componentStats[name]
|
|
if not entry then
|
|
entry = {
|
|
-- update requests
|
|
updateReqCount = 0,
|
|
-- actual updates
|
|
didUpdateCount = 0,
|
|
-- time spent in shouldUpdate
|
|
shouldUpdateTime = 0,
|
|
-- number of renders
|
|
renderCount = 0,
|
|
-- total render time spent
|
|
renderTime = 0,
|
|
}
|
|
componentStats[name] = entry
|
|
end
|
|
|
|
return entry
|
|
end
|
|
|
|
--[[
|
|
Logs the time taken and resulting value of a Component's shouldUpdate function
|
|
]]
|
|
function Instrumentation.logShouldUpdate(handle, updateNeeded, shouldUpdateTime)
|
|
-- Grab or create associated entry in stats table
|
|
local statEntry = getStatEntry(handle)
|
|
if statEntry then
|
|
-- Increment the total number of times update was invoked
|
|
statEntry.updateReqCount = statEntry.updateReqCount + 1
|
|
|
|
-- Increment (when applicable) total number of times shouldUpdate returned true
|
|
statEntry.didUpdateCount = statEntry.didUpdateCount + (updateNeeded and 1 or 0)
|
|
|
|
-- Add time spent checking if an update is needed (in millis) to total time
|
|
statEntry.shouldUpdateTime = statEntry.shouldUpdateTime + shouldUpdateTime * 1000
|
|
end
|
|
end
|
|
|
|
--[[
|
|
Logs the time taken value of a Component's render function
|
|
]]
|
|
function Instrumentation.logRenderTime(handle, renderTime)
|
|
-- Grab or create associated entry in stats table
|
|
local statEntry = getStatEntry(handle)
|
|
if statEntry then
|
|
-- Increment total render count
|
|
statEntry.renderCount = statEntry.renderCount + 1
|
|
|
|
-- Add render time (in millis) to total rendering time
|
|
statEntry.renderTime = statEntry.renderTime + renderTime * 1000
|
|
end
|
|
end
|
|
|
|
--[[
|
|
Clears all the stats collected thus far. Useful for testing and for profiling in the future
|
|
]]
|
|
function Instrumentation.clearCollectedStats()
|
|
componentStats = {}
|
|
end
|
|
|
|
--[[
|
|
Returns all the stats collected thus far. Useful for testing and for profiling in the future
|
|
]]
|
|
function Instrumentation.getCollectedStats()
|
|
return componentStats
|
|
end
|
|
|
|
return Instrumentation |