import { useEffect, useRef, useState } from 'react'; import { useRos } from '../RosConnection'; import { DefaultMessageType, subscribe, unsubscribe } from './getTopic'; import { SubscriberProps } from './Subscriber'; export type UseSubscriptionProps = SubscriberProps & { /** * Function to determine if messages are the same to cut down on renders. Do not set if you want every message. * @param o1 The existing message * @param o2 The new incoming message * @return Standard comparison result, `true` or `0` if equal, `false` or non-zero otherwise. */ compareFunc?: ( o1: TMessage | null | undefined, o2: TMessage | null | undefined, ) => boolean | number; }; export function useSubscription( props: UseSubscriptionProps, ): TMessage | null { const ros = useRos(); const { topic, messageType, throttleRate, latch, queueLength, queueSize, customCallback, compareFunc, } = props; const [message, setMessage] = useState( props.messageInitialValue ?? null, ); const messageRef = useRef(message); useEffect(() => { const updateMessage = (msg: TMessage) => { setMessage(msg); messageRef.current = msg; }; const messageCallback = (newMsg: TMessage) => { if (compareFunc) { const compareRes = compareFunc(messageRef.current, newMsg); // The values are the same, return. if (compareRes === true || compareRes === 0) { return; } } if (customCallback) { customCallback(newMsg); } updateMessage(newMsg); }; const subscription = subscribe( ros, { topic, messageType, throttleRate, latch, queueLength, queueSize, }, messageCallback, ); return () => { unsubscribe(subscription, messageCallback); }; }, [ ros, topic, messageType, throttleRate, latch, queueLength, queueSize, customCallback, compareFunc, ]); return message; }