rojo/plugin/rbx_dom_lua/init.lua
Joe dccd3a691a Enhance property encoding and class descriptor retrieval in rbx_dom_lua
- Introduced a new function, `findClassDescriptor`, to retrieve class properties and metadata, including inherited properties, from the database.
- Updated `encodeInstance` to include encoding for Tags alongside Attributes, ensuring comprehensive property serialization.
- Improved property filtering logic to skip non-serializable properties and those matching default values, aligning with syncback behavior.
- Enhanced comments for clarity on property handling and encoding processes.
2026-01-30 13:18:20 -06:00

116 lines
3.3 KiB
Lua

local database = require(script.database)
local Error = require(script.Error)
local PropertyDescriptor = require(script.PropertyDescriptor)
-- Returns a class descriptor with all property names and metadata (including inherited ones)
-- 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
local function findClassDescriptor(className)
local classData = database.Classes[className]
if classData == nil then
return nil
end
-- Build a table of all properties, walking up the inheritance chain
local allProperties = {}
local currentClassName = className
repeat
local currentClass = database.Classes[currentClassName]
if currentClass == nil then
break
end
-- Add properties from this class (don't override if already set by subclass)
for propertyName, propertyData in pairs(currentClass.Properties) do
if allProperties[propertyName] == nil then
-- Only include canonical properties (not aliases)
if propertyData.Kind and propertyData.Kind.Canonical then
allProperties[propertyName] = {
name = propertyName,
scriptability = propertyData.Scriptability,
dataType = propertyData.DataType,
serialization = propertyData.Kind.Canonical.Serialization,
}
end
end
end
currentClassName = currentClass.Superclass
until currentClassName == nil
return {
name = classData.Name,
superclass = classData.Superclass,
properties = allProperties,
}
end
local function findCanonicalPropertyDescriptor(className, propertyName)
local currentClassName = className
repeat
local currentClass = database.Classes[currentClassName]
if currentClass == nil then
return currentClass
end
local propertyData = currentClass.Properties[propertyName]
if propertyData ~= nil then
local canonicalData = propertyData.Kind.Canonical
if canonicalData ~= nil then
return PropertyDescriptor.fromRaw(propertyData, currentClassName, propertyName)
end
local aliasData = propertyData.Kind.Alias
if aliasData ~= nil then
return PropertyDescriptor.fromRaw(
currentClass.Properties[aliasData.AliasFor],
currentClassName,
aliasData.AliasFor
)
end
return nil
end
currentClassName = currentClass.Superclass
until currentClassName == nil
return nil
end
local function readProperty(instance, propertyName)
local descriptor = findCanonicalPropertyDescriptor(instance.ClassName, propertyName)
if descriptor == nil then
local fullName = ("%s.%s"):format(instance.className, propertyName)
return false, Error.new(Error.Kind.UnknownProperty, fullName)
end
return descriptor:read(instance)
end
local function writeProperty(instance, propertyName, value)
local descriptor = findCanonicalPropertyDescriptor(instance.ClassName, propertyName)
if descriptor == nil then
local fullName = ("%s.%s"):format(instance.className, propertyName)
return false, Error.new(Error.Kind.UnknownProperty, fullName)
end
return descriptor:write(instance, value)
end
return {
readProperty = readProperty,
writeProperty = writeProperty,
findCanonicalPropertyDescriptor = findCanonicalPropertyDescriptor,
findClassDescriptor = findClassDescriptor,
Error = Error,
EncodedValue = require(script.EncodedValue),
}