refactor: ECS context

This commit is contained in:
cha0s 2024-06-22 23:32:57 -05:00
parent 0536e7b4f2
commit 663e33a300
6 changed files with 32 additions and 13 deletions

9
app/context/ecs.js Normal file
View File

@ -0,0 +1,9 @@
import {createContext, useContext} from 'react';
const context = createContext();
export default context;
export function useEcs() {
return useContext(context);
}

View File

@ -7,4 +7,3 @@ export default context;
export function useMainEntity() {
return useContext(context);
}

View File

@ -2,8 +2,8 @@ import {Container} from '@pixi/react';
import {useState} from 'react';
import {RESOLUTION} from '@/constants.js';
import {useEcs} from '@/context/ecs.js';
import {useMainEntity} from '@/context/main-entity.js';
import Ecs from '@/ecs/ecs.js';
import Components from '@/ecs-components/index.js';
import Systems from '@/ecs-systems/index.js';
import usePacket from '@/hooks/use-packet.js';
@ -13,14 +13,13 @@ import TargetingGhost from './targeting-ghost.jsx';
import TileLayer from './tile-layer.jsx';
export default function EcsComponent() {
const [ecs] = useState(new Ecs({Components, Systems}));
const [ecs] = useEcs();
const [entities, setEntities] = useState({});
const [mainEntity] = useMainEntity();
usePacket('Tick', (payload) => {
if (0 === Object.keys(payload.ecs).length) {
return;
}
ecs.apply(payload.ecs);
const updatedEntities = {...entities};
for (const id in payload.ecs) {
if (false === payload.ecs[id]) {

View File

@ -7,6 +7,7 @@ import {createElement, useContext} from 'react';
import {RESOLUTION} from '@/constants.js';
import ClientContext from '@/context/client.js';
import EcsContext from '@/context/ecs.js';
import MainEntityContext from '@/context/main-entity.js';
import Ecs from './ecs.jsx';
@ -14,7 +15,9 @@ import styles from './pixi.module.css';
BaseTexture.defaultOptions.scaleMode = SCALE_MODES.NEAREST;
const ContextBridge = ({children, Contexts, render}) => {
const Contexts = [ClientContext, EcsContext, MainEntityContext];
const ContextBridge = ({children, render}) => {
const contexts = Contexts.map(useContext);
return render(
<>
@ -33,7 +36,6 @@ const ContextBridge = ({children, Contexts, render}) => {
export const Stage = ({children, ...props}) => {
return (
<ContextBridge
Contexts={[ClientContext, MainEntityContext]}
render={(children) => <PixiStage {...props}>{children}</PixiStage>}
>
{children}

View File

@ -3,6 +3,7 @@ import {useContext, useEffect, useState} from 'react';
import addKeyListener from '@/add-key-listener.js';
import {RESOLUTION} from '@/constants.js';
import ClientContext from '@/context/client.js';
import {useEcs} from '@/context/ecs.js';
import {useMainEntity} from '@/context/main-entity.js';
import usePacket from '@/hooks/use-packet.js';
@ -18,6 +19,7 @@ export default function Ui({disconnected}) {
// Key input.
const client = useContext(ClientContext);
const [mainEntity, setMainEntity] = useMainEntity();
const [ecs] = useEcs();
const [showDisconnected, setShowDisconnected] = useState(false);
const [hotbarSlots, setHotbarSlots] = useState(Array(10).fill(0).map(() => {}));
const [activeSlot, setActiveSlot] = useState(0);
@ -136,15 +138,17 @@ export default function Ui({disconnected}) {
if (0 === Object.keys(payload.ecs).length) {
return;
}
ecs.apply(payload.ecs);
let localMainEntity = mainEntity;
for (const id in payload.ecs) {
if (payload.ecs[id]?.MainEntity) {
const update = payload.ecs[id];
if (update?.MainEntity) {
setMainEntity(localMainEntity = id);
}
if (localMainEntity === id) {
if (payload.ecs[id].Inventory) {
if (update.Inventory) {
const newHotbarSlots = [...hotbarSlots];
const {slots, slotChanged} = payload.ecs[id].Inventory;
const {slots, slotChanged} = update.Inventory;
if (slotChanged) {
for (const slotIndex in slotChanged) {
newHotbarSlots[slotIndex] = {
@ -164,8 +168,8 @@ export default function Ui({disconnected}) {
}
setHotbarSlots(newHotbarSlots);
}
if (payload.ecs[id].Wielder && 'activeSlot' in payload.ecs[id].Wielder) {
setActiveSlot(payload.ecs[id].Wielder.activeSlot);
if (update.Wielder && 'activeSlot' in update.Wielder) {
setActiveSlot(update.Wielder.activeSlot);
}
}
}

View File

@ -3,8 +3,11 @@ import {useEffect, useState} from 'react';
import {useOutletContext, useParams} from 'react-router-dom';
import ClientContext from '@/context/client.js';
import EcsContext from '@/context/ecs.js';
import MainEntityContext from '@/context/main-entity.js';
import Ecs from '@/ecs/ecs.js';
import Components from '@/ecs-components/index.js';
import Systems from '@/ecs-systems/index.js';
import Ui from '@/react-components/ui.jsx';
import {juggleSession} from '@/session.server';
@ -17,6 +20,7 @@ export default function PlaySpecific() {
const Client = useOutletContext();
const [client, setClient] = useState();
const mainEntityTuple = useState();
const ecsTuple = useState(new Ecs({Components, Systems}));
const [disconnected, setDisconnected] = useState(false);
const params = useParams();
const [type, url] = params['*'].split('/');
@ -88,7 +92,9 @@ export default function PlaySpecific() {
return (
<ClientContext.Provider value={client}>
<MainEntityContext.Provider value={mainEntityTuple}>
<Ui disconnected={disconnected} />
<EcsContext.Provider value={ecsTuple}>
<Ui disconnected={disconnected} />
</EcsContext.Provider>
</MainEntityContext.Provider>
</ClientContext.Provider>
);