From e163948c97211bfdfd9c37e1036ed3a7a591349f Mon Sep 17 00:00:00 2001 From: g1mmethemoney Date: Fri, 30 Aug 2024 12:24:59 +0300 Subject: [PATCH 1/2] fix(use-async-effect): unknown -> any --- src/use-async-effect/use-async-effect.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/use-async-effect/use-async-effect.ts b/src/use-async-effect/use-async-effect.ts index aaa351d..e4cb075 100644 --- a/src/use-async-effect/use-async-effect.ts +++ b/src/use-async-effect/use-async-effect.ts @@ -7,7 +7,7 @@ import { useEffect } from "@rbxts/react"; * @param effect The async effect to run. * @param deps The dependencies to run the effect on. */ -export function useAsyncEffect(effect: () => Promise, deps?: unknown[]) { +export function useAsyncEffect(effect: () => Promise, deps?: unknown[]) { useEffect(() => { const promise = effect(); From ecc243f74181b3320abc47fd578e64a9e6f5da7d Mon Sep 17 00:00:00 2001 From: wad4444 <77159113+wad4444@users.noreply.github.com> Date: Sun, 9 Feb 2025 12:48:55 +0300 Subject: [PATCH 2/2] perf: use a single heartbeat connection for all `useMotion` hooks --- src/use-motion/use-motion.ts | 45 +++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/src/use-motion/use-motion.ts b/src/use-motion/use-motion.ts index 8f8e36c..e0c3095 100644 --- a/src/use-motion/use-motion.ts +++ b/src/use-motion/use-motion.ts @@ -1,10 +1,33 @@ import type { Binding } from "@rbxts/react"; -import { useBinding, useMemo } from "@rbxts/react"; +import { useBinding, useEffect, useMemo } from "@rbxts/react"; import type { Motion, MotionGoal } from "@rbxts/ripple"; import { createMotion } from "@rbxts/ripple"; -import { useEventListener } from "../use-event-listener"; import { RunService } from "@rbxts/services"; +const callbacks = new Set<(dt: number) => void>(); +let connection: RBXScriptConnection | undefined; + +function connect(callback: (dt: number) => void) { + callbacks.add(callback); + + if (!connection) { + connection = RunService.Heartbeat.Connect((dt) => { + for (const callback of callbacks) { + callback(dt); + } + }); + } +} + +function disconnect(callback: (dt: number) => void) { + callbacks.delete(callback); + + if (callbacks.isEmpty()) { + connection?.Disconnect(); + connection = undefined; + } +} + export function useMotion(initialValue: number): LuaTuple<[Binding, Motion]>; export function useMotion(initialValue: T): LuaTuple<[Binding, Motion]>; export function useMotion(initialValue: T) { @@ -14,13 +37,19 @@ export function useMotion(initialValue: T) { const [binding, setValue] = useBinding(initialValue); - useEventListener(RunService.Heartbeat, (delta) => { - const value = motion.step(delta); + useEffect(() => { + const callback = (delta: number) => { + const value = motion.step(delta); + + if (value !== binding.getValue()) { + setValue(value); + } + }; - if (value !== binding.getValue()) { - setValue(value); - } - }); + connect(callback); + + return () => disconnect(callback); + }, []); return $tuple(binding, motion); }