mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-23 22:11:38 +00:00
- Introduced `DIFF_YIELD_INTERVAL` and `HYDRATE_YIELD_INTERVAL` constants to manage execution pacing during the diffing and hydrating processes, respectively. - Implemented logic to pause execution every specified interval to improve performance and prevent potential blocking in long-running operations. - Enhanced the `diff` and `hydrate` functions to track and yield based on their respective counts, ensuring smoother operation during intensive tasks. These changes aim to enhance the responsiveness of the system during heavy processing tasks by introducing controlled yielding mechanisms.
80 lines
2.2 KiB
Lua
80 lines
2.2 KiB
Lua
--[[
|
|
Defines the process of "hydration" -- matching up a virtual DOM with
|
|
concrete instances and assigning them IDs.
|
|
|
|
Uses the change-count matching algorithm to handle duplicate-named
|
|
instances: groups by (Name, ClassName), then greedy-assigns pairs
|
|
by fewest total reconciler changes (recursive into subtrees).
|
|
]]
|
|
|
|
local Packages = script.Parent.Parent.Parent.Packages
|
|
local Log = require(Packages.Log)
|
|
|
|
local invariant = require(script.Parent.Parent.invariant)
|
|
local Matching = require(script.Parent.matching)
|
|
|
|
local HYDRATE_YIELD_INTERVAL = 1000
|
|
|
|
local function hydrate(instanceMap, virtualInstances, rootId, rootInstance, session)
|
|
if not session then
|
|
session = Matching.newSession()
|
|
end
|
|
|
|
if not session.hydrateCount then
|
|
session.hydrateCount = 0
|
|
end
|
|
session.hydrateCount += 1
|
|
if session.hydrateCount % HYDRATE_YIELD_INTERVAL == 0 then
|
|
task.wait()
|
|
end
|
|
|
|
local virtualInstance = virtualInstances[rootId]
|
|
|
|
if virtualInstance == nil then
|
|
invariant("Cannot hydrate an instance not present in virtualInstances\nID: {}", rootId)
|
|
end
|
|
|
|
instanceMap:insert(rootId, rootInstance)
|
|
|
|
local existingChildren = rootInstance:GetChildren()
|
|
local virtualChildIds = virtualInstance.Children
|
|
|
|
-- Filter out virtual children missing from virtualInstances
|
|
local validVirtualIds: { string } = {}
|
|
for _, childId in ipairs(virtualChildIds) do
|
|
if virtualInstances[childId] then
|
|
table.insert(validVirtualIds, childId)
|
|
else
|
|
Log.warn(
|
|
"Hydration: virtualInstances missing child ID {} (parent: {} '{}')",
|
|
childId,
|
|
rootId,
|
|
virtualInstance.Name
|
|
)
|
|
end
|
|
end
|
|
|
|
local result =
|
|
Matching.matchChildren(session, validVirtualIds, existingChildren, virtualInstances, rootId, rootInstance)
|
|
|
|
-- Recursively hydrate matched pairs
|
|
for _, pair in result.matched do
|
|
hydrate(instanceMap, virtualInstances, pair.virtualId, pair.studioInstance, session)
|
|
end
|
|
|
|
-- Log unmatched virtual children (no Studio counterpart found)
|
|
for _, virtualId in result.unmatchedVirtual do
|
|
local virtualChild = virtualInstances[virtualId]
|
|
if virtualChild then
|
|
Log.debug(
|
|
"Hydration: No match for virtual child '{}' ({}) under '{}' ({})",
|
|
virtualChild.Name,
|
|
virtualChild.ClassName,
|
|
virtualInstance.Name,
|
|
rootInstance:GetFullName()
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
return hydrate
|