refactor: event stream
This commit is contained in:
parent
7505b8e524
commit
250f057d0c
|
@ -65,7 +65,7 @@ export default (latus) => {
|
||||||
const promises = [];
|
const promises = [];
|
||||||
for (let i = 0; i < this.#flatEntities.length; i++) {
|
for (let i = 0; i < this.#flatEntities.length; i++) {
|
||||||
promises.push(this.#flatEntities[i].destroy());
|
promises.push(this.#flatEntities[i].destroy());
|
||||||
this.#flatEntities[i].tick(Infinity);
|
this.#flatEntities[i]?.tick(Infinity);
|
||||||
}
|
}
|
||||||
return Promise.all(promises);
|
return Promise.all(promises);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
"@pixi/sprite": "^5.3.9",
|
"@pixi/sprite": "^5.3.9",
|
||||||
"@pixi/text": "^5.3.9",
|
"@pixi/text": "^5.3.9",
|
||||||
"image-size": "^0.9.3",
|
"image-size": "^0.9.3",
|
||||||
|
"kefir": "^3.8.8",
|
||||||
"lru-cache": "^6.0.0",
|
"lru-cache": "^6.0.0",
|
||||||
"rc-slider": "^9.7.1"
|
"rc-slider": "^9.7.1"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
import './index.scss';
|
|
||||||
|
|
||||||
import {Vector} from '@avocado/math';
|
import {Vector} from '@avocado/math';
|
||||||
import {
|
import {
|
||||||
|
forwardRef,
|
||||||
memo,
|
memo,
|
||||||
PropTypes,
|
PropTypes,
|
||||||
React,
|
React,
|
||||||
useEffect,
|
useEffect,
|
||||||
|
useImperativeHandle,
|
||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from '@latus/react';
|
} from '@latus/react';
|
||||||
|
import K from 'kefir';
|
||||||
import Slider from 'rc-slider';
|
import Slider from 'rc-slider';
|
||||||
|
|
||||||
import Renderer from '../../renderer';
|
import Renderer from '../../renderer';
|
||||||
|
import './index.scss';
|
||||||
|
|
||||||
const marks = {
|
const marks = {
|
||||||
1: '1x',
|
1: '1x',
|
||||||
|
@ -20,16 +22,27 @@ const marks = {
|
||||||
8: '8x',
|
8: '8x',
|
||||||
};
|
};
|
||||||
|
|
||||||
const Stage = ({
|
const Stage = forwardRef(({
|
||||||
centered,
|
centered,
|
||||||
renderable,
|
renderable,
|
||||||
renderer,
|
renderer,
|
||||||
scalable,
|
scalable,
|
||||||
size,
|
size,
|
||||||
ticker,
|
ticker,
|
||||||
}) => {
|
}, fref) => {
|
||||||
const ref = useRef();
|
|
||||||
const [scale, setScale] = useState(1);
|
const [scale, setScale] = useState(1);
|
||||||
|
const hostRef = useRef();
|
||||||
|
useImperativeHandle(fref, () => ({
|
||||||
|
events: () => K.merge(
|
||||||
|
[
|
||||||
|
'click',
|
||||||
|
'mousemove',
|
||||||
|
'mousedown',
|
||||||
|
'mouseup',
|
||||||
|
]
|
||||||
|
.map((event) => K.fromEvents(renderer.element, event)),
|
||||||
|
),
|
||||||
|
}));
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!renderable) {
|
if (!renderable) {
|
||||||
return;
|
return;
|
||||||
|
@ -48,10 +61,10 @@ const Stage = ({
|
||||||
renderer.resize(Vector.scale(size, scale));
|
renderer.resize(Vector.scale(size, scale));
|
||||||
}, [renderer, scale, size]);
|
}, [renderer, scale, size]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const {current} = ref;
|
if (!renderer) {
|
||||||
if (!current || !renderer) {
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
const {current} = hostRef;
|
||||||
current.appendChild(renderer.element);
|
current.appendChild(renderer.element);
|
||||||
const cleanups = [
|
const cleanups = [
|
||||||
() => {
|
() => {
|
||||||
|
@ -59,6 +72,7 @@ const Stage = ({
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
if (scalable) {
|
if (scalable) {
|
||||||
|
const wheelEvents = K.fromEvents(renderer.element, 'wheel');
|
||||||
const onWheel = (event) => {
|
const onWheel = (event) => {
|
||||||
if (event.ctrlKey) {
|
if (event.ctrlKey) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
@ -66,15 +80,15 @@ const Stage = ({
|
||||||
setScale(Math.min(8, Math.max(1, scale * increment)));
|
setScale(Math.min(8, Math.max(1, scale * increment)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
current.addEventListener('wheel', onWheel);
|
wheelEvents.onValue(onWheel);
|
||||||
cleanups.push(() => {
|
cleanups.push(() => {
|
||||||
current.removeEventListener('wheel', onWheel);
|
wheelEvents.offValue(onWheel);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return () => {
|
return () => {
|
||||||
cleanups.forEach((fn) => fn());
|
cleanups.forEach((fn) => fn());
|
||||||
};
|
};
|
||||||
}, [ref, renderer, scalable, scale, setScale]);
|
}, [hostRef, renderer, scalable, scale, setScale]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!renderable || !renderer) {
|
if (!renderable || !renderer) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -98,7 +112,9 @@ const Stage = ({
|
||||||
};
|
};
|
||||||
}, [renderable, renderer, ticker]);
|
}, [renderable, renderer, ticker]);
|
||||||
return (
|
return (
|
||||||
<div className="stage">
|
<div
|
||||||
|
className="stage"
|
||||||
|
>
|
||||||
{scalable && (
|
{scalable && (
|
||||||
<Slider
|
<Slider
|
||||||
min={1}
|
min={1}
|
||||||
|
@ -113,11 +129,11 @@ const Stage = ({
|
||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
className="canvas-host"
|
className="canvas-host"
|
||||||
ref={ref}
|
ref={hostRef}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
Stage.defaultProps = {
|
Stage.defaultProps = {
|
||||||
centered: true,
|
centered: true,
|
||||||
|
|
|
@ -5425,6 +5425,11 @@ jsprim@^1.2.2:
|
||||||
array-includes "^3.1.2"
|
array-includes "^3.1.2"
|
||||||
object.assign "^4.1.2"
|
object.assign "^4.1.2"
|
||||||
|
|
||||||
|
kefir@^3.8.8:
|
||||||
|
version "3.8.8"
|
||||||
|
resolved "https://verdaccio.hq.cha0s.io/kefir/-/kefir-3.8.8.tgz#235932ddfbed422acebf5d7cba503035e9ea05c5"
|
||||||
|
integrity sha512-xWga7QCZsR2Wjy2vNL3Kq/irT+IwxwItEWycRRlT5yhqHZK2fmEhziP+LzcJBWSTAMranGKtGTQ6lFpyJS3+jA==
|
||||||
|
|
||||||
killable@^1.0.1:
|
killable@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://verdaccio.hq.cha0s.io/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"
|
resolved "https://verdaccio.hq.cha0s.io/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
hot,
|
hot,
|
||||||
PropTypes,
|
PropTypes,
|
||||||
React,
|
React,
|
||||||
|
useCallback,
|
||||||
useEffect,
|
useEffect,
|
||||||
useLatus,
|
useLatus,
|
||||||
useParams,
|
useParams,
|
||||||
|
@ -30,6 +31,7 @@ const RoomComponent = ({
|
||||||
const latus = useLatus();
|
const latus = useLatus();
|
||||||
const {uri} = useParams();
|
const {uri} = useParams();
|
||||||
const {Room} = latus.get('%resources');
|
const {Room} = latus.get('%resources');
|
||||||
|
const [events, setEvents] = useState();
|
||||||
const [room, setRoom] = useState();
|
const [room, setRoom] = useState();
|
||||||
const [roomRenderable, setRoomRenderable] = useState();
|
const [roomRenderable, setRoomRenderable] = useState();
|
||||||
const [viewport, setViewport] = useState([0, 0]);
|
const [viewport, setViewport] = useState([0, 0]);
|
||||||
|
@ -37,6 +39,9 @@ const RoomComponent = ({
|
||||||
const [currentAction, setCurrentAction] = useState(0);
|
const [currentAction, setCurrentAction] = useState(0);
|
||||||
const [currentSide, setCurrentSide] = useState(0);
|
const [currentSide, setCurrentSide] = useState(0);
|
||||||
const [sideIsActive, setSideIsActive] = useState(false);
|
const [sideIsActive, setSideIsActive] = useState(false);
|
||||||
|
const onRef = useCallback((stage) => {
|
||||||
|
setEvents(stage?.events());
|
||||||
|
}, [setEvents]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!room) {
|
if (!room) {
|
||||||
const loadRoom = async () => {
|
const loadRoom = async () => {
|
||||||
|
@ -98,6 +103,7 @@ const RoomComponent = ({
|
||||||
>
|
>
|
||||||
<Stage
|
<Stage
|
||||||
centered={false}
|
centered={false}
|
||||||
|
ref={onRef}
|
||||||
renderer={renderer}
|
renderer={renderer}
|
||||||
renderable={roomRenderable}
|
renderable={roomRenderable}
|
||||||
size={viewport}
|
size={viewport}
|
||||||
|
@ -129,7 +135,9 @@ const RoomComponent = ({
|
||||||
{buttons}
|
{buttons}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={locals.side}><Side room={room} /></div>
|
<div className={locals.side}>
|
||||||
|
<Side events={1 === currentAction && events} room={room} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,13 +5,31 @@ import {
|
||||||
hot,
|
hot,
|
||||||
PropTypes,
|
PropTypes,
|
||||||
React,
|
React,
|
||||||
|
useEffect,
|
||||||
useState,
|
useState,
|
||||||
} from '@latus/react';
|
} from '@latus/react';
|
||||||
|
|
||||||
import {locals} from './side.module.scss';
|
import {locals} from './side.module.scss';
|
||||||
|
|
||||||
function EntitiesSide({room}) {
|
function EntitiesSide({events, room}) {
|
||||||
const [selectedEntity, setSelectedEntity] = useState(0);
|
const [selectedEntity, setSelectedEntity] = useState(0);
|
||||||
|
useEffect(() => {
|
||||||
|
if (!events) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const onValue = (event) => {
|
||||||
|
switch (event.type) {
|
||||||
|
case 'click':
|
||||||
|
console.log(event);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
};
|
||||||
|
events.onValue(onValue);
|
||||||
|
return () => {
|
||||||
|
events.offValue(onValue);
|
||||||
|
};
|
||||||
|
});
|
||||||
const names = Object.entries(room.entities)
|
const names = Object.entries(room.entities)
|
||||||
.map(([key, entity], i) => (
|
.map(([key, entity], i) => (
|
||||||
<button
|
<button
|
||||||
|
|
Loading…
Reference in New Issue
Block a user