mirror of
https://github.com/centau/vide.git
synced 2026-08-20 14:41:37 +00:00
This commit is contained in:
parent
1f0b734956
commit
866135b152
2 changed files with 65 additions and 16 deletions
|
|
@ -5,11 +5,12 @@ local flags = require(script.Parent.flags)
|
||||||
|
|
||||||
export type StartNode<T> = {
|
export type StartNode<T> = {
|
||||||
cache: T,
|
cache: T,
|
||||||
n: number,
|
children: { [Node<T>]: true } | false
|
||||||
[number]: Node<T>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Node<T> = StartNode<T> & {
|
export type Node<T> = {
|
||||||
|
cache: T,
|
||||||
|
children: { [Node<T>]: true } | false,
|
||||||
effect: (T) -> (),
|
effect: (T) -> (),
|
||||||
cleanups: { () -> () } | false,
|
cleanups: { () -> () } | false,
|
||||||
}
|
}
|
||||||
|
|
@ -50,9 +51,11 @@ local function get_scope(): Node<unknown>
|
||||||
end
|
end
|
||||||
|
|
||||||
local function add_child<T>(parent: Node<any>, child: Node<any>)
|
local function add_child<T>(parent: Node<any>, child: Node<any>)
|
||||||
local n = parent.n + 1
|
if parent.children then
|
||||||
parent.n = n
|
parent.children[child] = true
|
||||||
parent[n] = child
|
else
|
||||||
|
parent.children = { [child] = true :: true }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- local function open_root_scope<T>(node: Node<T>)
|
-- local function open_root_scope<T>(node: Node<T>)
|
||||||
|
|
@ -107,15 +110,17 @@ local function destroy<T>(node: Node<T>)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- runs node effects, recalculates descendants and runs descendant effects
|
-- runs node effects, recalculates descendants and runs descendant effects
|
||||||
local function update<T>(node: StartNode<T>)
|
local function update<T>(node: StartNode<T>)
|
||||||
local children = { unpack(node) }
|
if not node.children then return end
|
||||||
for i = 1, node.n do
|
|
||||||
node[i] = nil
|
|
||||||
end
|
|
||||||
node.n = 0
|
|
||||||
|
|
||||||
for _, child in children do
|
local cache = {}
|
||||||
|
for child in node.children do
|
||||||
|
table.insert(cache, child)
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, child in next, cache do
|
||||||
open_scope(child)
|
open_scope(child)
|
||||||
run_cleanups(child)
|
run_cleanups(child)
|
||||||
run_effect(child)
|
run_effect(child)
|
||||||
|
|
@ -132,17 +137,25 @@ local function create_node<T>(value: T): Node<T>
|
||||||
return {
|
return {
|
||||||
cache = value,
|
cache = value,
|
||||||
effect = function() end,
|
effect = function() end,
|
||||||
cleanups = false :: false,
|
cleanups = false,
|
||||||
n = 0
|
children = false
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_children(node: Node<unknown>): { Node<unknown> }
|
local function get_children(node: Node<unknown>): { Node<unknown> }
|
||||||
return { unpack(node) }
|
if not node.children then return {} end
|
||||||
|
|
||||||
|
local children = {}
|
||||||
|
|
||||||
|
for child in node.children do
|
||||||
|
table.insert(children, child)
|
||||||
|
end
|
||||||
|
|
||||||
|
return children
|
||||||
end
|
end
|
||||||
|
|
||||||
local function create_start_node<T>(value: T): StartNode<T>
|
local function create_start_node<T>(value: T): StartNode<T>
|
||||||
return { cache = value, n = 0 }
|
return { cache = value, children = false }
|
||||||
end
|
end
|
||||||
|
|
||||||
return table.freeze {
|
return table.freeze {
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,42 @@ TEST("graph", function()
|
||||||
CHECK(count == 3)
|
CHECK(count == 3)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
do CASE "etst"
|
||||||
|
--[[
|
||||||
|
|
||||||
|
root
|
||||||
|
Items -> Indexes()
|
||||||
|
|
||||||
|
indexes_root
|
||||||
|
v1 + sel -> bind
|
||||||
|
v2 + sel -> bind
|
||||||
|
|
||||||
|
]]
|
||||||
|
local items = create_node { 1, 2 }
|
||||||
|
|
||||||
|
local count = 0
|
||||||
|
|
||||||
|
local function effect()
|
||||||
|
track(a)
|
||||||
|
track(b)
|
||||||
|
count += 1
|
||||||
|
end
|
||||||
|
|
||||||
|
c.effect = effect
|
||||||
|
|
||||||
|
open_scope(c)
|
||||||
|
|
||||||
|
effect()
|
||||||
|
|
||||||
|
close_scope()
|
||||||
|
|
||||||
|
CHECK(count == 1)
|
||||||
|
update(a)
|
||||||
|
CHECK(count == 2)
|
||||||
|
update(b)
|
||||||
|
CHECK(count == 3)
|
||||||
|
end
|
||||||
|
|
||||||
-- todo: further tests
|
-- todo: further tests
|
||||||
|
|
||||||
do CASE "nodes garbage collection"
|
do CASE "nodes garbage collection"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue