local RunService = game:GetService("RunService")
local PatchSet = require(script.Parent.PatchSet)
local createPatchSet = require(script.createPatchSet)
local ChangeBatcher = {}
ChangeBatcher.__index = ChangeBatcher
local BATCH_INTERVAL = 0.2
function ChangeBatcher.new(instanceMap, onChangesFlushed)
local self
local renderSteppedConnection = RunService.RenderStepped:Connect(function(dt)
self:__cycle(dt)
end)
self = setmetatable({
__accumulator = 0,
__renderSteppedConnection = renderSteppedConnection,
__instanceMap = instanceMap,
__onChangesFlushed = onChangesFlushed,
__pendingPropertyChanges = {},
}, ChangeBatcher)
return self
end
function ChangeBatcher:stop()
self.__renderSteppedConnection:Disconnect()
self.__pendingPropertyChanges = {}
end
function ChangeBatcher:add(instance, propertyName)
local properties = self.__pendingPropertyChanges[instance]
if not properties then
properties = {}
self.__pendingPropertyChanges[instance] = properties
end
properties[propertyName] = true
end
function ChangeBatcher:__cycle(dt)
self.__accumulator += dt
if self.__accumulator >= BATCH_INTERVAL then
self.__accumulator -= BATCH_INTERVAL
local patch = self:__flush()
if patch then
self.__onChangesFlushed(patch)
end
end
self.__instanceMap:unpauseAllInstances()
end
function ChangeBatcher:__flush()
if next(self.__pendingPropertyChanges) == nil then
return nil
end
local patch = createPatchSet(self.__instanceMap, self.__pendingPropertyChanges)
if PatchSet.isEmpty(patch) then
return nil
end
return patch
end
return ChangeBatcher