forked from rojo-rbx/rojo
Use SerializationService as a fallback for when patch application fails (#1030)
This commit is contained in:
@@ -5,8 +5,6 @@
|
||||
Patches can come from the server or be generated by the client.
|
||||
]]
|
||||
|
||||
local ChangeHistoryService = game:GetService("ChangeHistoryService")
|
||||
|
||||
local Packages = script.Parent.Parent.Parent.Packages
|
||||
local Log = require(Packages.Log)
|
||||
|
||||
@@ -20,13 +18,6 @@ local reifyInstance, applyDeferredRefs = reify.reifyInstance, reify.applyDeferre
|
||||
local setProperty = require(script.Parent.setProperty)
|
||||
|
||||
local function applyPatch(instanceMap, patch)
|
||||
local patchTimestamp = DateTime.now():FormatLocalTime("LTS", "en-us")
|
||||
local historyRecording = ChangeHistoryService:TryBeginRecording("Rojo: Patch " .. patchTimestamp)
|
||||
if not historyRecording then
|
||||
-- There can only be one recording at a time
|
||||
Log.debug("Failed to begin history recording for " .. patchTimestamp .. ". Another recording is in progress.")
|
||||
end
|
||||
|
||||
-- Tracks any portions of the patch that could not be applied to the DOM.
|
||||
local unappliedPatch = PatchSet.newEmpty()
|
||||
|
||||
@@ -73,9 +64,6 @@ local function applyPatch(instanceMap, patch)
|
||||
if parentInstance == nil then
|
||||
-- This would be peculiar. If you create an instance with no
|
||||
-- parent, were you supposed to create it at all?
|
||||
if historyRecording then
|
||||
ChangeHistoryService:FinishRecording(historyRecording, Enum.FinishRecordingOperation.Commit)
|
||||
end
|
||||
invariant(
|
||||
"Cannot add an instance from a patch that has no parent.\nInstance {} with parent {}.\nState: {:#?}",
|
||||
id,
|
||||
@@ -244,10 +232,6 @@ local function applyPatch(instanceMap, patch)
|
||||
end
|
||||
end
|
||||
|
||||
if historyRecording then
|
||||
ChangeHistoryService:FinishRecording(historyRecording, Enum.FinishRecordingOperation.Commit)
|
||||
end
|
||||
|
||||
applyDeferredRefs(instanceMap, deferredRefs, unappliedPatch)
|
||||
|
||||
return unappliedPatch
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
|
||||
local Rojo = script:FindFirstAncestor("Rojo")
|
||||
local Plugin = Rojo.Plugin
|
||||
local Packages = Rojo.Packages
|
||||
|
||||
local Log = require(Packages.Log)
|
||||
|
||||
local Timer = require(Plugin.Timer)
|
||||
|
||||
@@ -22,78 +19,17 @@ function Reconciler.new(instanceMap)
|
||||
local self = {
|
||||
-- Tracks all of the instances known by the reconciler by ID.
|
||||
__instanceMap = instanceMap,
|
||||
__precommitCallbacks = {},
|
||||
__postcommitCallbacks = {},
|
||||
}
|
||||
|
||||
return setmetatable(self, Reconciler)
|
||||
end
|
||||
|
||||
function Reconciler:hookPrecommit(callback: (patch: any, instanceMap: any) -> ()): () -> ()
|
||||
table.insert(self.__precommitCallbacks, callback)
|
||||
Log.trace("Added precommit callback: {}", callback)
|
||||
|
||||
return function()
|
||||
-- Remove the callback from the list
|
||||
for i, cb in self.__precommitCallbacks do
|
||||
if cb == callback then
|
||||
table.remove(self.__precommitCallbacks, i)
|
||||
Log.trace("Removed precommit callback: {}", callback)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Reconciler:hookPostcommit(callback: (patch: any, instanceMap: any, unappliedPatch: any) -> ()): () -> ()
|
||||
table.insert(self.__postcommitCallbacks, callback)
|
||||
Log.trace("Added postcommit callback: {}", callback)
|
||||
|
||||
return function()
|
||||
-- Remove the callback from the list
|
||||
for i, cb in self.__postcommitCallbacks do
|
||||
if cb == callback then
|
||||
table.remove(self.__postcommitCallbacks, i)
|
||||
Log.trace("Removed postcommit callback: {}", callback)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Reconciler:applyPatch(patch)
|
||||
Timer.start("Reconciler:applyPatch")
|
||||
|
||||
Timer.start("precommitCallbacks")
|
||||
-- Precommit callbacks must be serial in order to obey the contract that
|
||||
-- they execute before commit
|
||||
for _, callback in self.__precommitCallbacks do
|
||||
local success, err = pcall(callback, patch, self.__instanceMap)
|
||||
if not success then
|
||||
Log.warn("Precommit hook errored: {}", err)
|
||||
end
|
||||
end
|
||||
Timer.stop()
|
||||
|
||||
Timer.start("apply")
|
||||
local unappliedPatch = applyPatch(self.__instanceMap, patch)
|
||||
Timer.stop()
|
||||
|
||||
Timer.start("postcommitCallbacks")
|
||||
-- Postcommit callbacks can be called with spawn since regardless of firing order, they are
|
||||
-- guaranteed to be called after the commit
|
||||
for _, callback in self.__postcommitCallbacks do
|
||||
task.spawn(function()
|
||||
local success, err = pcall(callback, patch, self.__instanceMap, unappliedPatch)
|
||||
if not success then
|
||||
Log.warn("Postcommit hook errored: {}", err)
|
||||
end
|
||||
end)
|
||||
end
|
||||
Timer.stop()
|
||||
|
||||
Timer.stop()
|
||||
|
||||
return unappliedPatch
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user