mirror of
https://github.com/centau/vide.git
synced 2026-08-20 14:41:37 +00:00
Update property nesting
Deeper nested properties guaranteed to be processed after shallower nested properties. Also added strict mode checks for duplicate nested properties.
This commit is contained in:
parent
ddb88cfdf8
commit
a769139136
5 changed files with 125 additions and 29 deletions
|
|
@ -5,11 +5,12 @@ if not game then
|
|||
typeof = require "test/mock".typeof
|
||||
end
|
||||
|
||||
local graph = require(script.Parent.graph)
|
||||
type Node<T> = graph.Node<T>
|
||||
|
||||
local flags = require(script.Parent.flags)
|
||||
local throw = require(script.Parent.throw)
|
||||
local bind = require(script.Parent.bind)
|
||||
local _, is_action = require(script.Parent.action)()
|
||||
local graph = require(script.Parent.graph)
|
||||
type Node<T> = graph.Node<T>
|
||||
|
||||
local event_buffer: { [string]: () -> () } = {}
|
||||
local action_buffers = {} :: { { () -> () } }
|
||||
|
|
@ -21,32 +22,64 @@ setmetatable(action_buffers :: any, {
|
|||
end
|
||||
})
|
||||
|
||||
local function recurse(instance: Instance, properties: { [unknown]: unknown })
|
||||
for property, value in properties do
|
||||
if type(value) == "table" then
|
||||
if is_action(value) then
|
||||
table.insert(action_buffers[(value :: any).priority], (value :: any).callback :: () -> ())
|
||||
else
|
||||
recurse(instance, value :: {})
|
||||
end
|
||||
elseif type(property) == "string" then
|
||||
if type(value) == "function" then
|
||||
if typeof((instance :: any)[property]) == "RBXScriptSignal" then
|
||||
event_buffer[property] = value :: () -> ()
|
||||
local nested_debug_cache: { [number]: { [string]: true } } = {}
|
||||
|
||||
setmetatable(nested_debug_cache :: any, {
|
||||
__index = function(_, i: number)
|
||||
nested_debug_cache[i] = {}
|
||||
return nested_debug_cache[i]
|
||||
end
|
||||
})
|
||||
|
||||
local nested_stack = {} :: { {} | number }
|
||||
|
||||
local function process(instance: Instance, properties: { [unknown]: unknown })
|
||||
local strict = flags.strict
|
||||
|
||||
table.clear(nested_stack)
|
||||
if strict then table.clear(nested_debug_cache) end
|
||||
|
||||
local depth = 1
|
||||
|
||||
repeat
|
||||
for property, value in properties do
|
||||
if type(value) == "table" then
|
||||
if is_action(value) then
|
||||
table.insert(action_buffers[(value :: any).priority], (value :: any).callback :: () -> ())
|
||||
else
|
||||
bind.property(instance, property, value :: () -> ())
|
||||
table.insert(nested_stack, depth + 1)
|
||||
table.insert(nested_stack, value :: {})
|
||||
end
|
||||
elseif type(property) == "string" then
|
||||
if strict then
|
||||
if nested_debug_cache[depth][property] then
|
||||
throw(`duplicate property {property} at depth {depth}`)
|
||||
end
|
||||
nested_debug_cache[depth][property] = true
|
||||
end
|
||||
|
||||
if type(value) == "function" then
|
||||
if typeof((instance :: any)[property]) == "RBXScriptSignal" then
|
||||
event_buffer[property] = value :: () -> ()
|
||||
else
|
||||
bind.property(instance, property, value :: () -> ())
|
||||
end
|
||||
else
|
||||
(instance :: any)[property] = value
|
||||
end
|
||||
elseif type(property) == "number" then
|
||||
if type(value) == "function" then
|
||||
bind.children(instance, value :: () -> { Instance })
|
||||
else
|
||||
(value :: Instance).Parent = instance
|
||||
end
|
||||
else
|
||||
(instance :: any)[property] = value
|
||||
end
|
||||
elseif type(property) == "number" then
|
||||
if type(value) == "function" then
|
||||
bind.children(instance, value :: () -> { Instance })
|
||||
else
|
||||
(value :: Instance).Parent = instance
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
properties = table.remove(nested_stack) :: {}
|
||||
depth = table.remove(nested_stack) :: number
|
||||
|
||||
until not properties
|
||||
end
|
||||
|
||||
local function apply<T>(instance: T & Instance, properties: { [unknown]: unknown }): T
|
||||
|
|
@ -58,7 +91,7 @@ local function apply<T>(instance: T & Instance, properties: { [unknown]: unknown
|
|||
table.clear(buffer)
|
||||
end
|
||||
|
||||
recurse(instance, properties)
|
||||
process(instance, properties)
|
||||
|
||||
for event, fn in next, event_buffer do
|
||||
(instance :: any)[event]:Connect(fn)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue