refactor: asset and data I/O

This commit is contained in:
cha0s 2024-07-21 01:37:40 -05:00
parent 1d35b9b6d5
commit 8bf26ef7cd
6 changed files with 66 additions and 85 deletions

View File

@ -62,6 +62,6 @@ export default async function createPlayer(id) {
activeSlot: 0, activeSlot: 0,
}, },
}; };
return (new TextEncoder()).encode(JSON.stringify(player)); return player;
} }

View File

@ -1,10 +1,19 @@
import EntityFactory from './entity-factory.js'; import EntityFactory from './entity-factory.js';
import {Encoder, Decoder} from '@msgpack/msgpack'; import {Encoder, Decoder} from '@msgpack/msgpack';
import {LRUCache} from 'lru-cache';
import Script from '@/util/script.js';
const cache = new LRUCache({
max: 128,
});
const decoder = new Decoder(); const decoder = new Decoder();
const encoder = new Encoder(); const encoder = new Encoder();
const textDecoder = new TextDecoder();
export default class Ecs { export default class Ecs {
$$caret = 1; $$caret = 1;
@ -308,6 +317,48 @@ export default class Ecs {
} }
} }
async readJson(uri) {
const key = ['$$json', uri].join(':');
if (!cache.has(key)) {
let promise, resolve, reject;
promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
cache.set(key, promise);
this.readAsset(uri)
.then((chars) => {
resolve(
chars.byteLength > 0
? JSON.parse(textDecoder.decode(chars))
: {},
);
})
.catch(reject);
}
return cache.get(key);
}
async readScript(uriOrCode, context = {}) {
if (!uriOrCode) {
return undefined;
}
let code = '';
if (!uriOrCode.startsWith('/')) {
code = uriOrCode;
}
else {
const buffer = await this.readAsset(uriOrCode);
if (buffer.byteLength > 0) {
code = textDecoder.decode(buffer);
}
}
if (!code) {
return undefined;
}
return Script.fromCode(code, context);
}
rebuild(entityId, componentNames) { rebuild(entityId, componentNames) {
let Class; let Class;
if (componentNames) { if (componentNames) {

View File

@ -5,7 +5,6 @@ import {
RESOLUTION, RESOLUTION,
TPS, TPS,
} from '@/util/constants.js'; } from '@/util/constants.js';
import Script from '@/util/script.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';
@ -19,6 +18,8 @@ const cache = new LRUCache({
max: 128, max: 128,
}); });
const textEncoder = new TextEncoder();
export default class Engine { export default class Engine {
connectedPlayers = new Map(); connectedPlayers = new Map();
@ -59,41 +60,6 @@ export default class Engine {
} }
return cache.get(uri); return cache.get(uri);
} }
async readJson(uri) {
const key = ['$$json', uri].join(':');
if (!cache.has(key)) {
let promise, resolve, reject;
promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
cache.set(key, promise);
this.readAsset(uri)
.then((chars) => {
resolve(chars.byteLength > 0 ? JSON.parse((new TextDecoder()).decode(chars)) : {});
})
.catch(reject);
}
return cache.get(key);
}
async readScript(uriOrCode, context) {
if (!uriOrCode) {
return undefined;
}
let code = '';
if (!uriOrCode.startsWith('/')) {
code = uriOrCode;
}
else {
const buffer = await this.readAsset(uriOrCode);
if (buffer.byteLength > 0) {
code = (new TextDecoder()).decode(buffer);
}
}
if (code) {
return Script.fromCode(code, context);
}
}
async switchEcs(entity, path, updates) { async switchEcs(entity, path, updates) {
for (const [connection, connectedPlayer] of engine.connectedPlayers) { for (const [connection, connectedPlayer] of engine.connectedPlayers) {
if (entity !== connectedPlayer.entity) { if (entity !== connectedPlayer.entity) {
@ -280,9 +246,9 @@ export default class Engine {
} }
async loadPlayer(id) { async loadPlayer(id) {
let buffer; let player;
try { try {
buffer = await this.server.readData(['players', `${id}`].join('/')) player = await this.server.readJson(['players', `${id}`].join('/'))
} }
catch (error) { catch (error) {
if ('ENOENT' !== error.code) { if ('ENOENT' !== error.code) {
@ -309,13 +275,10 @@ export default class Engine {
['forests', `${id}`].join('/'), ['forests', `${id}`].join('/'),
forest, forest,
); );
buffer = await createPlayer(id); player = await createPlayer(id);
await this.server.writeData( await this.savePlayer(id, player);
['players', `${id}`].join('/'),
buffer,
);
} }
return JSON.parse((new TextDecoder()).decode(buffer)); return player;
} }
async saveEcs(path, ecs) { async saveEcs(path, ecs) {
@ -332,8 +295,7 @@ export default class Engine {
} }
async savePlayer(id, entity) { async savePlayer(id, entity) {
const encoder = new TextEncoder(); const buffer = textEncoder.encode(JSON.stringify(entity));
const buffer = encoder.encode(JSON.stringify(entity.toJSON()));
await this.server.writeData(['players', `${id}`].join('/'), buffer); await this.server.writeData(['players', `${id}`].join('/'), buffer);
} }

View File

@ -1,5 +1,7 @@
import {SERVER_LATENCY} from '@/util/constants.js'; import {SERVER_LATENCY} from '@/util/constants.js';
const textDecoder = new TextDecoder();
export default class Server { export default class Server {
constructor() { constructor() {
this.listeners = {}; this.listeners = {};
@ -19,6 +21,9 @@ export default class Server {
} }
this.listeners[type].push(listener); this.listeners[type].push(listener);
} }
async readJson(path) {
return JSON.parse(textDecoder.decode(await this.readData(path)));
}
removePacketListener(type, listener) { removePacketListener(type, listener) {
const listeners = this.listeners[type]; const listeners = this.listeners[type];
if (!listeners) { if (!listeners) {

View File

@ -83,8 +83,7 @@ if (import.meta.hot) {
const resolver = createResolver(); const resolver = createResolver();
resolvers.push(resolver); resolvers.push(resolver);
await beforeResolver; await beforeResolver;
const oldBuffer = await engine.server.readData('players/0'); const oldPlayer = await engine.server.readJson('players/0');
const oldPlayer = JSON.parse((new TextDecoder()).decode(oldBuffer));
const buffer = await createPlayer(0); const buffer = await createPlayer(0);
const player = JSON.parse((new TextDecoder()).decode(buffer)); const player = JSON.parse((new TextDecoder()).decode(buffer));
// Less jarring // Less jarring

View File

@ -1,5 +1,4 @@
import Ecs from '@/ecs/ecs.js'; import Ecs from '@/ecs/ecs.js';
import Script from '@/util/script.js';
import {LRUCache} from 'lru-cache'; import {LRUCache} from 'lru-cache';
@ -24,39 +23,4 @@ export default class ClientEcs extends Ecs {
} }
return cache.get(uri); return cache.get(uri);
} }
async readJson(uri) {
const key = ['$$json', uri].join(':');
if (!cache.has(key)) {
let promise, resolve, reject;
promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
cache.set(key, promise);
this.readAsset(uri)
.then((chars) => {
resolve(chars.byteLength > 0 ? JSON.parse((new TextDecoder()).decode(chars)) : {});
})
.catch(reject);
}
return cache.get(key);
}
async readScript(uriOrCode, context = {}) {
if (!uriOrCode) {
return undefined;
}
let code = '';
if (!uriOrCode.startsWith('/')) {
code = uriOrCode;
}
else {
const buffer = await this.readAsset(uriOrCode);
if (buffer.byteLength > 0) {
code = (new TextDecoder()).decode(buffer);
}
}
if (code) {
return Script.fromCode(code, context);
}
}
} }