refactor: event stream

This commit is contained in:
cha0s 2021-07-09 02:50:14 -05:00
parent 7505b8e524
commit 250f057d0c
6 changed files with 64 additions and 16 deletions

View File

@ -65,7 +65,7 @@ export default (latus) => {
const promises = [];
for (let i = 0; i < this.#flatEntities.length; i++) {
promises.push(this.#flatEntities[i].destroy());
this.#flatEntities[i].tick(Infinity);
this.#flatEntities[i]?.tick(Infinity);
}
return Promise.all(promises);
}

View File

@ -38,6 +38,7 @@
"@pixi/sprite": "^5.3.9",
"@pixi/text": "^5.3.9",
"image-size": "^0.9.3",
"kefir": "^3.8.8",
"lru-cache": "^6.0.0",
"rc-slider": "^9.7.1"
},

View File

@ -1,17 +1,19 @@
import './index.scss';
import {Vector} from '@avocado/math';
import {
forwardRef,
memo,
PropTypes,
React,
useEffect,
useImperativeHandle,
useRef,
useState,
} from '@latus/react';
import K from 'kefir';
import Slider from 'rc-slider';
import Renderer from '../../renderer';
import './index.scss';
const marks = {
1: '1x',
@ -20,16 +22,27 @@ const marks = {
8: '8x',
};
const Stage = ({
const Stage = forwardRef(({
centered,
renderable,
renderer,
scalable,
size,
ticker,
}) => {
const ref = useRef();
}, fref) => {
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(() => {
if (!renderable) {
return;
@ -48,10 +61,10 @@ const Stage = ({
renderer.resize(Vector.scale(size, scale));
}, [renderer, scale, size]);
useEffect(() => {
const {current} = ref;
if (!current || !renderer) {
if (!renderer) {
return undefined;
}
const {current} = hostRef;
current.appendChild(renderer.element);
const cleanups = [
() => {
@ -59,6 +72,7 @@ const Stage = ({
},
];
if (scalable) {
const wheelEvents = K.fromEvents(renderer.element, 'wheel');
const onWheel = (event) => {
if (event.ctrlKey) {
event.preventDefault();
@ -66,15 +80,15 @@ const Stage = ({
setScale(Math.min(8, Math.max(1, scale * increment)));
}
};
current.addEventListener('wheel', onWheel);
wheelEvents.onValue(onWheel);
cleanups.push(() => {
current.removeEventListener('wheel', onWheel);
wheelEvents.offValue(onWheel);
});
}
return () => {
cleanups.forEach((fn) => fn());
};
}, [ref, renderer, scalable, scale, setScale]);
}, [hostRef, renderer, scalable, scale, setScale]);
useEffect(() => {
if (!renderable || !renderer) {
return undefined;
@ -98,7 +112,9 @@ const Stage = ({
};
}, [renderable, renderer, ticker]);
return (
<div className="stage">
<div
className="stage"
>
{scalable && (
<Slider
min={1}
@ -113,11 +129,11 @@ const Stage = ({
)}
<div
className="canvas-host"
ref={ref}
ref={hostRef}
/>
</div>
);
};
});
Stage.defaultProps = {
centered: true,

View File

@ -5425,6 +5425,11 @@ jsprim@^1.2.2:
array-includes "^3.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:
version "1.0.1"
resolved "https://verdaccio.hq.cha0s.io/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"

View File

@ -11,6 +11,7 @@ import {
hot,
PropTypes,
React,
useCallback,
useEffect,
useLatus,
useParams,
@ -30,6 +31,7 @@ const RoomComponent = ({
const latus = useLatus();
const {uri} = useParams();
const {Room} = latus.get('%resources');
const [events, setEvents] = useState();
const [room, setRoom] = useState();
const [roomRenderable, setRoomRenderable] = useState();
const [viewport, setViewport] = useState([0, 0]);
@ -37,6 +39,9 @@ const RoomComponent = ({
const [currentAction, setCurrentAction] = useState(0);
const [currentSide, setCurrentSide] = useState(0);
const [sideIsActive, setSideIsActive] = useState(false);
const onRef = useCallback((stage) => {
setEvents(stage?.events());
}, [setEvents]);
useEffect(() => {
if (!room) {
const loadRoom = async () => {
@ -98,6 +103,7 @@ const RoomComponent = ({
>
<Stage
centered={false}
ref={onRef}
renderer={renderer}
renderable={roomRenderable}
size={viewport}
@ -129,7 +135,9 @@ const RoomComponent = ({
{buttons}
</div>
</div>
<div className={locals.side}><Side room={room} /></div>
<div className={locals.side}>
<Side events={1 === currentAction && events} room={room} />
</div>
</div>
);
};

View File

@ -5,13 +5,31 @@ import {
hot,
PropTypes,
React,
useEffect,
useState,
} from '@latus/react';
import {locals} from './side.module.scss';
function EntitiesSide({room}) {
function EntitiesSide({events, room}) {
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)
.map(([key, entity], i) => (
<button