perf: updates

This commit is contained in:
cha0s 2024-09-22 02:16:32 -05:00
parent 5492ec32bd
commit 73b7a9e0a5
6 changed files with 63 additions and 50 deletions

View File

@ -2,6 +2,7 @@ import {useCallback, useState} from 'react';
import {usePacket} from '@/react/context/client.js';
import {useEcsTick} from '@/react/context/ecs.js';
import {RESOLUTION} from '@/util/constants.js';
import {parseLetters} from '@/util/dialogue.js';
import Damages from './damages.jsx';
@ -14,6 +15,10 @@ export default function Entities({
setChatMessages,
}) {
const [entities, setEntities] = useState({});
const translatedCamera = {
x: Math.round((camera.x * scale) - RESOLUTION.x / 2),
y: Math.round((camera.y * scale) - RESOLUTION.y / 2),
};
usePacket('EcsChange', async () => {
setEntities({});
});
@ -98,7 +103,7 @@ export default function Entities({
for (const id in entities) {
renderables.push(
<Entity
camera={camera}
camera={translatedCamera}
entity={entities[id]}
key={id}
scale={scale}
@ -109,8 +114,8 @@ export default function Entities({
<div
style={{
translate: `
calc(-1px * ${camera.x})
calc(-1px * ${camera.y})
calc(-1px * ${translatedCamera.x})
calc(-1px * ${translatedCamera.y})
`,
}}
>

View File

@ -10,7 +10,7 @@ import TargetingGrid from './targeting-grid.jsx';
import TileLayer from './tile-layer.jsx';
import Water from './water.jsx';
export default function Ecs({camera, monopolizers, particleWorker, scale}) {
export default function Ecs({monopolizers, particleWorker}) {
const app = useApp();
const mainEntityRef = useMainEntity();
const [layers, setLayers] = useState([]);
@ -120,17 +120,22 @@ export default function Ecs({camera, monopolizers, particleWorker, scale}) {
}
if (entity) {
const {Direction, Position, Wielder} = entity;
setPosition(Position.toJSON());
setProjected(Wielder.activeItem()?.project(Position.tile, Direction.quantize(4)));
setPosition((position) => {
return position.x !== Position.x || position.y !== Position.y
? Position.toJSON()
: position;
});
setProjected((projected) => {
const newProjected = Wielder.activeItem()?.project(Position.tile, Direction.quantize(4));
return JSON.stringify(projected) !== JSON.stringify(newProjected)
? newProjected
: projected;
});
}
}, [app.ambientLight, mainEntityRef]);
useEcsTick(onEcsTick);
return (
<Container
scale={scale}
x={-camera.x}
y={-camera.y}
>
<>
<Container>
{layers.map((layer, i) => (
<TileLayer
@ -162,6 +167,6 @@ export default function Ecs({camera, monopolizers, particleWorker, scale}) {
monopolizers={monopolizers}
particleWorker={particleWorker}
/>
</Container>
</>
)
}

View File

@ -1,14 +1,13 @@
import {SCALE_MODES} from '@pixi/constants';
import {BaseTexture, extensions} from '@pixi/core';
import {Stage as PixiStage} from '@pixi/react';
import {createElement, useContext} from 'react';
import {Container, Stage as PixiStage} from '@pixi/react';
import {createElement, forwardRef, memo, useContext} from 'react';
import AssetsContext from '@/react/context/assets.js';
import ClientContext from '@/react/context/client.js';
import DebugContext from '@/react/context/debug.js';
import EcsContext from '@/react/context/ecs.js';
import MainEntityContext from '@/react/context/main-entity.js';
import RadiansContext from '@/react/context/radians.js';
import {RESOLUTION} from '@/util/constants.js';
import Ecs from './ecs.jsx';
@ -28,7 +27,6 @@ const Contexts = [
DebugContext,
EcsContext,
MainEntityContext,
RadiansContext,
];
const ContextBridge = ({children, render}) => {
@ -57,7 +55,7 @@ export const Stage = ({children, ...props}) => {
);
};
export default function Pixi({camera, monopolizers, particleWorker, scale}) {
function Pixi({monopolizers, particleWorker}, ref) {
return (
<Stage
className={styles.stage}
@ -67,13 +65,16 @@ export default function Pixi({camera, monopolizers, particleWorker, scale}) {
background: 0x0,
}}
>
<Ecs
camera={camera}
monopolizers={monopolizers}
particleWorker={particleWorker}
scale={scale}
/>
<Container
ref={ref}
>
<Ecs
monopolizers={monopolizers}
particleWorker={particleWorker}
/>
</Container>
</Stage>
);
}
export default memo(forwardRef(Pixi));

View File

@ -36,6 +36,7 @@ function Ui({disconnected}) {
const chatInputRef = useRef();
const latestTick = useRef();
const gameRef = useRef();
const pixiRef = useRef();
const mainEntityRef = useMainEntity();
const [, setDebug] = useDebug();
const ecsRef = useEcs();
@ -326,16 +327,15 @@ function Ui({disconnected}) {
}
}, []);
useEcsTick(onEcsTickAabbs);
const onEcsTickCamera = useCallback((payload, ecs) => {
if (mainEntityRef.current) {
const mainEntityEntity = ecs.get(mainEntityRef.current);
const x = Math.round((mainEntityEntity.Camera.x * scale) - RESOLUTION.x / 2);
const y = Math.round((mainEntityEntity.Camera.y * scale) - RESOLUTION.y / 2);
if (x !== camera.x || y !== camera.y) {
setCamera({x, y});
}
const onEcsTickCamera = useCallback((payload) => {
if (mainEntityRef.current && payload[mainEntityRef.current]?.Camera) {
setCamera((camera) => ({
x: camera.x,
y: camera.y,
...payload[mainEntityRef.current].Camera,
}))
}
}, [camera, mainEntityRef, scale]);
}, [mainEntityRef]);
useEcsTick(onEcsTickCamera);
useEffect(() => {
function onContextMenu(event) {
@ -389,6 +389,14 @@ function Ui({disconnected}) {
payload: {type: 'swapSlots', value: [0, externalInventory, i]},
});
}, [client, externalInventory]);
useEffect(() => {
if (!pixiRef.current) {
return;
}
pixiRef.current.scale.set(scale);
pixiRef.current.x = -Math.round((camera.x * scale) - RESOLUTION.x / 2);
pixiRef.current.y = -Math.round((camera.y * scale) - RESOLUTION.y / 2);
}, [camera, scale])
return (
<div
className={styles.ui}
@ -494,10 +502,9 @@ function Ui({disconnected}) {
ref={gameRef}
>
<Pixi
camera={camera}
monopolizers={monopolizers.current}
particleWorker={particleWorker}
scale={scale}
ref={pixiRef}
/>
<Dom>
<HotBar

View File

@ -1,9 +1,14 @@
import {createContext, useContext} from 'react';
import {useCallback, useState} from 'react';
const context = createContext();
export default context;
import useAnimationFrame from '@/react/hooks/use-animation-frame.js';
import {TAU} from '@/util/math.js';
export function useRadians() {
return useContext(context);
const [radians, setRadians] = useState(0);
useAnimationFrame(
useCallback((elapsed) => {
setRadians((radians) => radians + (elapsed * TAU));
}, []),
);
return radians;
}

View File

@ -7,9 +7,6 @@ import ClientContext from '@/react/context/client.js';
import DebugContext from '@/react/context/debug.js';
import EcsContext from '@/react/context/ecs.js';
import MainEntityContext from '@/react/context/main-entity.js';
import RadiansContext from '@/react/context/radians.js';
import useAnimationFrame from '@/react/hooks/use-animation-frame.js';
import {TAU} from '@/util/math.js';
import ClientEcs from '@/react/components/client-ecs.js';
@ -25,11 +22,6 @@ export default function PlaySpecific() {
const [disconnected, setDisconnected] = useState(false);
const params = useParams();
const [type, url] = params['*'].split('/');
const [radians, setRadians] = useState(0);
const spin = useCallback((elapsed) => {
setRadians((radians) => radians + (elapsed * TAU));
}, []);
useAnimationFrame(spin);
useEffect(() => {
if (!Client) {
return;
@ -174,9 +166,7 @@ export default function PlaySpecific() {
<EcsContext.Provider value={ecsRef}>
<DebugContext.Provider value={debugTuple}>
<AssetsContext.Provider value={assetsTuple}>
<RadiansContext.Provider value={radians}>
<Ui disconnected={disconnected} />
</RadiansContext.Provider>
<Ui disconnected={disconnected} />
</AssetsContext.Provider>
</DebugContext.Provider>
</EcsContext.Provider>