diff --git a/src/spring.luau b/src/spring.luau index 9b73d08..f018e5b 100644 --- a/src/spring.luau +++ b/src/spring.luau @@ -167,18 +167,22 @@ local function update_springs(dt: number) local new_time = data.duration + dt local new_alpha = solve(data.period, data.damping_ratio, data.initial_velocity, new_time) + local new_velocity = -(new_alpha - data.alpha)/dt - data.velocity = -(new_alpha - data.alpha)/dt + local acceleration = (new_velocity - data.velocity)/dt + + data.velocity = new_velocity data.alpha = new_alpha data.duration = new_time local value = lerp(initial_position, target_position, new_alpha) - set(output, value) - - -- if new_alpha > 0.9 then - -- table.insert(remove_queue, data) - -- end + if math.abs(acceleration) < 0.01 then + table.insert(remove_queue, data) + set(output, target_position) + else + set(output, value) + end end for _, data in next, remove_queue do diff --git a/test/benchmark.luau b/test/benchmark.luau index b299505..b16e1ad 100644 --- a/test/benchmark.luau +++ b/test/benchmark.luau @@ -131,11 +131,11 @@ BENCH("indexes() no change", function() local state = vide.source(data) - local _list = vide.values(state, function(v, i) + local _list = vide.indexes(state, function(v, i) return {} end) - state(state()) -- fill double buffer + --state(state()) -- fill double buffer START(N) @@ -152,11 +152,11 @@ BENCH("indexes() all change", function() local state = vide.source(data) - local _list = vide.values(state, function(v, i) + local _list = vide.indexes(state, function(v, i) return {} end) - state(state()) -- fill double buffer + --state(state()) -- fill double buffer for i, v in data do data[i] = v + 1 @@ -176,7 +176,7 @@ BENCH("indexes() all remove", function() local state = vide.source(data) - local _list = vide.values(state, function(v, i) + local _list = vide.indexes(state, function(v, i) return {} end) diff --git a/test/tests.luau b/test/tests.luau index 9a06fec..becea69 100644 --- a/test/tests.luau +++ b/test/tests.luau @@ -1147,7 +1147,10 @@ TEST("spring()", function() local output = spring(input) input(1) - vide.step(1e9) -- spring alpha at ~1 + vide.step(0.05) + CHECK(output() ~= input()) -- check spring is moving + vide.step(6) -- spring finished, should be internally removed from queue + CHECK(output() == input()) -- check spring is at target local count = -1 watch(function() @@ -1155,15 +1158,14 @@ TEST("spring()", function() count += 1 end) - vide.step(1) -- spring should be internally removed from spring queue - CHECK(count == 0) - + vide.step(1) -- attempt to cause another spring update + CHECK(count == 1) -- check no update occurs as spring is finished -- gc() -- perform full gc input(2) -- spring should be re-added to spring queue vide.step(0) -- process spring queue - CHECK(count == 1) -- check spring was rescheduled correctly + CHECK(count == 2) -- check spring was rescheduled correctly end end) diff --git a/todo.md b/todo.md index 5d020d9..51ad4d8 100644 --- a/todo.md +++ b/todo.md @@ -1,13 +1,16 @@ # todo +- cleanup codebase +- setup site, improve docs +- cleanup within `values()` and `indexes()` - strict mode - - warn when map returns primitive - + - better error reporting + - warn when `values()` returns primitive - Implement from solid - - onCleanup - - Index - - For - - untrack - - batch - - async/loading/suspense - - define order with nested properties + - [x] onCleanup > `cleanup()` + - [x] Index > `indexes()` + - [x] For > `values()` + - [ ] untrack + - [ ] batch + - [ ] async/loading/suspense +- define order with nested properties