mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-23 05:51:39 +00:00
Add default properties caching and update matching logic
- Implemented a caching mechanism for default properties per class in `rbx_dom_lua/init.lua`, allowing for efficient retrieval of encoded default values, including inherited defaults. - Updated the matching logic in `Reconciler/matching.lua` to account for properties present only on the Studio side, ensuring accurate comparisons against default values during reconciliation. - Added new test cases to validate the handling of default-omitted properties, enhancing the robustness of the reconciliation process. These changes improve the efficiency and accuracy of property matching, addressing issues related to default values in the reconciliation workflow.
This commit is contained in:
parent
e54f5ef4e3
commit
9c6966acff
30 changed files with 1648 additions and 0 deletions
|
|
@ -6,6 +6,43 @@ local PropertyDescriptor = require(script.PropertyDescriptor)
|
|||
-- Returns nil if the class doesn't exist in the database
|
||||
-- The properties table maps property names to metadata (scriptability, serialization status)
|
||||
-- To get a full PropertyDescriptor for encoding, use findCanonicalPropertyDescriptor
|
||||
-- Cache for default properties per class (includes inherited defaults).
|
||||
local defaultPropertiesCache: { [string]: { [string]: any } } = {}
|
||||
|
||||
-- Returns a table mapping property names to their encoded default values
|
||||
-- for a given class, including inherited defaults from parent classes.
|
||||
-- Subclass overrides take precedence. Results are cached per class.
|
||||
local function findDefaultProperties(className: string): { [string]: any }
|
||||
local cached = defaultPropertiesCache[className]
|
||||
if cached then
|
||||
return cached
|
||||
end
|
||||
|
||||
local defaults: { [string]: any } = {}
|
||||
local currentClassName: string? = className
|
||||
|
||||
repeat
|
||||
local currentClass = database.Classes[currentClassName]
|
||||
if currentClass == nil then
|
||||
break
|
||||
end
|
||||
|
||||
local classDefaults = currentClass.DefaultProperties
|
||||
if classDefaults then
|
||||
for propName, encodedValue in classDefaults do
|
||||
if defaults[propName] == nil then
|
||||
defaults[propName] = encodedValue
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
currentClassName = currentClass.Superclass
|
||||
until currentClassName == nil
|
||||
|
||||
defaultPropertiesCache[className] = defaults
|
||||
return defaults
|
||||
end
|
||||
|
||||
local function findClassDescriptor(className)
|
||||
local classData = database.Classes[className]
|
||||
if classData == nil then
|
||||
|
|
@ -111,6 +148,7 @@ return {
|
|||
writeProperty = writeProperty,
|
||||
findCanonicalPropertyDescriptor = findCanonicalPropertyDescriptor,
|
||||
findClassDescriptor = findClassDescriptor,
|
||||
findDefaultProperties = findDefaultProperties,
|
||||
Error = Error,
|
||||
EncodedValue = require(script.EncodedValue),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -330,6 +330,48 @@ function Matching._countOwnDiffs(vInst: any, studioInstance: Instance): number
|
|||
end
|
||||
end
|
||||
|
||||
-- Properties present only on the Studio side (not in virtual).
|
||||
-- Syncback strips default-valued properties from model files, so virtual
|
||||
-- instances may omit properties that Studio has at non-default values.
|
||||
-- Without this check, a virtual instance missing e.g. Face scores equally
|
||||
-- against all Studio instances in the group, causing wrong pairings.
|
||||
local defaults = RbxDom.findDefaultProperties(vInst.ClassName)
|
||||
if defaults then
|
||||
for propName, encodedDefault in defaults do
|
||||
if propName == "Tags" or propName == "Attributes" then
|
||||
continue
|
||||
end
|
||||
|
||||
-- Skip properties already compared from the virtual side
|
||||
if vProps and vProps[propName] ~= nil then
|
||||
continue
|
||||
end
|
||||
|
||||
-- Skip Ref/UniqueId types (not comparable during hydration)
|
||||
local ty = next(encodedDefault)
|
||||
if ty == "Ref" or ty == "UniqueId" then
|
||||
continue
|
||||
end
|
||||
|
||||
-- pcall guards against unsupported types (e.g. SharedString)
|
||||
local pcallOk, decodeOk, defaultValue = pcall(RbxDom.EncodedValue.decode, encodedDefault)
|
||||
if not pcallOk or not decodeOk then
|
||||
continue
|
||||
end
|
||||
|
||||
local readOk, studioValue = pcall(function()
|
||||
return (studioInstance :: any)[propName]
|
||||
end)
|
||||
if not readOk then
|
||||
continue
|
||||
end
|
||||
|
||||
if not trueEquals(defaultValue, studioValue) then
|
||||
cost += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Tags: count individual adds/removes
|
||||
local vTags = vInst.Properties and vInst.Properties.Tags
|
||||
if vTags then
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue