This commit is contained in:
aaron 2023-08-07 00:58:11 +01:00
parent fa2709f182
commit 6f9e86c5c7
3 changed files with 73 additions and 20 deletions

View file

@ -87,6 +87,7 @@ local function bind_parent(instance: Instance, fn: () -> Instance?)
end)
end
-- todo: could optimize, see: maps.luau values()
local function bind_children(parent: Instance, fn: () -> { Instance })
local current_child_set: { [Instance]: true } = {} -- cache of all children parented before update
local new_child_set: { [Instance]: true } = {} -- cache of all children parented after update

View file

@ -9,7 +9,7 @@ local link = graph.link
type Map<K, V> = { [K]: V }
-- todo: this could be optimized
-- todo: optimize output array
local function indexes<K, VI, VO>(input: () -> Map<K, VI>, transform: (() -> VI, K) -> VO): () -> { VO }
local input_cache = {} :: Map<K, VI>
local output_cache = {} :: Map<K, VO>
@ -32,9 +32,12 @@ local function indexes<K, VI, VO>(input: () -> Map<K, VI>, transform: (() -> VI,
input_nodes[k] = nil
end
table.clear(remove_queue)
-- process new or changed values
for k, v in next, data do
local cv = input_cache[k]
if cv == nil then
local node, get_value = create(v)
input_nodes[k] = node
@ -72,45 +75,45 @@ local function indexes<K, VI, VO>(input: () -> Map<K, VI>, transform: (() -> VI,
return output_get
end
-- todo: this should be optimized
-- todo: optimize output array
local function values<K, VI, VO>(input: () -> Map<K, VI>, transform: (VI, () -> K) -> VO): () -> { VO }
local input_cache_up = {} :: Map<VI, K>
local input_cache_buffer_up = {} :: Map<VI, K>
local cur_input_cache_up = {} :: Map<VI, K>
local new_input_cache_up = {} :: Map<VI, K>
local output_cache = {} :: Map<VI, VO>
local input_nodes = {} :: Map<VI, Node<K>>
local output_array = {} :: { VO }
local function recompute(data: Map<K, VI>)
local input_cache, input_cache_buffer =
input_cache_up, input_cache_buffer_up
local cur_input_cache, new_input_cache = cur_input_cache_up, new_input_cache_up
-- process new or changed values
-- process data
for i, v in next, data do
local cv = input_cache[v]
new_input_cache[v] = i
local cv = cur_input_cache[v]
if cv == nil then
local node, get_value = create(i)
input_nodes[v] = node
output_cache[v] = transform(v, get_value)
elseif cv ~= i then
else
if cv ~= i then
set(input_nodes[v], i)
end
input_cache_buffer[v] = i
cur_input_cache[v] = nil
end
end
-- remove old values
for v, k in next, input_cache do
if input_cache_buffer[v] == nil then
for v in next, cur_input_cache do
output_cache[v] = nil
input_nodes[v] = nil
end
end
-- update buffer cache
table.clear(input_cache)
input_cache_up, input_cache_buffer_up = input_cache_buffer, input_cache
table.clear(cur_input_cache)
cur_input_cache_up, new_input_cache_up = new_input_cache, cur_input_cache
-- output elements
table.clear(output_array)

View file

@ -135,11 +135,14 @@ BENCH("indexes() no change", function()
return {}
end)
state(state()) -- fill double buffer
START(N)
state(data)
end)
-- todo: find out what is causing allocation
BENCH("indexes() all change", function()
local data = {}
@ -153,6 +156,8 @@ BENCH("indexes() all change", function()
return {}
end)
state(state()) -- fill double buffer
for i, v in data do
data[i] = v + 1
end
@ -162,6 +167,26 @@ BENCH("indexes() all change", function()
state(data)
end)
BENCH("indexes() all remove", function()
local data = {}
for i = 1, N do
data[i] = i
end
local state = vide.source(data)
local _list = vide.values(state, function(v, i)
return {}
end)
table.clear(data)
START(N)
state(data)
end)
BENCH("values() no change", function()
local data = {}
@ -175,6 +200,8 @@ BENCH("values() no change", function()
return {}
end)
state(state()) -- fill double buffer
START(N)
state(data)
@ -193,6 +220,8 @@ BENCH("values() all change", function()
return {}
end)
state(state()) -- fill double buffer
for i = 1, N do
local r = math.random(1, #data)
data[i], data[r] = data[r], data[i]
@ -203,4 +232,24 @@ BENCH("values() all change", function()
state(data)
end)
BENCH("values() all remove", function()
local data = {}
for i = 1, N do
data[i] = {}
end
local state = vide.source(data)
local _list = vide.values(state, function(v, i)
return {}
end)
table.clear(data)
START(N)
state(data)
end)
return nil