perf: entities

This commit is contained in:
cha0s 2024-07-31 13:01:33 -05:00
parent cb3d9ad8c6
commit b53d7e3d35

View File

@ -1,7 +1,7 @@
import {AdjustmentFilter} from '@pixi/filter-adjustment'; import {AdjustmentFilter} from '@pixi/filter-adjustment';
import {GlowFilter} from '@pixi/filter-glow'; import {GlowFilter} from '@pixi/filter-glow';
import {Container} from '@pixi/react'; import {Container} from '@pixi/react';
import {useCallback, useEffect, useState} from 'react'; import {useCallback, useEffect, useRef, useState} from 'react';
import {usePacket} from '@/react/context/client.js'; import {usePacket} from '@/react/context/client.js';
import {useEcs, useEcsTick} from '@/react/context/ecs.js'; import {useEcs, useEcsTick} from '@/react/context/ecs.js';
@ -12,7 +12,7 @@ import Entity from './entity.jsx';
export default function Entities({monopolizers, particleWorker}) { export default function Entities({monopolizers, particleWorker}) {
const [ecs] = useEcs(); const [ecs] = useEcs();
const [entities, setEntities] = useState({}); const entities = useRef({});
const [mainEntity] = useMainEntity(); const [mainEntity] = useMainEntity();
const radians = useRadians(); const radians = useRadians();
const [willInteractWith, setWillInteractWith] = useState(0); const [willInteractWith, setWillInteractWith] = useState(0);
@ -20,31 +20,22 @@ export default function Entities({monopolizers, particleWorker}) {
new AdjustmentFilter(), new AdjustmentFilter(),
new GlowFilter({color: 0x0}), new GlowFilter({color: 0x0}),
]); ]);
const [, forceRender] = useState();
useEffect(() => { useEffect(() => {
if (!ecs || !particleWorker) { if (!ecs || !particleWorker) {
return; return;
} }
async function onMessage(diff) { async function onMessage(diff) {
await ecs.apply(diff.data); await ecs.apply(diff.data);
const deleted = {};
const updated = {};
for (const id in diff.data) { for (const id in diff.data) {
if (!diff.data[id]) { if (!diff.data[id]) {
deleted[id] = true; delete entities.current[id]
} }
else { else {
updated[id] = ecs.get(id); entities.current[id] = ecs.get(id);
} }
} }
setEntities((entities) => { forceRender(Math.random());
for (const id in deleted) {
delete entities[id];
}
return {
...entities,
...updated,
};
});
} }
particleWorker.addEventListener('message', onMessage); particleWorker.addEventListener('message', onMessage);
return () => { return () => {
@ -55,31 +46,21 @@ export default function Entities({monopolizers, particleWorker}) {
interactionFilters[0].brightness = (pulse * 0.75) + 1; interactionFilters[0].brightness = (pulse * 0.75) + 1;
interactionFilters[1].outerStrength = pulse * 0.5; interactionFilters[1].outerStrength = pulse * 0.5;
usePacket('EcsChange', async () => { usePacket('EcsChange', async () => {
setEntities({}); entities.current = {};
}); });
const onEcsTickEntities = useCallback((payload, ecs) => { const onEcsTickEntities = useCallback((payload, ecs) => {
const deleting = {};
const updating = {};
for (const id in payload) { for (const id in payload) {
if ('1' === id) { if ('1' === id) {
continue; continue;
} }
const update = payload[id]; const update = payload[id];
if (false === update) { if (false === update) {
deleting[id] = true; delete entities.current[id];
continue; continue;
} }
updating[id] = ecs.get(id); entities.current[id] = ecs.get(id);
} }
setEntities((entities) => { forceRender(Math.random());
for (const id in deleting) {
delete entities[id];
}
return {
...entities,
...updating,
};
});
}, []); }, []);
useEcsTick(onEcsTickEntities); useEcsTick(onEcsTickEntities);
const onEcsTickParticles = useCallback((payload) => { const onEcsTickParticles = useCallback((payload) => {
@ -101,12 +82,12 @@ export default function Entities({monopolizers, particleWorker}) {
}, [mainEntity]); }, [mainEntity]);
useEcsTick(onEcsTickInteractions); useEcsTick(onEcsTickInteractions);
const renderables = []; const renderables = [];
for (const id in entities) { for (const id in entities.current) {
const isHighlightedInteraction = 0 === monopolizers.length && id == willInteractWith; const isHighlightedInteraction = 0 === monopolizers.length && id == willInteractWith;
renderables.push( renderables.push(
<Entity <Entity
filters={isHighlightedInteraction ? interactionFilters : null} filters={isHighlightedInteraction ? interactionFilters : null}
entity={entities[id]} entity={entities.current[id]}
key={id} key={id}
/> />
); );