perf: updates
This commit is contained in:
parent
5492ec32bd
commit
73b7a9e0a5
|
@ -2,6 +2,7 @@ import {useCallback, useState} from 'react';
|
||||||
|
|
||||||
import {usePacket} from '@/react/context/client.js';
|
import {usePacket} from '@/react/context/client.js';
|
||||||
import {useEcsTick} from '@/react/context/ecs.js';
|
import {useEcsTick} from '@/react/context/ecs.js';
|
||||||
|
import {RESOLUTION} from '@/util/constants.js';
|
||||||
import {parseLetters} from '@/util/dialogue.js';
|
import {parseLetters} from '@/util/dialogue.js';
|
||||||
|
|
||||||
import Damages from './damages.jsx';
|
import Damages from './damages.jsx';
|
||||||
|
@ -14,6 +15,10 @@ export default function Entities({
|
||||||
setChatMessages,
|
setChatMessages,
|
||||||
}) {
|
}) {
|
||||||
const [entities, setEntities] = useState({});
|
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 () => {
|
usePacket('EcsChange', async () => {
|
||||||
setEntities({});
|
setEntities({});
|
||||||
});
|
});
|
||||||
|
@ -98,7 +103,7 @@ export default function Entities({
|
||||||
for (const id in entities) {
|
for (const id in entities) {
|
||||||
renderables.push(
|
renderables.push(
|
||||||
<Entity
|
<Entity
|
||||||
camera={camera}
|
camera={translatedCamera}
|
||||||
entity={entities[id]}
|
entity={entities[id]}
|
||||||
key={id}
|
key={id}
|
||||||
scale={scale}
|
scale={scale}
|
||||||
|
@ -109,8 +114,8 @@ export default function Entities({
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
translate: `
|
translate: `
|
||||||
calc(-1px * ${camera.x})
|
calc(-1px * ${translatedCamera.x})
|
||||||
calc(-1px * ${camera.y})
|
calc(-1px * ${translatedCamera.y})
|
||||||
`,
|
`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
|
@ -10,7 +10,7 @@ import TargetingGrid from './targeting-grid.jsx';
|
||||||
import TileLayer from './tile-layer.jsx';
|
import TileLayer from './tile-layer.jsx';
|
||||||
import Water from './water.jsx';
|
import Water from './water.jsx';
|
||||||
|
|
||||||
export default function Ecs({camera, monopolizers, particleWorker, scale}) {
|
export default function Ecs({monopolizers, particleWorker}) {
|
||||||
const app = useApp();
|
const app = useApp();
|
||||||
const mainEntityRef = useMainEntity();
|
const mainEntityRef = useMainEntity();
|
||||||
const [layers, setLayers] = useState([]);
|
const [layers, setLayers] = useState([]);
|
||||||
|
@ -120,17 +120,22 @@ export default function Ecs({camera, monopolizers, particleWorker, scale}) {
|
||||||
}
|
}
|
||||||
if (entity) {
|
if (entity) {
|
||||||
const {Direction, Position, Wielder} = entity;
|
const {Direction, Position, Wielder} = entity;
|
||||||
setPosition(Position.toJSON());
|
setPosition((position) => {
|
||||||
setProjected(Wielder.activeItem()?.project(Position.tile, Direction.quantize(4)));
|
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]);
|
}, [app.ambientLight, mainEntityRef]);
|
||||||
useEcsTick(onEcsTick);
|
useEcsTick(onEcsTick);
|
||||||
return (
|
return (
|
||||||
<Container
|
<>
|
||||||
scale={scale}
|
|
||||||
x={-camera.x}
|
|
||||||
y={-camera.y}
|
|
||||||
>
|
|
||||||
<Container>
|
<Container>
|
||||||
{layers.map((layer, i) => (
|
{layers.map((layer, i) => (
|
||||||
<TileLayer
|
<TileLayer
|
||||||
|
@ -162,6 +167,6 @@ export default function Ecs({camera, monopolizers, particleWorker, scale}) {
|
||||||
monopolizers={monopolizers}
|
monopolizers={monopolizers}
|
||||||
particleWorker={particleWorker}
|
particleWorker={particleWorker}
|
||||||
/>
|
/>
|
||||||
</Container>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
import {SCALE_MODES} from '@pixi/constants';
|
import {SCALE_MODES} from '@pixi/constants';
|
||||||
import {BaseTexture, extensions} from '@pixi/core';
|
import {BaseTexture, extensions} from '@pixi/core';
|
||||||
import {Stage as PixiStage} from '@pixi/react';
|
import {Container, Stage as PixiStage} from '@pixi/react';
|
||||||
import {createElement, useContext} from 'react';
|
import {createElement, forwardRef, memo, useContext} from 'react';
|
||||||
|
|
||||||
import AssetsContext from '@/react/context/assets.js';
|
import AssetsContext from '@/react/context/assets.js';
|
||||||
import ClientContext from '@/react/context/client.js';
|
import ClientContext from '@/react/context/client.js';
|
||||||
import DebugContext from '@/react/context/debug.js';
|
import DebugContext from '@/react/context/debug.js';
|
||||||
import EcsContext from '@/react/context/ecs.js';
|
import EcsContext from '@/react/context/ecs.js';
|
||||||
import MainEntityContext from '@/react/context/main-entity.js';
|
import MainEntityContext from '@/react/context/main-entity.js';
|
||||||
import RadiansContext from '@/react/context/radians.js';
|
|
||||||
import {RESOLUTION} from '@/util/constants.js';
|
import {RESOLUTION} from '@/util/constants.js';
|
||||||
|
|
||||||
import Ecs from './ecs.jsx';
|
import Ecs from './ecs.jsx';
|
||||||
|
@ -28,7 +27,6 @@ const Contexts = [
|
||||||
DebugContext,
|
DebugContext,
|
||||||
EcsContext,
|
EcsContext,
|
||||||
MainEntityContext,
|
MainEntityContext,
|
||||||
RadiansContext,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const ContextBridge = ({children, render}) => {
|
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 (
|
return (
|
||||||
<Stage
|
<Stage
|
||||||
className={styles.stage}
|
className={styles.stage}
|
||||||
|
@ -67,13 +65,16 @@ export default function Pixi({camera, monopolizers, particleWorker, scale}) {
|
||||||
background: 0x0,
|
background: 0x0,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Ecs
|
<Container
|
||||||
camera={camera}
|
ref={ref}
|
||||||
monopolizers={monopolizers}
|
>
|
||||||
particleWorker={particleWorker}
|
<Ecs
|
||||||
scale={scale}
|
monopolizers={monopolizers}
|
||||||
/>
|
particleWorker={particleWorker}
|
||||||
|
/>
|
||||||
|
</Container>
|
||||||
</Stage>
|
</Stage>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default memo(forwardRef(Pixi));
|
||||||
|
|
|
@ -36,6 +36,7 @@ function Ui({disconnected}) {
|
||||||
const chatInputRef = useRef();
|
const chatInputRef = useRef();
|
||||||
const latestTick = useRef();
|
const latestTick = useRef();
|
||||||
const gameRef = useRef();
|
const gameRef = useRef();
|
||||||
|
const pixiRef = useRef();
|
||||||
const mainEntityRef = useMainEntity();
|
const mainEntityRef = useMainEntity();
|
||||||
const [, setDebug] = useDebug();
|
const [, setDebug] = useDebug();
|
||||||
const ecsRef = useEcs();
|
const ecsRef = useEcs();
|
||||||
|
@ -326,16 +327,15 @@ function Ui({disconnected}) {
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
useEcsTick(onEcsTickAabbs);
|
useEcsTick(onEcsTickAabbs);
|
||||||
const onEcsTickCamera = useCallback((payload, ecs) => {
|
const onEcsTickCamera = useCallback((payload) => {
|
||||||
if (mainEntityRef.current) {
|
if (mainEntityRef.current && payload[mainEntityRef.current]?.Camera) {
|
||||||
const mainEntityEntity = ecs.get(mainEntityRef.current);
|
setCamera((camera) => ({
|
||||||
const x = Math.round((mainEntityEntity.Camera.x * scale) - RESOLUTION.x / 2);
|
x: camera.x,
|
||||||
const y = Math.round((mainEntityEntity.Camera.y * scale) - RESOLUTION.y / 2);
|
y: camera.y,
|
||||||
if (x !== camera.x || y !== camera.y) {
|
...payload[mainEntityRef.current].Camera,
|
||||||
setCamera({x, y});
|
}))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, [camera, mainEntityRef, scale]);
|
}, [mainEntityRef]);
|
||||||
useEcsTick(onEcsTickCamera);
|
useEcsTick(onEcsTickCamera);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function onContextMenu(event) {
|
function onContextMenu(event) {
|
||||||
|
@ -389,6 +389,14 @@ function Ui({disconnected}) {
|
||||||
payload: {type: 'swapSlots', value: [0, externalInventory, i]},
|
payload: {type: 'swapSlots', value: [0, externalInventory, i]},
|
||||||
});
|
});
|
||||||
}, [client, externalInventory]);
|
}, [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 (
|
return (
|
||||||
<div
|
<div
|
||||||
className={styles.ui}
|
className={styles.ui}
|
||||||
|
@ -494,10 +502,9 @@ function Ui({disconnected}) {
|
||||||
ref={gameRef}
|
ref={gameRef}
|
||||||
>
|
>
|
||||||
<Pixi
|
<Pixi
|
||||||
camera={camera}
|
|
||||||
monopolizers={monopolizers.current}
|
monopolizers={monopolizers.current}
|
||||||
particleWorker={particleWorker}
|
particleWorker={particleWorker}
|
||||||
scale={scale}
|
ref={pixiRef}
|
||||||
/>
|
/>
|
||||||
<Dom>
|
<Dom>
|
||||||
<HotBar
|
<HotBar
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
import {createContext, useContext} from 'react';
|
import {useCallback, useState} from 'react';
|
||||||
|
|
||||||
const context = createContext();
|
import useAnimationFrame from '@/react/hooks/use-animation-frame.js';
|
||||||
|
import {TAU} from '@/util/math.js';
|
||||||
export default context;
|
|
||||||
|
|
||||||
export function useRadians() {
|
export function useRadians() {
|
||||||
return useContext(context);
|
const [radians, setRadians] = useState(0);
|
||||||
|
useAnimationFrame(
|
||||||
|
useCallback((elapsed) => {
|
||||||
|
setRadians((radians) => radians + (elapsed * TAU));
|
||||||
|
}, []),
|
||||||
|
);
|
||||||
|
return radians;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,6 @@ import ClientContext from '@/react/context/client.js';
|
||||||
import DebugContext from '@/react/context/debug.js';
|
import DebugContext from '@/react/context/debug.js';
|
||||||
import EcsContext from '@/react/context/ecs.js';
|
import EcsContext from '@/react/context/ecs.js';
|
||||||
import MainEntityContext from '@/react/context/main-entity.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';
|
import ClientEcs from '@/react/components/client-ecs.js';
|
||||||
|
|
||||||
|
@ -25,11 +22,6 @@ export default function PlaySpecific() {
|
||||||
const [disconnected, setDisconnected] = useState(false);
|
const [disconnected, setDisconnected] = useState(false);
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const [type, url] = params['*'].split('/');
|
const [type, url] = params['*'].split('/');
|
||||||
const [radians, setRadians] = useState(0);
|
|
||||||
const spin = useCallback((elapsed) => {
|
|
||||||
setRadians((radians) => radians + (elapsed * TAU));
|
|
||||||
}, []);
|
|
||||||
useAnimationFrame(spin);
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!Client) {
|
if (!Client) {
|
||||||
return;
|
return;
|
||||||
|
@ -174,9 +166,7 @@ export default function PlaySpecific() {
|
||||||
<EcsContext.Provider value={ecsRef}>
|
<EcsContext.Provider value={ecsRef}>
|
||||||
<DebugContext.Provider value={debugTuple}>
|
<DebugContext.Provider value={debugTuple}>
|
||||||
<AssetsContext.Provider value={assetsTuple}>
|
<AssetsContext.Provider value={assetsTuple}>
|
||||||
<RadiansContext.Provider value={radians}>
|
<Ui disconnected={disconnected} />
|
||||||
<Ui disconnected={disconnected} />
|
|
||||||
</RadiansContext.Provider>
|
|
||||||
</AssetsContext.Provider>
|
</AssetsContext.Provider>
|
||||||
</DebugContext.Provider>
|
</DebugContext.Provider>
|
||||||
</EcsContext.Provider>
|
</EcsContext.Provider>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user