Update spring tests

This commit is contained in:
aaron 2023-08-26 14:49:46 +01:00
parent ffef8e24ca
commit 5ab76a434e
3 changed files with 71 additions and 19 deletions

View file

@ -42,7 +42,7 @@ type Animatable = number | CFrame | Color3 | UDim | UDim2 | Vector2 | Vector3
type SpringData<T> = {
k: number, -- spring constant
c: number, -- damping coeff (from k)
c: number, -- damping coeff
-- dimensions 1-3
x0_123: Vec3,
@ -54,7 +54,7 @@ type SpringData<T> = {
x1_456: Vec3,
v_456: Vec3,
source_value: T
source_value: T -- current value of spring input source
}
type TypeToVec6<T> = (T) -> (Vec3, Vec3)
@ -140,7 +140,7 @@ setmetatable(type_to_vec6, invalid_type)
setmetatable(vec6_to_type, invalid_type)
-- maps spring data to its corresponding output node
-- lifetime of spring data is tied to output node's
-- lifetime of spring data is tied to output node
local springs: { [SpringData<any>]: Node<any> } = {}
setmetatable(springs, { __mode = "v" })
@ -162,7 +162,7 @@ local function spring<T>(source: () -> T, period: number?, damping_ratio: number
local c_c = 2*w_n
local c = z * c_c
local data: SpringData<T> = { -- todo: confirm gc of data
local data: SpringData<T> = {
k = k,
c = c,
@ -178,26 +178,32 @@ local function spring<T>(source: () -> T, period: number?, damping_ratio: number
}
-- reschedule spring for simulation on input update
local function input_updated()
local function input_updated(node)
local v = source()
data.x1_123, data.x1_456 = type_to_vec6[typeof(v)](v)
data.source_value = v
springs[data] = output -- todo: investigate why insertion is not O(1) at ~20k springs
springs[data] = node -- todo: investigate why insertion is not O(1) at ~20k springs
end
output.derive = input_updated :: any -- have output reference inputs
-- unused field, use so output prevents gc of inputs
output.derive = source :: any
-- register above function as side-effect for all inputs
for _, input in next, inputs do
set_effect(input, input_updated, output)
end
return output_get
return output_get, data
end
local function step_springs(dt: number)
for data, output in next, springs do
local k, c, x0_123, x1_123, u_123, x0_456, x1_456, u_456 = data.k, data.c, data.x0_123, data.x1_123, data.v_123, data.x0_456, data.x1_456, data.v_456
for data in next, springs do
local k, c,
x0_123, x1_123, u_123,
x0_456, x1_456, u_456 =
data.k, data.c,
data.x0_123, data.x1_123, data.v_123,
data.x0_456, data.x1_456, data.v_456
-- calculate displacement from target
local dx_123 = x0_123 - x1_123
@ -232,9 +238,14 @@ local remove_queue = {}
local function update_spring_sources()
for data, output in next, springs do
local x0_123, x1_123, v_123, x0_456, x1_456, v_456 = data.x0_123, data.x1_123, data.v_123, data.x0_456, data.x1_456, data.v_456
local x0_123, x1_123, v_123,
x0_456, x1_456, v_456 =
data.x0_123, data.x1_123, data.v_123,
data.x0_456, data.x1_456, data.v_456
local dx_123, dx_456 = x0_123 - x1_123, x0_456 - x1_456
local dx_123, dx_456 =
x0_123 - x1_123,
x0_456 - x1_456
-- todo: can this false positive?
if (v_123 + v_456 + dx_123 + dx_456).Magnitude < TOLERANCE then

View file

@ -13,10 +13,6 @@ local function step(): number
end
local function main()
local source = vide.source
local spring = vide.spring
local watch = vide.watch
local TERMINAL_HEIGHT = 73 --* REDUCE IF BAR DOES NOT FIT IN TERMINAL
local MIN_ALPHA = 0.3
local MAX_ALPHA = 0.7
@ -39,6 +35,10 @@ local function main()
else ""
end
local source = vide.source
local spring = vide.spring
local watch = vide.watch
local value = source(MAX)
local sprung = spring(value, 1, 0.3)

View file

@ -214,6 +214,19 @@ TEST("source()", function()
state(b)
CHECK(updates == 1)
end
do CASE "garbage collection of node"
local capture = require "src/graph".capture
local src = source(0)
local wref do
local node = unpack(capture(src))
wref = weak { node }
end
gc()
CHECK(not wref[1])
end
end)
TEST("derive()", function()
@ -332,6 +345,20 @@ TEST("derive()", function()
CHECK(c() == 2)
end
end
do CASE "garbage collection of node"
local capture = require "src/graph".capture
local input = source(1)
local wref do
local output = derive(input)
local output_node = unpack(capture(output))
wref = weak { output_node }
end
gc()
CHECK(not wref[1])
end
end)
TEST("watch()", function()
@ -632,8 +659,6 @@ TEST("create()", function()
Position = UDim2.new()
}
print("template", template.AnchorPoint)
local text = create(template) {
AnchorPoint = { 1, 2 },
Position = { 3, 4 }
@ -1215,8 +1240,24 @@ TEST("spring()", function()
gc()
CHECK(not wref[1])
end
end
do -- spring data gc
local capture = require "src/graph".capture
local input = source(10)
local wref do
local output, data = (spring :: any)(input)
input(input() + 1) -- schedule spring calculation
local output_node = unpack(capture(output))
wref = weak { output_node, data }
end
gc()
CHECK(not wref[1])
CHECK(not wref[2])
end
end
do CASE "garbage collection (binded)"
local input = source(10)