Skip to content

Instantly share code, notes, and snippets.

@breqdev
Last active February 11, 2022 03:26
Show Gist options
  • Save breqdev/9878a0c3151822c9368c684b0a269308 to your computer and use it in GitHub Desktop.
Save breqdev/9878a0c3151822c9368c684b0a269308 to your computer and use it in GitHub Desktop.
React hook to keep track of a "dirty" flag and manage an interval which clears it.
export default function ArmSliderControl() {
const [joints, setJoints] = React.useState(JOINTS.map(() => 0));
const publish = useRosPublisher(topics.arm.positions);
const setDirty = useDirtyInterval(() => {
publish({
header: {
seq: 0,
stamp: {
secs: Math.round(new Date().getTime() / 1000),
nsecs: new Date().getMilliseconds() * 1000000,
},
frame_id: '',
},
name: JOINTS.map((joint) => joint.label),
position: joints,
velocity: JOINTS.map(() => 0),
effort: JOINTS.map(() => 0),
});
}, 100);
const handleChange = (index: number) => (value: number) => {
setJoints(joints.map((joint, i) => (i === index ? value : joint)));
setDirty();
};
const sliders = JOINTS.map(({ label, min, max }, index) => (
<Slider
key={label}
label={label}
min={min}
max={max}
value={joints[index]}
onChange={handleChange(index)}
/>
));
return (
<MonitorFrame label="Arm Sliders" height={2} width={1}>
<div className="flex flex-col gap-4">{sliders}</div>
</MonitorFrame>
);
}
export default function useDirtyInterval(handler: () => void, time: number) {
const dirtyRef = React.useRef(false);
const handlerRef = React.useRef<() => void>();
React.useEffect(() => {
handlerRef.current = handler;
}, [handler]);
React.useEffect(() => {
const interval = setInterval(() => {
if (dirtyRef.current) {
dirtyRef.current = false;
handlerRef.current?.();
}
}, time);
return () => clearInterval(interval);
}, [time]);
return () => (dirtyRef.current = true);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment