From 866135b152852faab91ac8fc2cd0b449d45c0372 Mon Sep 17 00:00:00 2001 From: aaron <83140718+centau@users.noreply.github.com> Date: Sat, 9 Sep 2023 18:59:25 +0100 Subject: [PATCH] --- src/graph.luau | 45 +++++++++++++++++++++++++++++---------------- test/tests.luau | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 16 deletions(-) diff --git a/src/graph.luau b/src/graph.luau index 396dca2..0e16de6 100644 --- a/src/graph.luau +++ b/src/graph.luau @@ -5,11 +5,12 @@ local flags = require(script.Parent.flags) export type StartNode = { cache: T, - n: number, - [number]: Node + children: { [Node]: true } | false } -export type Node = StartNode & { +export type Node = { + cache: T, + children: { [Node]: true } | false, effect: (T) -> (), cleanups: { () -> () } | false, } @@ -50,9 +51,11 @@ local function get_scope(): Node end local function add_child(parent: Node, child: Node) - local n = parent.n + 1 - parent.n = n - parent[n] = child + if parent.children then + parent.children[child] = true + else + parent.children = { [child] = true :: true } + end end -- local function open_root_scope(node: Node) @@ -107,15 +110,17 @@ local function destroy(node: Node) end end + -- runs node effects, recalculates descendants and runs descendant effects local function update(node: StartNode) - local children = { unpack(node) } - for i = 1, node.n do - node[i] = nil - end - node.n = 0 + if not node.children then return end - 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) run_cleanups(child) run_effect(child) @@ -132,17 +137,25 @@ local function create_node(value: T): Node return { cache = value, effect = function() end, - cleanups = false :: false, - n = 0 + cleanups = false, + children = false } end local function get_children(node: Node): { Node } - 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 local function create_start_node(value: T): StartNode - return { cache = value, n = 0 } + return { cache = value, children = false } end return table.freeze { diff --git a/test/tests.luau b/test/tests.luau index 52d8c7d..f6e4ac6 100644 --- a/test/tests.luau +++ b/test/tests.luau @@ -87,6 +87,42 @@ TEST("graph", function() CHECK(count == 3) 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 do CASE "nodes garbage collection"