Skip to content

Commit

Permalink
debounce update streams before subscribing
Browse files Browse the repository at this point in the history
  • Loading branch information
holic committed Oct 2, 2023
1 parent 17b5d20 commit cac2a38
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 8 deletions.
17 changes: 13 additions & 4 deletions packages/react/src/useComponentValue.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import {
Component,
ComponentUpdate,
ComponentValue,
defineQuery,
Entity,
getComponentValue,
Has,
isComponentUpdate,
Schema,
UpdateType,
} from "@latticexyz/recs";
import { useEffect, useState } from "react";
import { debounceTime, filter } from "rxjs";

export function useComponentValue<S extends Schema>(
component: Component<S>,
Expand All @@ -34,12 +37,18 @@ export function useComponentValue<S extends Schema>(
if (entity == null) return;

const queryResult = defineQuery([Has(component)], { runOnInit: false });
const subscription = queryResult.update$.subscribe((update) => {
if (isComponentUpdate(update, component) && update.entity === entity) {
const subscription = queryResult.update$
.pipe(
filter(
(update): update is ComponentUpdate<S> & { type: UpdateType } =>
isComponentUpdate(update, component) && update.entity === entity
),
debounceTime(10)
)
.subscribe((update) => {
const [nextValue] = update.value;
setValue(nextValue);
}
});
});
return () => subscription.unsubscribe();
}, [component, entity]);

Expand Down
4 changes: 2 additions & 2 deletions packages/react/src/useEntityQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { defineQuery, QueryFragment } from "@latticexyz/recs";
import { useEffect, useMemo, useState } from "react";
import { useDeepMemo } from "./utils/useDeepMemo";
import isEqual from "fast-deep-equal";
import { distinctUntilChanged, map } from "rxjs";
import { debounceTime, distinctUntilChanged, map } from "rxjs";

// This does a little more rendering than is necessary when arguments change,
// but at least it's giving correct results now. Will optimize later!
Expand All @@ -29,7 +29,7 @@ export function useEntityQuery(fragments: QueryFragment[], options?: { updateOnV
// re-render only on entity array changes
observable = observable.pipe(distinctUntilChanged((a, b) => isEqual(a, b)));
}
const subscription = observable.subscribe((entities) => setEntities(entities));
const subscription = observable.pipe(debounceTime(10)).subscribe((entities) => setEntities(entities));
return () => subscription.unsubscribe();
}, [query, updateOnValueChange]);

Expand Down
4 changes: 2 additions & 2 deletions packages/recs/src/System.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { concat, EMPTY, from, Observable } from "rxjs";
import { concat, debounceTime, EMPTY, from, Observable } from "rxjs";
import { getComponentEntities, removeComponent, setComponent } from "./Component";
import { UpdateType } from "./constants";
import { defineEnterQuery, defineExitQuery, defineQuery, defineUpdateQuery } from "./Query";
Expand All @@ -17,7 +17,7 @@ import { toUpdateStream } from "./utils";
* @param system System function to run on updates of the `observable$`. System function gets passed the update events from the `observable$`.
*/
export function defineRxSystem<T>(world: World, observable$: Observable<T>, system: (event: T) => void) {
const subscription = observable$.subscribe(system);
const subscription = observable$.pipe(debounceTime(10)).subscribe(system);
world.registerDisposer(() => subscription?.unsubscribe());
}

Expand Down

0 comments on commit cac2a38

Please sign in to comment.