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,
},
};
return (new TextEncoder()).encode(JSON.stringify(player));
return player;
}

View File

@ -1,10 +1,19 @@
import EntityFactory from './entity-factory.js';
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 encoder = new Encoder();
const textDecoder = new TextDecoder();
export default class Ecs {
$$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) {
let Class;
if (componentNames) {

View File

@ -5,7 +5,6 @@ import {
RESOLUTION,
TPS,
} from '@/util/constants.js';
import Script from '@/util/script.js';
import createEcs from './create/ecs.js';
import createForest from './create/forest.js';
@ -19,6 +18,8 @@ const cache = new LRUCache({
max: 128,
});
const textEncoder = new TextEncoder();
export default class Engine {
connectedPlayers = new Map();
@ -59,41 +60,6 @@ export default class Engine {
}
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) {
for (const [connection, connectedPlayer] of engine.connectedPlayers) {
if (entity !== connectedPlayer.entity) {
@ -280,9 +246,9 @@ export default class Engine {
}
async loadPlayer(id) {
let buffer;
let player;
try {
buffer = await this.server.readData(['players', `${id}`].join('/'))
player = await this.server.readJson(['players', `${id}`].join('/'))
}
catch (error) {
if ('ENOENT' !== error.code) {
@ -309,13 +275,10 @@ export default class Engine {
['forests', `${id}`].join('/'),
forest,
);
buffer = await createPlayer(id);
await this.server.writeData(
['players', `${id}`].join('/'),
buffer,
);
player = await createPlayer(id);
await this.savePlayer(id, player);
}
return JSON.parse((new TextDecoder()).decode(buffer));
return player;
}
async saveEcs(path, ecs) {
@ -332,8 +295,7 @@ export default class Engine {
}
async savePlayer(id, entity) {
const encoder = new TextEncoder();
const buffer = encoder.encode(JSON.stringify(entity.toJSON()));
const buffer = textEncoder.encode(JSON.stringify(entity));
await this.server.writeData(['players', `${id}`].join('/'), buffer);
}

View File

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

View File

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

View File

@ -1,5 +1,4 @@
import Ecs from '@/ecs/ecs.js';
import Script from '@/util/script.js';
import {LRUCache} from 'lru-cache';
@ -24,39 +23,4 @@ export default class ClientEcs extends Ecs {
}
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);
}
}
}