mirror of
https://github.com/littensy/charm.git
synced 2026-10-20 17:51:37 +00:00
perf: run observe fn in untracked
This commit is contained in:
parent
e3e6209891
commit
27c7f5a6fd
1 changed files with 18 additions and 18 deletions
|
|
@ -178,8 +178,8 @@ end
|
||||||
@param cleanups List of cleanup functions
|
@param cleanups List of cleanup functions
|
||||||
]]
|
]]
|
||||||
local function runCleanups(cleanups: { Cleanup })
|
local function runCleanups(cleanups: { Cleanup })
|
||||||
for key, cleanup in cleanups do
|
for index, cleanup in cleanups do
|
||||||
cleanups[key] = nil
|
cleanups[index] = nil
|
||||||
|
|
||||||
local prevSub = setActiveSub(nil)
|
local prevSub = setActiveSub(nil)
|
||||||
local success, result: any = pcall(cleanup)
|
local success, result: any = pcall(cleanup)
|
||||||
|
|
@ -418,10 +418,11 @@ end
|
||||||
Called when a node is not being watched by any subscribers. Cleans up the
|
Called when a node is not being watched by any subscribers. Cleans up the
|
||||||
node's dependencies and performs the necessary cleanup operations:
|
node's dependencies and performs the necessary cleanup operations:
|
||||||
|
|
||||||
- Computed signals: Unlink dependencies and mark as dirty for potential future updates
|
- Computed signals: Unlink dependencies and mark as dirty for potential
|
||||||
|
future updates
|
||||||
- Effects/scopes: Perform full cleanup to free resources
|
- Effects/scopes: Perform full cleanup to free resources
|
||||||
|
|
||||||
@param node Reactive node (computed or effect/scope)
|
@param node Reactive node (computed, effect, or effect scope)
|
||||||
]]
|
]]
|
||||||
local function unwatched(node: ReactiveNode)
|
local function unwatched(node: ReactiveNode)
|
||||||
if bit32.band(node.flags, MUTABLE) == 0 then
|
if bit32.band(node.flags, MUTABLE) == 0 then
|
||||||
|
|
@ -649,7 +650,7 @@ end
|
||||||
signals created within it so that they can be disposed together.
|
signals created within it so that they can be disposed together.
|
||||||
|
|
||||||
@param fn Function that creates effects within the scope
|
@param fn Function that creates effects within the scope
|
||||||
@param detached If true, the scope will not be tracked by the parent effect/scope
|
@param detached If true, the scope will not be tracked by the parent effect or scope
|
||||||
@return A cleanup function that stops all effects in the scope
|
@return A cleanup function that stops all effects in the scope
|
||||||
@see https://github.com/littensy/charm?tab=readme-ov-file#effectscopecallback-detached
|
@see https://github.com/littensy/charm?tab=readme-ov-file#effectscopecallback-detached
|
||||||
]]
|
]]
|
||||||
|
|
@ -719,7 +720,7 @@ end
|
||||||
set to `true`.
|
set to `true`.
|
||||||
|
|
||||||
@param fn Function to run during cleanup
|
@param fn Function to run during cleanup
|
||||||
@param failSilently If true, silences the warning when called outside an effect/scope
|
@param failSilently If true, silences the warning when called outside an effect or scope
|
||||||
@see https://github.com/littensy/charm?tab=readme-ov-file#oncleanupcallback-failsilently
|
@see https://github.com/littensy/charm?tab=readme-ov-file#oncleanupcallback-failsilently
|
||||||
]]
|
]]
|
||||||
local function onCleanup(fn: Cleanup, failSilently: boolean?)
|
local function onCleanup(fn: Cleanup, failSilently: boolean?)
|
||||||
|
|
@ -788,7 +789,7 @@ end
|
||||||
@param fn Function to check
|
@param fn Function to check
|
||||||
@return `true` if `fn` is a signal getter, computed signal, or atom function, `false` otherwise
|
@return `true` if `fn` is a signal getter, computed signal, or atom function, `false` otherwise
|
||||||
]]
|
]]
|
||||||
local function isSignalOrComputed(fn: Getter<any>): boolean
|
local function isSignal(fn: Getter<any>): boolean
|
||||||
local name = debug.info(fn, "n")
|
local name = debug.info(fn, "n")
|
||||||
return name == "readSignal" or name == "computedOper" or name == "atomOper"
|
return name == "readSignal" or name == "computedOper" or name == "atomOper"
|
||||||
end
|
end
|
||||||
|
|
@ -804,7 +805,7 @@ end
|
||||||
@see https://github.com/littensy/charm?tab=readme-ov-file#listengetter-callback
|
@see https://github.com/littensy/charm?tab=readme-ov-file#listengetter-callback
|
||||||
]]
|
]]
|
||||||
local function listen<T>(getter: Getter<T>, fn: (state: T, lastState: T?) -> ()): Cleanup
|
local function listen<T>(getter: Getter<T>, fn: (state: T, lastState: T?) -> ()): Cleanup
|
||||||
local tracked: Getter<T> = if isSignalOrComputed(getter) then getter else computed(getter)
|
local tracked: Getter<T> = if isSignal(getter) then getter else computed(getter)
|
||||||
local current: T
|
local current: T
|
||||||
|
|
||||||
return effect(function()
|
return effect(function()
|
||||||
|
|
@ -825,7 +826,7 @@ end
|
||||||
@see https://github.com/littensy/charm?tab=readme-ov-file#subscribegetter-callback
|
@see https://github.com/littensy/charm?tab=readme-ov-file#subscribegetter-callback
|
||||||
]]
|
]]
|
||||||
local function subscribe<T>(getter: Getter<T>, fn: (state: T, lastState: T) -> ()): Cleanup
|
local function subscribe<T>(getter: Getter<T>, fn: (state: T, lastState: T) -> ()): Cleanup
|
||||||
local tracked: Getter<T> = if isSignalOrComputed(getter) then getter else computed(getter)
|
local tracked: Getter<T> = if isSignal(getter) then getter else computed(getter)
|
||||||
local current: T
|
local current: T
|
||||||
local firstRun = true
|
local firstRun = true
|
||||||
|
|
||||||
|
|
@ -841,9 +842,9 @@ local function subscribe<T>(getter: Getter<T>, fn: (state: T, lastState: T) -> (
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
Calls the callback function for each unique key in the table returned by the
|
Calls the callback function for each unique key in the table returned by
|
||||||
getter. The callback is called once for each key, and again when a new key
|
the getter. The callback is called once for each key, and again when a new
|
||||||
is added.
|
key is added.
|
||||||
|
|
||||||
The callback may return a cleanup function, which will be called when the
|
The callback may return a cleanup function, which will be called when the
|
||||||
key is removed or the `observe()` effect is disposed. Effects created
|
key is removed or the `observe()` effect is disposed. Effects created
|
||||||
|
|
@ -885,10 +886,9 @@ local function observe<K, V>(getter: Getter<{ [K]: V }>, fn: (item: V, key: K) -
|
||||||
|
|
||||||
return effectScope(function()
|
return effectScope(function()
|
||||||
effect(function()
|
effect(function()
|
||||||
-- Batch so that side effects run after all scopes are created.
|
-- Wrap in untracked so that calling fn inside updateScopes does
|
||||||
-- This ensures that a scope creating or removing items doesn't
|
-- not register dependencies to this effect
|
||||||
-- interfere with the current update cycle.
|
untracked(updateScopes, getter())
|
||||||
batch(updateScopes, getter())
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
return function()
|
return function()
|
||||||
|
|
@ -930,8 +930,8 @@ local function mapped<KI, VI, KO, VO>(getter: Getter<{ [KI]: VI }>, mapper: (VI,
|
||||||
return valueOut, if keyOut == nil then key :: any else keyOut
|
return valueOut, if keyOut == nil then key :: any else keyOut
|
||||||
end
|
end
|
||||||
|
|
||||||
return computed(function(lastOutput)
|
return computed(function(lastOutput: { [KO]: VO }?): { [KO]: VO }
|
||||||
local nextOutput = lastOutput or {}
|
local nextOutput: { [KO]: VO } = lastOutput or {}
|
||||||
local prevInput = nextInput
|
local prevInput = nextInput
|
||||||
nextInput = getter()
|
nextInput = getter()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue