From 990419c35154248571989e4b5cccf4d9c19a041b Mon Sep 17 00:00:00 2001 From: cha0s Date: Mon, 27 May 2024 06:27:08 -0500 Subject: [PATCH] refactor: structure --- src/client/client.js | 19 +++++++++ src/{server => client}/local.js | 6 +-- src/{server => client}/remote.js | 6 +-- src/components/entities.jsx | 7 +-- src/components/pixi.jsx | 8 ++-- src/components/silphius.jsx | 24 +++++------ src/components/ui.jsx | 6 +-- src/context/{server.js => client.js} | 0 src/server/engine.js | 61 -------------------------- src/server/server.js | 64 +++++++++++++++++++++++----- src/server/socket.js | 4 +- src/server/worker.js | 4 +- 12 files changed, 102 insertions(+), 107 deletions(-) create mode 100644 src/client/client.js rename src/{server => client}/local.js (51%) rename src/{server => client}/remote.js (67%) rename src/context/{server.js => client.js} (100%) delete mode 100644 src/server/engine.js diff --git a/src/client/client.js b/src/client/client.js new file mode 100644 index 0000000..83c0a47 --- /dev/null +++ b/src/client/client.js @@ -0,0 +1,19 @@ +export default class Client { + constructor() { + this.listeners = []; + } + accept(data) { + for (const i in this.listeners) { + this.listeners[i](data); + } + } + addMessageListener(listener) { + this.listeners.push(listener); + } + removeMessageListener(listener) { + const index = this.listeners.indexOf(listener); + if (-1 !== index) { + this.listeners.splice(index, 1); + } + } +} diff --git a/src/server/local.js b/src/client/local.js similarity index 51% rename from src/server/local.js rename to src/client/local.js index 468cfe5..725a0de 100644 --- a/src/server/local.js +++ b/src/client/local.js @@ -1,8 +1,8 @@ -import Server from './server.js'; +import Client from './client.js'; -export default class Local extends Server { +export default class LocalClient extends Client { async connect() { - this.worker = new Worker('/server/worker.js', {type: 'module'}); + this.worker = new Worker('../server/worker.js', {type: 'module'}); this.worker.onmessage = (event) => { this.accept(event.data); }; diff --git a/src/server/remote.js b/src/client/remote.js similarity index 67% rename from src/server/remote.js rename to src/client/remote.js index 7b9b742..cf3448f 100644 --- a/src/server/remote.js +++ b/src/client/remote.js @@ -1,8 +1,8 @@ -import Server from './server.js'; +import Client from './client.js'; -export default class Remote extends Server { +export default class RemoteClient extends Client { async connect() { - this.socket = new WebSocket('/ws'); + this.socket = new WebSocket(`ws://${window.location.host}/ws`); this.socket.onmessage = (event) => { for (const i in this.listeners) { this.listeners[i](JSON.parse(event.data)); diff --git a/src/components/entities.jsx b/src/components/entities.jsx index 8cdd35f..f92b21b 100644 --- a/src/components/entities.jsx +++ b/src/components/entities.jsx @@ -1,9 +1,4 @@ -import { - Sprite, -} from '@pixi/react'; -import {useContext, useEffect, useState} from 'react'; - -import ServerContext from '../context/server'; +import {Sprite} from '@pixi/react'; export default function Entities({entities}) { return ( diff --git a/src/components/pixi.jsx b/src/components/pixi.jsx index 050d256..c4bbcbf 100644 --- a/src/components/pixi.jsx +++ b/src/components/pixi.jsx @@ -5,12 +5,12 @@ import { import {useContext, useEffect, useState} from 'react'; import {RESOLUTION} from '../constants.js'; -import ServerContext from '../context/server'; +import ClientContext from '../context/client'; import Entities from './entities'; import styles from './pixi.module.css'; export default function Pixi() { - const server = useContext(ServerContext); + const client = useContext(ClientContext); const [entities, setEntities] = useState({}); useEffect(() => { function onMessage(message) { @@ -27,9 +27,9 @@ export default function Pixi() { default: } } - server.addMessageListener(onMessage); + client.addMessageListener(onMessage); return () => { - server.removeMessageListener(onMessage); + client.removeMessageListener(onMessage); }; }); return ( diff --git a/src/components/silphius.jsx b/src/components/silphius.jsx index f65c34b..c3720da 100644 --- a/src/components/silphius.jsx +++ b/src/components/silphius.jsx @@ -1,41 +1,41 @@ import {useEffect, useState} from 'react'; -import ServerContext from '../context/server.js'; +import ClientContext from '../context/client.js'; import Title from './title'; import Ui from './ui'; export default function Silphius() { const connectionTuple = useState(); - const [server, setServer] = useState(); + const [client, setClient] = useState(); useEffect(() => { if (!connectionTuple[0]) { return; } async function connect() { - let Server; + let Client; switch (connectionTuple[0]) { case 'local': - ({default: Server} = await import('../server/local.js')); + ({default: Client} = await import('../client/local.js')); break; case 'remote': - ({default: Server} = await import('../server/remote.js')); + ({default: Client} = await import('../client/remote.js')); break; } - const server = new Server(); - await server.connect(); - server.send({type: 'connect'}); - setServer(server); + const client = new Client(); + await client.connect(); + client.send({type: 'connect'}); + setClient(client); } connect(); }, [connectionTuple[0]]); return ( connectionTuple[0] ? ( - server + client ? ( - + - + ) : null ) diff --git a/src/components/ui.jsx b/src/components/ui.jsx index adb5ea6..828e9de 100644 --- a/src/components/ui.jsx +++ b/src/components/ui.jsx @@ -2,7 +2,7 @@ import {useContext, useEffect} from 'react'; import addKeyListener from '../add-key-listener.js'; import {RESOLUTION} from '../constants'; -import ServerContext from '../context/server'; +import ClientContext from '../context/client'; import Dom from './dom'; import Pixi from './pixi'; import styles from './ui.module.css'; @@ -23,11 +23,11 @@ const KEY_MAP = { export default function Ui() { // Key input. - const server = useContext(ServerContext); + const client = useContext(ClientContext); useEffect(() => { return addKeyListener(document.body, ({type, payload}) => { if (type in KEY_MAP && payload in ACTION_MAP) { - server.send({ + client.send({ type: 'action', payload: { type: ACTION_MAP[payload], diff --git a/src/context/server.js b/src/context/client.js similarity index 100% rename from src/context/server.js rename to src/context/client.js diff --git a/src/server/engine.js b/src/server/engine.js deleted file mode 100644 index accc248..0000000 --- a/src/server/engine.js +++ /dev/null @@ -1,61 +0,0 @@ -const SPEED = 100; -const TPS = 60; - -const MOVE_MAP = { - 'moveUp': 0, - 'moveRight': 1, - 'moveDown': 2, - 'moveLeft': 3, -}; - -export default class Engine { - - constructor() { - this.dude = { - image: './assets/bunny.png', - movement: [0, 0, 0, 0], - position: [50, 50], - }; - this.frame = 0; - this.last = Date.now(); - } - - accept({type, payload}) { - switch (type) { - case 'connect': { - this.send({type: 'connected', payload: {dude: this.dude}}); - break; - } - case 'action': { - if (payload.type in MOVE_MAP) { - this.dude.movement[MOVE_MAP[payload.type]] = payload.value; - } - break; - } - default: - } - } - - start() { - return setInterval(() => { - const elapsed = (Date.now() - this.last) / 1000; - this.last = Date.now(); - this.tick(elapsed); - }, 1000 / TPS); - } - - tick(elapsed) { - this.dude.position[0] += SPEED * elapsed * (this.dude.movement[1] - this.dude.movement[3]); - this.dude.position[1] += SPEED * elapsed * (this.dude.movement[2] - this.dude.movement[0]); - this.send({ - type: 'tick', - payload: { - entities: {dude: this.dude}, - elapsed, - frame: this.frame, - }, - }); - this.frame += 1; - } - -} diff --git a/src/server/server.js b/src/server/server.js index 7cfefde..2e61164 100644 --- a/src/server/server.js +++ b/src/server/server.js @@ -1,19 +1,61 @@ +const SPEED = 100; +const TPS = 60; + +const MOVE_MAP = { + 'moveUp': 0, + 'moveRight': 1, + 'moveDown': 2, + 'moveLeft': 3, +}; + export default class Server { + constructor() { - this.listeners = []; + this.dude = { + image: './assets/bunny.png', + movement: [0, 0, 0, 0], + position: [50, 50], + }; + this.frame = 0; + this.last = Date.now(); } - accept(data) { - for (const i in this.listeners) { - this.listeners[i](data); + + accept({type, payload}) { + switch (type) { + case 'connect': { + this.send({type: 'connected', payload: {dude: this.dude}}); + break; + } + case 'action': { + if (payload.type in MOVE_MAP) { + this.dude.movement[MOVE_MAP[payload.type]] = payload.value; + } + break; + } + default: } } - addMessageListener(listener) { - this.listeners.push(listener); + + start() { + return setInterval(() => { + const elapsed = (Date.now() - this.last) / 1000; + this.last = Date.now(); + this.tick(elapsed); + }, 1000 / TPS); } - removeMessageListener(listener) { - const index = this.listeners.indexOf(listener); - if (-1 !== index) { - this.listeners.splice(index, 1); - } + + tick(elapsed) { + this.dude.position[0] += SPEED * elapsed * (this.dude.movement[1] - this.dude.movement[3]); + this.dude.position[1] += SPEED * elapsed * (this.dude.movement[2] - this.dude.movement[0]); + this.send({ + type: 'tick', + payload: { + entities: {dude: this.dude}, + elapsed, + frame: this.frame, + }, + }); + this.frame += 1; } + } diff --git a/src/server/socket.js b/src/server/socket.js index 682cd7b..0004909 100644 --- a/src/server/socket.js +++ b/src/server/socket.js @@ -1,6 +1,6 @@ import {WebSocketServer} from 'ws'; -import Engine from './engine.js'; +import Server from './server.js'; const { SILPHIUS_WEBSOCKET_PORT = 8080 @@ -9,7 +9,7 @@ const { const wss = new WebSocketServer({port: SILPHIUS_WEBSOCKET_PORT}); wss.on('connection', function connection(ws) { - const server = new class WorkerEngine extends Engine { + const server = new class SocketServer extends Server { send(data) { ws.send(JSON.stringify(data)); } } ws.on('message', function message(data) { diff --git a/src/server/worker.js b/src/server/worker.js index b6a4280..beb5e40 100644 --- a/src/server/worker.js +++ b/src/server/worker.js @@ -1,6 +1,6 @@ -import Engine from './engine.js'; +import Server from './server.js'; -const server = new class WorkerEngine extends Engine { +const server = new class WorkerServer extends Server { send(data) { postMessage(data); } }