refactor: components

This commit is contained in:
cha0s 2021-03-25 02:46:45 -05:00
parent 48298d7161
commit 2d42298467
21 changed files with 227 additions and 233 deletions

View File

@ -3,7 +3,7 @@ import './index.scss';
import {hot} from 'react-hot-loader'; import {hot} from 'react-hot-loader';
import {useIsNative, ValentUi} from '@humus/core'; import {useIsNative} from '@humus/core';
import {Universe} from '@humus/universe'; import {Universe} from '@humus/universe';
import {React} from '@latus/react'; import {React} from '@latus/react';
import {ConnectedRouter} from 'connected-react-router'; import {ConnectedRouter} from 'connected-react-router';
@ -14,8 +14,6 @@ import {
} from 'react-router-dom'; } from 'react-router-dom';
import Login from '../login'; import Login from '../login';
import Play from '../play';
import Renderer from '../renderer';
import Title from '../title'; import Title from '../title';
import history from './history'; import history from './history';
@ -30,17 +28,13 @@ const Humus = () => {
return ( return (
<div className="humus"> <div className="humus">
<ConnectedRouter history={history}> <ConnectedRouter history={history}>
<Renderer /> <Switch>
<ValentUi width={WIDTH} height={HEIGHT}> <Route path="/login">
<Switch> {isLoggedIn ? <Redirect to="/title" /> : Login}
<Route path="/login"> </Route>
{isLoggedIn ? <Redirect to="/title" /> : Login} <Universe width={WIDTH} height={HEIGHT} />
</Route> {isNative ? <Route path="/title"><Title /></Route> : <Redirect to="/universe" />}
<Route path="/universe/:uuid/play" component={Play} /> </Switch>
<Route path={['/universe/:uuid', '/universe']} component={Universe} />
{isNative ? <Route path="/title"><Title /></Route> : <Redirect to="/universe" />}
</Switch>
</ValentUi>
<Route exact path="/"> <Route exact path="/">
<Redirect to="/title" /> <Redirect to="/title" />
</Route> </Route>

View File

@ -1,16 +0,0 @@
import {Color, Container, Primitives} from '@avocado/graphics';
import {PixiComponent} from '@inlet/react-pixi';
const primitives = new Primitives();
primitives.drawCircle(
[250, 250],
50,
{
color: new Color(255, 255, 0),
thickness: 1,
},
);
export default PixiComponent('Dumb', {
create: () => (new Container()).internal,
});

View File

@ -1,48 +0,0 @@
// TODO should be betta
import 'pixi.js-legacy';
import {LatusContext, React, useLatus} from '@latus/react';
import {Provider, useStore} from '@latus/redux';
import {
__RouterContext as RouterContext,
} from 'react-router';
import {
Route,
Switch,
useLocation,
} from 'react-router-dom';
import Stage from '../stage';
import Dumb from './dumb';
import RoomView from './room-view';
const Renderer = () => {
const location = useLocation();
const latus = useLatus();
const store = useStore();
return (
<Stage width={320} height={180}>
<LatusContext.Provider value={latus}>
<RouterContext.Provider value={{location}}>
<Provider store={store}>
<Switch>
<Route path="/login">
<Dumb />
</Route>
<Route path="/universe">
<RoomView />
</Route>
</Switch>
</Provider>
</RouterContext.Provider>
</LatusContext.Provider>
</Stage>
);
};
export default Renderer;
if (module.hot) {
module.hot.decline();
}

View File

@ -1,106 +0,0 @@
import {
React,
useEffect,
useMemo,
useState,
} from '@latus/react';
import {Container, Renderer} from '@avocado/graphics';
import {Vector} from '@avocado/math';
import {createLoop, destroyLoop} from '@avocado/timing';
import {RoomView} from '@avocado/topdown';
import {useRoom, useSelfEntity} from '@humus/core';
import {PixiComponent, useApp} from '@inlet/react-pixi';
const container = new Container();
const VIEWPORT = [320, 180];
const Component = PixiComponent('RoomView', {
create: () => container.internal,
applyProps: (instance, oldProps, newProps) => {
if (oldProps.room !== newProps.room) {
if (oldProps.room) {
container.removeAllChildren();
}
if (newProps.room) {
container.addChild(new RoomView(newProps.room, newProps.renderer));
}
}
const [roomView] = container.children;
if (roomView) {
const halfViewport = Vector.scale(VIEWPORT, 0.5);
roomView.pivot = Vector.sub(halfViewport, Vector.scale(newProps.offset, -1));
[roomView.x, roomView.y] = halfViewport;
[roomView.scaleX, roomView.scaleY] = newProps.scale;
roomView.rotation = newProps.rotation;
}
},
});
const RoomViewComponent = () => {
const app = useApp();
const renderer = useMemo(() => {
if (app.renderer) {
const renderer = new Renderer();
renderer.renderer = app.renderer;
return renderer;
}
return undefined;
}, [app]);
const selfEntity = useSelfEntity();
const [offset, setOffset] = useState([0, 0]);
const [scale, setScale] = useState([1, 1]);
const [rotation, setRotation] = useState(0);
const room = useRoom();
useEffect(() => {
if (!room || !selfEntity) {
return undefined;
}
selfEntity.camera.realPosition = selfEntity.camera.position;
const onCameraRealOffsetChanged = () => {
setOffset(selfEntity.camera.realOffset);
};
const onCameraRotationChanged = () => {
setRotation(selfEntity.camera.rotation);
};
const onCameraScaleChanged = () => {
setScale(selfEntity.camera.scale);
};
onCameraRealOffsetChanged();
onCameraRotationChanged();
onCameraScaleChanged();
selfEntity.camera.on('realOffsetChanged', onCameraRealOffsetChanged);
selfEntity.camera.on('rotationChanged', onCameraRotationChanged);
selfEntity.camera.on('scaleChanged', onCameraScaleChanged);
return () => {
const {camera} = selfEntity || {};
if (camera) {
camera.off('realOffsetChanged', onCameraRealOffsetChanged);
camera.off('scaleChanged', onCameraScaleChanged);
}
};
}, [room, selfEntity]);
useEffect(() => {
if (!room) {
return undefined;
}
const handle = createLoop((elapsed) => {
room.tick(elapsed);
container.renderTick(elapsed);
});
return () => {
destroyLoop(handle);
};
}, [room]);
return (
<Component
offset={offset}
renderer={renderer}
room={room}
rotation={rotation}
scale={scale}
/>
);
};
export default RoomViewComponent;

View File

@ -1,16 +0,0 @@
import {Color, Primitives} from '@avocado/graphics';
import {PixiComponent} from '@inlet/react-pixi';
const primitives = new Primitives();
primitives.drawCircle(
[250, 250],
50,
{
color: new Color(255, 0, 255),
thickness: 1,
},
);
export default PixiComponent('Stupid', {
create: () => primitives.internal,
});

View File

@ -1,24 +1,24 @@
.stage { // .stage {
display: inline-block; // display: inline-block;
left: 50%; // left: 50%;
line-height: 0; // line-height: 0;
position: absolute; // position: absolute;
top: 50%; // top: 50%;
transform: translate(-50%, -50%); // transform: translate(-50%, -50%);
> canvas { // > canvas {
image-rendering: pixelated; // image-rendering: pixelated;
} // }
} // }
/* Exact aspect ratio, put it at the bottom to avoid override*/ // /* Exact aspect ratio, put it at the bottom to avoid override*/
@media (max-aspect-ratio: 16/9) { // @media (max-aspect-ratio: 16/9) {
.stage, .stage > canvas { // .stage, .stage > canvas {
width: 100%; // width: 100%;
} // }
} // }
@media (min-aspect-ratio: 16/9) { // @media (min-aspect-ratio: 16/9) {
.stage, .stage > canvas { // .stage, .stage > canvas {
height: 100%; // height: 100%;
} // }
} // }

View File

@ -22,20 +22,27 @@
"test.js.map" "test.js.map"
], ],
"dependencies": { "dependencies": {
"@avocado/graphics": "^2.0.0",
"@avocado/input": "^2.0.0",
"@avocado/math": "^2.0.0", "@avocado/math": "^2.0.0",
"@avocado/react": "^1.0.0",
"@avocado/resource": "^2.0.0", "@avocado/resource": "^2.0.0",
"@avocado/s13n": "^2.0.0", "@avocado/s13n": "^2.0.0",
"@avocado/timing": "^2.0.0", "@avocado/timing": "^2.0.0",
"@avocado/topdown": "^2.0.0",
"@avocado/traits": "^2.0.0", "@avocado/traits": "^2.0.0",
"@humus/core": "^1.0.0", "@humus/core": "^1.0.0",
"@humus/inventory": "^1.0.0",
"@latus/core": "^2.0.0", "@latus/core": "^2.0.0",
"@latus/react": "^2.0.0", "@latus/react": "^2.0.0",
"@latus/redux": "^2.0.0", "@latus/redux": "^2.0.0",
"@latus/socket": "^2.0.0", "@latus/socket": "^2.0.0",
"autoprefixer": "^9.8.6", "autoprefixer": "^9.8.6",
"classnames": "^2.2.6",
"debug": "4.3.1", "debug": "4.3.1",
"express": "^4.17.1", "express": "^4.17.1",
"glob": "^7.1.6", "glob": "^7.1.6",
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0" "react-router-dom": "^5.2.0"
}, },
"devDependencies": { "devDependencies": {

View File

@ -0,0 +1,37 @@
import {ValentUi} from '@humus/core';
import {PropTypes, React} from '@latus/react';
import {
Route,
Switch,
} from 'react-router-dom';
import Overview from './overview';
import PlayRenderable from './play/renderable';
import PlayUi from './play/ui';
const Universe = ({
height,
width,
// eslint-disable-next-line arrow-body-style
}) => {
return (
<Route path="/universe">
<Switch>
<Route path="/universe/:uuid/play" component={PlayRenderable} />
</Switch>
<ValentUi width={width} height={height}>
<Switch>
<Route path="/universe/:uuid/play" component={PlayUi} />
<Route path={['/universe/:uuid', '/universe']} component={Overview} />
</Switch>
</ValentUi>
</Route>
);
};
Universe.propTypes = {
height: PropTypes.number.isRequired,
width: PropTypes.number.isRequired,
};
export default Universe;

View File

Before

Width:  |  Height:  |  Size: 594 KiB

After

Width:  |  Height:  |  Size: 594 KiB

View File

@ -8,7 +8,7 @@ import {
useLocation, useLocation,
} from 'react-router-dom'; } from 'react-router-dom';
import {universesByLocalitySelector, universesSelector} from '../state'; import {universesByLocalitySelector, universesSelector} from '../../state';
const Universe = ({match: {params: {uuid}}}) => { const Universe = ({match: {params: {uuid}}}) => {
const history = useHistory(); const history = useHistory();

View File

@ -0,0 +1,83 @@
import {
React,
useEffect,
useState,
} from '@latus/react';
import {Container, Renderer} from '@avocado/graphics';
import {Vector} from '@avocado/math';
import {Stage} from '@avocado/react';
import {createLoop, destroyLoop} from '@avocado/timing';
import {RoomView} from '@avocado/topdown';
import {useRoom, useSelfEntity} from '@humus/core';
const ticker = () => {};
const RoomStage = () => {
const selfEntity = useSelfEntity();
const [container] = useState(new Container());
const [VIEWPORT] = useState([320, 180]);
const halfViewport = Vector.scale(VIEWPORT, 0.5);
const [renderer] = useState(new Renderer(VIEWPORT));
const room = useRoom();
useEffect(() => {
container.removeAllChildren();
if (renderer && room) {
const roomView = new RoomView(room, renderer);
container.addChild(roomView);
[container.x, container.y] = halfViewport;
}
}, [container, halfViewport, renderer, room]);
useEffect(() => {
if (!room || !selfEntity) {
return undefined;
}
selfEntity.camera.realPosition = selfEntity.camera.position;
const onCameraRealOffsetChanged = () => {
container.pivot = Vector.sub(halfViewport, Vector.scale(selfEntity.camera.realOffset, -1));
};
const onCameraRotationChanged = () => {
container.rotation = selfEntity.camera.rotation;
};
const onCameraScaleChanged = () => {
[container.scaleX, container.scaleY] = selfEntity.camera.scale;
};
onCameraRealOffsetChanged();
onCameraRotationChanged();
onCameraScaleChanged();
selfEntity.camera.on('realOffsetChanged', onCameraRealOffsetChanged);
selfEntity.camera.on('rotationChanged', onCameraRotationChanged);
selfEntity.camera.on('scaleChanged', onCameraScaleChanged);
return () => {
const {camera} = selfEntity || {};
if (camera) {
camera.off('realOffsetChanged', onCameraRealOffsetChanged);
camera.off('scaleChanged', onCameraScaleChanged);
}
};
}, [container, halfViewport, room, selfEntity]);
useEffect(() => {
if (!room) {
return undefined;
}
const handle = createLoop((elapsed) => {
room.tick(elapsed);
container.renderTick(elapsed);
});
return () => {
destroyLoop(handle);
};
}, [container, room]);
return (
<Stage
centered={false}
scalable={false}
renderer={renderer}
renderable={container}
size={VIEWPORT}
ticker={ticker}
/>
);
};
export default RoomStage;

View File

@ -0,0 +1,24 @@
.stage {
display: inline-block;
left: 50%;
line-height: 0;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
canvas {
image-rendering: pixelated;
}
}
/* Exact aspect ratio, put it at the bottom to avoid override*/
@media (max-aspect-ratio: 16/9) {
.stage, .stage > .canvas-host, .stage > .canvas-host > canvas {
width: 100%;
}
}
@media (min-aspect-ratio: 16/9) {
.stage, .stage > .canvas-host, .stage > .canvas-host > canvas {
height: 100%;
}
}

View File

@ -1,5 +1,3 @@
import './index.scss';
import classnames from 'classnames'; import classnames from 'classnames';
import {usePropertyChange} from '@avocado/react'; import {usePropertyChange} from '@avocado/react';
import {useInventorySlice} from '@humus/inventory'; import {useInventorySlice} from '@humus/inventory';

View File

@ -1,5 +1,3 @@
import './index.scss';
import {InputNormalizer} from '@avocado/input/client'; import {InputNormalizer} from '@avocado/input/client';
import {Vector} from '@avocado/math'; import {Vector} from '@avocado/math';
import {Room} from '@avocado/topdown'; import {Room} from '@avocado/topdown';
@ -22,7 +20,7 @@ import Hotbar from './hotbar';
const FACTOR = 5; const FACTOR = 5;
const Play = () => { const PlayUi = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const {uuid} = useParams(); const {uuid} = useParams();
const ref = useRef(); const ref = useRef();
@ -94,4 +92,4 @@ const Play = () => {
); );
}; };
export default Play; export default PlayUi;

View File

@ -1,5 +1,3 @@
import './index.scss';
import {join} from 'path'; import {join} from 'path';
import classnames from 'classnames'; import classnames from 'classnames';

View File

@ -2,7 +2,7 @@ import {gatherWithLatus} from '@latus/core';
import {universes} from './state'; import {universes} from './state';
export {default as Universe} from './components/universe'; export {default as Universe} from './components';
export * from './state'; export * from './state';

View File

@ -89,6 +89,14 @@
d3-quadtree "^2.0.0" d3-quadtree "^2.0.0"
debug "4.3.1" debug "4.3.1"
"@avocado/react@^1.0.0":
version "1.0.0"
resolved "http://npm.cha0sdev/@avocado%2freact/-/react-1.0.0.tgz#ed3b3252f4302f72f80ee3188c3d407b4f3c3bea"
integrity sha512-K3xxoK/0dZOH7lR7aCkxpbXItUH1omT0NEbb+eKj6qpYZyLeWe2CNtJZ4tegnABpsewlrMuzT3NqRP/zaGJI9Q==
dependencies:
"@latus/core" "^2.0.0"
"@latus/react" "^2.0.0"
"@avocado/resource@2.0.0", "@avocado/resource@^2.0.0": "@avocado/resource@2.0.0", "@avocado/resource@^2.0.0":
version "2.0.0" version "2.0.0"
resolved "http://npm.cha0sdev/@avocado%2fresource/-/resource-2.0.0.tgz#3ec04329d6e1357f67a956fca48062dcbb7107e1" resolved "http://npm.cha0sdev/@avocado%2fresource/-/resource-2.0.0.tgz#3ec04329d6e1357f67a956fca48062dcbb7107e1"
@ -129,6 +137,22 @@
debug "4.3.1" debug "4.3.1"
lodash.mapvalues "^4.6.0" lodash.mapvalues "^4.6.0"
"@avocado/topdown@^2.0.0":
version "2.0.0"
resolved "http://npm.cha0sdev/@avocado%2ftopdown/-/topdown-2.0.0.tgz#615bbce088d5e6238fba483401c7e13ecb6a8b47"
integrity sha512-LUZKCNx2i/XWMBaMKmA4QzGjEfFXKJKiHPC/E5qL99CRUgsFXPiDfPQheOwbfibVYPgWFd0wPPuE/tLFg53PMg==
dependencies:
"@avocado/core" "2.0.0"
"@avocado/entity" "^2.0.0"
"@avocado/graphics" "2.0.0"
"@avocado/math" "2.0.0"
"@avocado/resource" "2.0.0"
"@avocado/s13n" "2.0.0"
"@avocado/traits" "^2.0.0"
"@latus/core" "2.0.0"
"@latus/socket" "^2.0.0"
debug "4.3.1"
"@avocado/traits@^2.0.0": "@avocado/traits@^2.0.0":
version "2.0.0" version "2.0.0"
resolved "http://npm.cha0sdev/@avocado%2ftraits/-/traits-2.0.0.tgz#4f0d2520296580af2055618d3180fc3fc0f7dc20" resolved "http://npm.cha0sdev/@avocado%2ftraits/-/traits-2.0.0.tgz#4f0d2520296580af2055618d3180fc3fc0f7dc20"
@ -1075,6 +1099,18 @@
debug "4.3.1" debug "4.3.1"
msgpack-lite "^0.1.26" msgpack-lite "^0.1.26"
"@humus/inventory@^1.0.0":
version "1.0.0"
resolved "http://npm.cha0sdev/@humus%2finventory/-/inventory-1.0.0.tgz#5c47369ddb58e548989e8875e390a86e8219ac3b"
integrity sha512-uXw05JBY4P45vafuLREt0hPZw70RUHeMJqJoCZlxY8APRm9GLOeBRvlBbg5yWUppRyg7pFXbb4eKj8phLXTPjQ==
dependencies:
"@avocado/behavior" "^2.0.0"
"@avocado/traits" "^2.0.0"
"@latus/core" "^2.0.0"
"@latus/socket" "^2.0.0"
autoprefixer "^9.8.6"
debug "4.3.1"
"@latus/build@1.x": "@latus/build@1.x":
version "1.0.0" version "1.0.0"
resolved "http://npm.cha0sdev/@latus%2fbuild/-/build-1.0.0.tgz#f46931805023e753e6ac5038acc832e53801e46c" resolved "http://npm.cha0sdev/@latus%2fbuild/-/build-1.0.0.tgz#f46931805023e753e6ac5038acc832e53801e46c"
@ -2629,6 +2665,11 @@ class-utils@^0.3.5:
isobject "^3.0.0" isobject "^3.0.0"
static-extend "^0.1.1" static-extend "^0.1.1"
classnames@^2.2.6:
version "2.2.6"
resolved "http://npm.cha0sdev/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
clean-css@4.2.x, clean-css@^4.2.3: clean-css@4.2.x, clean-css@^4.2.3:
version "4.2.3" version "4.2.3"
resolved "http://npm.cha0sdev/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" resolved "http://npm.cha0sdev/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78"
@ -7049,7 +7090,7 @@ react-router-dom@^5.2.0:
tiny-invariant "^1.0.2" tiny-invariant "^1.0.2"
tiny-warning "^1.0.0" tiny-warning "^1.0.0"
react-router@5.2.0: react-router@5.2.0, react-router@^5.2.0:
version "5.2.0" version "5.2.0"
resolved "http://npm.cha0sdev/react-router/-/react-router-5.2.0.tgz#424e75641ca8747fbf76e5ecca69781aa37ea293" resolved "http://npm.cha0sdev/react-router/-/react-router-5.2.0.tgz#424e75641ca8747fbf76e5ecca69781aa37ea293"
integrity sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw== integrity sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==