refactor: withResolvers

This commit is contained in:
cha0s 2024-07-22 00:13:03 -05:00
parent eb6e23f0e1
commit c224445345
9 changed files with 38 additions and 46 deletions

View File

@ -1,4 +1,5 @@
import {encode} from '@/net/packets/index.js'; import {encode} from '@/net/packets/index.js';
import {withResolvers} from '@/util/promise.js';
let connected = false; let connected = false;
let socket; let socket;
@ -12,7 +13,7 @@ onmessage = async (event) => {
const url = new URL(`wss://${event.data.host}/ws`) const url = new URL(`wss://${event.data.host}/ws`)
socket = new WebSocket(url.href); socket = new WebSocket(url.href);
socket.binaryType = 'arraybuffer'; socket.binaryType = 'arraybuffer';
const {promise, resolve} = Promise.withResolvers(); const {promise, resolve} = withResolvers();
socket.addEventListener('open', resolve); socket.addEventListener('open', resolve);
socket.addEventListener('error', () => { socket.addEventListener('error', () => {
postMessage(encode({type: 'ConnectionStatus', payload: 'aborted'})); postMessage(encode({type: 'ConnectionStatus', payload: 'aborted'}));

View File

@ -1,6 +1,7 @@
import Client from '@/net/client.js'; import Client from '@/net/client.js';
import {encode} from '@/net/packets/index.js'; import {encode} from '@/net/packets/index.js';
import {CLIENT_PREDICTION} from '@/util/constants.js'; import {CLIENT_PREDICTION} from '@/util/constants.js';
import {withResolvers} from '@/util/promise.js';
export default class RemoteClient extends Client { export default class RemoteClient extends Client {
constructor() { constructor() {
@ -30,7 +31,7 @@ export default class RemoteClient extends Client {
const onMessage = (event) => { const onMessage = (event) => {
this.accept(event.data); this.accept(event.data);
} }
const {promise, resolve} = Promise.withResolvers(); const {promise, resolve} = withResolvers();
this.socket.addEventListener('open', resolve); this.socket.addEventListener('open', resolve);
this.socket.addEventListener('error', () => { this.socket.addEventListener('error', () => {
this.accept(encode({type: 'ConnectionStatus', payload: 'aborted'})); this.accept(encode({type: 'ConnectionStatus', payload: 'aborted'}));

View File

@ -1,6 +1,7 @@
import {Encoder, Decoder} from '@msgpack/msgpack'; import {Encoder, Decoder} from '@msgpack/msgpack';
import {LRUCache} from 'lru-cache'; import {LRUCache} from 'lru-cache';
import {withResolvers} from '@/util/promise.js';
import Script from '@/util/script.js'; import Script from '@/util/script.js';
import EntityFactory from './entity-factory.js'; import EntityFactory from './entity-factory.js';
@ -326,11 +327,7 @@ export default class Ecs {
async readJson(uri) { async readJson(uri) {
const key = ['$$json', uri].join(':'); const key = ['$$json', uri].join(':');
if (!cache.has(key)) { if (!cache.has(key)) {
let promise, resolve, reject; const {promise, resolve, reject} = withResolvers();
promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
cache.set(key, promise); cache.set(key, promise);
this.readAsset(uri) this.readAsset(uri)
.then((chars) => { .then((chars) => {

View File

@ -1,6 +1,7 @@
import {LRUCache} from 'lru-cache'; import {LRUCache} from 'lru-cache';
import Ecs from '@/ecs/ecs.js'; import Ecs from '@/ecs/ecs.js';
import {withResolvers} from '@/util/promise.js';
const cache = new LRUCache({ const cache = new LRUCache({
max: 128, max: 128,
@ -9,11 +10,7 @@ const cache = new LRUCache({
export default class ClientEcs extends Ecs { export default class ClientEcs extends Ecs {
async readAsset(uri) { async readAsset(uri) {
if (!cache.has(uri)) { if (!cache.has(uri)) {
let promise, resolve, reject; const {promise, resolve, reject} = withResolvers();
promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
cache.set(uri, promise); cache.set(uri, promise);
fetch(new URL(uri, window.location.origin)) fetch(new URL(uri, window.location.origin))
.then(async (response) => { .then(async (response) => {

View File

@ -7,6 +7,7 @@ import {
RESOLUTION, RESOLUTION,
TPS, TPS,
} from '@/util/constants.js'; } from '@/util/constants.js';
import {withResolvers} from '@/util/promise.js';
import createEcs from './create/ecs.js'; import createEcs from './create/ecs.js';
import createForest from './create/forest.js'; import createForest from './create/forest.js';
@ -48,11 +49,7 @@ export default class Engine {
} }
async readAsset(uri) { async readAsset(uri) {
if (!cache.has(uri)) { if (!cache.has(uri)) {
let promise, resolve, reject; const {promise, resolve, reject} = withResolvers();
promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
cache.set(uri, promise); cache.set(uri, promise);
server.readAsset(uri) server.readAsset(uri)
.then(resolve) .then(resolve)

View File

@ -2,6 +2,7 @@ import {del, get, set} from 'idb-keyval';
import {encode} from '@/net/packets/index.js'; import {encode} from '@/net/packets/index.js';
import Server from '@/net/server.js'; import Server from '@/net/server.js';
import {withResolvers} from '@/util/promise.js';
import createEcs from './create/ecs.js'; import createEcs from './create/ecs.js';
import './create/forest.js'; import './create/forest.js';
@ -62,27 +63,19 @@ onmessage = async (event) => {
})(); })();
if (import.meta.hot) { if (import.meta.hot) {
const createResolver = () => { const before = withResolvers();
let r; const promises = [before.promise];
const promise = new Promise((resolve) => {
r = resolve;
});
promise.resolve = r;
return promise;
};
const beforeResolver = createResolver();
const resolvers = [beforeResolver];
import.meta.hot.on('vite:beforeUpdate', async () => { import.meta.hot.on('vite:beforeUpdate', async () => {
engine.stop(); engine.stop();
await engine.disconnectPlayer(0); await engine.disconnectPlayer(0);
await engine.saveEcses(); await engine.saveEcses();
beforeResolver.resolve(); before.resolve();
}); });
import.meta.hot.accept('./engine.js'); import.meta.hot.accept('./engine.js');
import.meta.hot.accept('./create/player.js', async ({default: createPlayer}) => { import.meta.hot.accept('./create/player.js', async ({default: createPlayer}) => {
const resolver = createResolver(); const {promise, resolve} = withResolvers();
resolvers.push(resolver); promises.push(promise);
await beforeResolver; await before.promise;
const oldPlayer = await engine.loadPlayer(0); const oldPlayer = await engine.loadPlayer(0);
const player = await createPlayer(0); const player = await createPlayer(0);
// Less jarring // Less jarring
@ -90,12 +83,12 @@ if (import.meta.hot) {
player.Direction = oldPlayer.Direction; player.Direction = oldPlayer.Direction;
player.Position = oldPlayer.Position; player.Position = oldPlayer.Position;
await engine.savePlayer(0, player); await engine.savePlayer(0, player);
resolver.resolve(); resolve();
}); });
import.meta.hot.accept('./create/forest.js', async ({default: createForest}) => { import.meta.hot.accept('./create/forest.js', async ({default: createForest}) => {
const resolver = createResolver(); const {promise, resolve} = withResolvers();
resolvers.push(resolver); promises.push(promise);
await beforeResolver; await before.promise;
delete engine.ecses['forests/0']; delete engine.ecses['forests/0'];
await engine.server.removeData('forests/0'); await engine.server.removeData('forests/0');
const forest = createEcs(engine.Ecs); const forest = createEcs(engine.Ecs);
@ -103,12 +96,12 @@ if (import.meta.hot) {
await forest.create(entity); await forest.create(entity);
} }
await engine.saveEcs('forests/0', forest); await engine.saveEcs('forests/0', forest);
resolver.resolve(); resolve();
}); });
import.meta.hot.accept('./create/homestead.js', async ({default: createHomestead}) => { import.meta.hot.accept('./create/homestead.js', async ({default: createHomestead}) => {
const resolver = createResolver(); const {promise, resolve} = withResolvers();
resolvers.push(resolver); promises.push(promise);
await beforeResolver; await before.promise;
delete engine.ecses['homesteads/0']; delete engine.ecses['homesteads/0'];
await engine.server.removeData('homesteads/0'); await engine.server.removeData('homesteads/0');
const homestead = createEcs(engine.Ecs); const homestead = createEcs(engine.Ecs);
@ -116,10 +109,10 @@ if (import.meta.hot) {
await homestead.create(entity); await homestead.create(entity);
} }
await engine.saveEcs('homesteads/0', homestead); await engine.saveEcs('homesteads/0', homestead);
resolver.resolve(); resolve();
}); });
import.meta.hot.on('vite:afterUpdate', async () => { import.meta.hot.on('vite:afterUpdate', async () => {
await Promise.all(resolvers); await Promise.all(promises);
postMessage(encode({type: 'ConnectionStatus', payload: 'aborted'})); postMessage(encode({type: 'ConnectionStatus', payload: 'aborted'}));
close(); close();
}); });

View File

@ -1,6 +1,6 @@
export const CHUNK_SIZE = 32; export const CHUNK_SIZE = 32;
export const CLIENT_LATENCY = 0; export const CLIENT_LATENCY = 100;
export const CLIENT_PREDICTION = true; export const CLIENT_PREDICTION = true;
@ -11,6 +11,6 @@ export const RESOLUTION = {
y: 450, y: 450,
}; };
export const SERVER_LATENCY = 0; export const SERVER_LATENCY = 100;
export const TPS = 60; export const TPS = 60;

View File

@ -1,3 +1,4 @@
import {withResolvers} from '@/util/promise.js';
import TickingPromise from '@/util/ticking-promise.js'; import TickingPromise from '@/util/ticking-promise.js';
const Modulators = { const Modulators = {
@ -35,9 +36,7 @@ export default function lfo(object, properties) {
} }
} }
oscillator.low = oscillator.median - oscillator.magnitude / 2; oscillator.low = oscillator.median - oscillator.magnitude / 2;
oscillator.promise = new Promise((resolve) => { ({promise: oscillator.promise, resolve: oscillator.stop} = withResolvers());
oscillator.stop = resolve;
});
oscillator.promise.then(() => { oscillator.promise.then(() => {
delete oscillators[key]; delete oscillators[key];
}); });

7
app/util/promise.js Normal file
View File

@ -0,0 +1,7 @@
export function withResolvers() {
let resolve, reject, promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return {promise, reject, resolve};
}