refactor: encapsulation

This commit is contained in:
cha0s 2024-07-09 16:00:05 -05:00
parent 2a0321f15e
commit 15d4abaad1
3 changed files with 80 additions and 49 deletions

View File

@ -7,12 +7,8 @@ import Tiles from './devtools/tiles.jsx';
export default function Devtools({
applyFilters,
brush,
layer,
eventsChannel,
setApplyFilters,
setBrush,
setLayer,
setStamp,
}) {
return (
<div className={styles.devtools}>
@ -44,11 +40,7 @@ export default function Devtools({
<TabPanel>
<Tiles
brush={brush}
layer={layer}
setBrush={setBrush}
setLayer={setLayer}
setStamp={setStamp}
eventsChannel={eventsChannel}
/>
</TabPanel>
</Tabs>

View File

@ -1,23 +1,58 @@
import {useRef, useState} from 'react';
import {useEffect, useRef, useState} from 'react';
import {useClient} from '@/context/client.js';
import {useEcs} from '@/context/ecs.js';
import useRect from '@/util/react-hooks/use-rect.js';
import styles from './tiles.module.css';
export default function Tiles({
brush,
layer,
setBrush,
setLayer,
setStamp,
}) {
export default function Tiles({eventsChannel}) {
const client = useClient();
const wrapperRef = useRef();
const imageRef = useRef();
const imageRect = useRect(imageRef);
const [selection, setSelection] = useState({x: 0, y: 0, w: 1, h: 1});
const [moveStart, setMoveStart] = useState();
const [layer, setLayer] = useState(0);
const [brush, setBrush] = useState(0);
const [stamp, setStamp] = useState([]);
const [ecs] = useEcs();
useEffect(() => {
if (!ecs) {
return false;
}
const master = ecs.get(1);
if (!master) {
return false;
}
const {TileLayers} = master;
const {area, tileSize} = TileLayers.layer(0);
function onClick({x, y}) {
const at = {
x: Math.floor(x / tileSize.x),
y: Math.floor(y / tileSize.y),
};
if (at.x < 0 || at.y < 0 || at.x >= area.x || at.y >= area.y) {
return;
}
const payload = {
brush,
layer,
stamp: {
at,
data: stamp,
},
}
client.send({
type: 'AdminAction',
payload: {type: 'paint', value: payload},
});
}
eventsChannel.addListener('click', onClick);
return () => {
eventsChannel.removeListener('click', onClick);
};
});
if (!ecs) {
return false;
}

View File

@ -19,6 +19,32 @@ function emptySlots() {
return Array(10).fill(undefined);
}
const devEventsChannel = {
$$listeners: {},
addListener(type, listener) {
if (!this.$$listeners[type]) {
this.$$listeners[type] = new Set();
}
this.$$listeners[type].add(listener);
},
invoke(type, payload) {
const listeners = this.$$listeners[type];
if (!listeners) {
return;
}
for (const listener of listeners) {
listener(payload);
}
},
removeListener(type, listener) {
const listeners = this.$$listeners[type];
if (!listeners) {
return;
}
listeners.delete(listener);
},
};
export default function Ui({disconnected}) {
// Key input.
const client = useClient();
@ -35,9 +61,6 @@ export default function Ui({disconnected}) {
const [scale, setScale] = useState(2);
const [Components, setComponents] = useState();
const [Systems, setSystems] = useState();
const [layer, setLayer] = useState(0);
const [brush, setBrush] = useState(0);
const [stamp, setStamp] = useState([]);
const [applyFilters, setApplyFilters] = useState(true);
useEffect(() => {
async function setEcsStuff() {
@ -278,36 +301,22 @@ export default function Ui({disconnected}) {
return;
}
const {Camera} = ecs.get(mainEntity);
const {TileLayers} = master;
const {area, tileSize} = TileLayers.layer(0);
const size = width / RESOLUTION.x;
const cr = {
const client = {
x: (event.clientX - left) / size,
y: (event.clientY - top) / size,
};
const cm = {
const camera = {
x: ((Camera.x * scale) - (RESOLUTION.x / 2)),
y: ((Camera.y * scale) - (RESOLUTION.y / 2)),
}
const at = {
x: Math.floor((cr.x + cm.x) / (tileSize.x * scale)),
y: Math.floor((cr.y + cm.y) / (tileSize.y * scale)),
};
if (at.x < 0 || at.y < 0 || at.x >= area.x || at.y >= area.y) {
return;
}
const payload = {
brush,
layer,
stamp: {
at,
data: stamp,
devEventsChannel.invoke(
'click',
{
x: (client.x + camera.x) / scale,
y: (client.y + camera.y) / scale,
},
}
client.send({
type: 'AdminAction',
payload: {type: 'paint', value: payload},
});
);
}
else {
client.send({
@ -380,13 +389,8 @@ export default function Ui({disconnected}) {
<div className={[styles.devtools, devtoolsIsOpen && styles.devtoolsIsOpen].filter(Boolean).join(' ')}>
<Devtools
applyFilters={applyFilters}
brush={brush}
layer={layer}
stamp={stamp}
eventsChannel={devEventsChannel}
setApplyFilters={setApplyFilters}
setBrush={setBrush}
setLayer={setLayer}
setStamp={setStamp}
/>
</div>
</div>