diff --git a/app/react-components/devtools.jsx b/app/react-components/devtools.jsx
index 4e3a1eb..4b31f7f 100644
--- a/app/react-components/devtools.jsx
+++ b/app/react-components/devtools.jsx
@@ -7,12 +7,8 @@ import Tiles from './devtools/tiles.jsx';
export default function Devtools({
applyFilters,
- brush,
- layer,
+ eventsChannel,
setApplyFilters,
- setBrush,
- setLayer,
- setStamp,
}) {
return (
@@ -44,11 +40,7 @@ export default function Devtools({
diff --git a/app/react-components/devtools/tiles.jsx b/app/react-components/devtools/tiles.jsx
index 920368e..a81dbc1 100644
--- a/app/react-components/devtools/tiles.jsx
+++ b/app/react-components/devtools/tiles.jsx
@@ -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;
}
diff --git a/app/react-components/ui.jsx b/app/react-components/ui.jsx
index 695abfa..d7b3c19 100644
--- a/app/react-components/ui.jsx
+++ b/app/react-components/ui.jsx
@@ -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}) {