refactor: resource loading

This commit is contained in:
cha0s 2021-01-16 04:12:51 -06:00
parent 044db82ca2
commit 2356ec5011
28 changed files with 20575 additions and 13447 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -20,13 +20,6 @@ export default (latus) => class EntityList extends decorate(JsonResource) {
#quadTree = new QuadTree();
constructor(entities = []) {
super();
for (let i = 0; i < entities.length; i++) {
this.addEntity(entities[i]);
}
}
async acceptPacket(packet) {
if ('EntityListUpdateEntity' === packet.constructor.type) {
for (let i = 0; i < packet.data.length; i++) {
@ -113,6 +106,12 @@ export default (latus) => class EntityList extends decorate(JsonResource) {
: undefined;
}
load(entities = []) {
for (let i = 0; i < entities.length; i++) {
this.addEntity(entities[i]);
}
}
packets(informed) {
const packets = [];
// Visible entities.

View File

@ -38,10 +38,8 @@ export default (latus) => class Entity extends decorate(JsonResource) {
#traitsAcceptingPackets = [];
constructor(json = {}) {
constructor() {
super();
const {instanceUuid, traitInstances = []} = json;
this.#originalJson = json;
this.once('destroyed', () => {
this.removeAllTraits();
});
@ -49,11 +47,9 @@ export default (latus) => class Entity extends decorate(JsonResource) {
this.tick = this.tick.bind(this);
// Fast props.
this.numericUid = numericUid++;
this.instanceUuid = instanceUuid || this.numericId;
this.position = [0, 0];
this.room = null;
this.visibleAabb = [0, 0, 0, 0];
this.addTraits(traitInstances);
}
acceptPacket(packet) {
@ -197,6 +193,13 @@ export default (latus) => class Entity extends decorate(JsonResource) {
return type in this.#traits;
}
load(json = {}) {
const {instanceUuid, traitInstances = []} = json;
this.#originalJson = json;
this.instanceUuid = instanceUuid || this.numericId;
this.addTraits(traitInstances);
}
markAsDirty() {
this.#markedAsDirty = true;
}

File diff suppressed because it is too large Load Diff

View File

@ -3,8 +3,26 @@ import {imageSize} from 'image-size';
export class Image extends Resource {
constructor(buffer) {
constructor() {
super();
this.texture = {
height: 0,
isFake: true,
width: 0,
};
}
destroy() {
if (!this.texture.isFake) {
this.texture.destroy();
}
}
get height() {
return this.texture.height;
}
load(buffer) {
if (buffer) {
const {height, width} = imageSize(Buffer.from(buffer));
if ('client' === process.env.SIDE) {
@ -29,16 +47,6 @@ export class Image extends Resource {
}
}
destroy() {
if (!this.texture.isFake) {
this.texture.destroy();
}
}
get height() {
return this.texture.height;
}
get size() {
return [this.width, this.height];
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,10 @@ import Resource from './resource';
export default class JsonResource extends Resource {
async extendAndLoad(json) {
return this.load(await this.constructor.extendJson(json));
}
static async extendJson(json) {
if ('string' === typeof json.extends) {
// eslint-disable-next-line no-param-reassign
@ -14,11 +18,15 @@ export default class JsonResource extends Resource {
static async load(json = {}) {
const {extends: uri} = json;
const resource = new this(await this.extendJson(json));
const resource = new this();
resource.uri = uri;
resource.load(await this.extendJson(json));
return resource;
}
// eslint-disable-next-line class-methods-use-this, no-unused-vars
load(json) {}
static mergeJson(json) {
if (json.extends) {
const {extends: xtends, ...rest} = json;

View File

@ -18,10 +18,14 @@ export default class Resource extends decorate(Class) {
this.instanceUuid = uuid();
}
// eslint-disable-next-line class-methods-use-this, no-unused-vars
load(buffer) {}
static async load(uri) {
const buffer = await this.read(uri);
const resource = new this(buffer);
const resource = new this();
resource.uri = uri;
resource.load(buffer);
return resource;
}

View File

@ -69,4 +69,10 @@ describe('JsonResource', () => {
expect(resource.json.foo).to.equal(420);
expect(resource.json.bar).to.equal('hoo');
});
it("can load to instance", async () => {
const resource = new JsonResourceSubclass();
resource.load({foo: 420, bar: 'hoo'});
expect(resource.json.foo).to.equal(420);
expect(resource.json.bar).to.equal('hoo');
});
});

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ export default class ReceiverSynchronizer {
this.latus = latus;
}
acceptPacket(packet) {
async acceptPacket(packet) {
const {constructor: {s13nType}} = packet;
switch (s13nType) {
case 'create': {
@ -19,10 +19,10 @@ export default class ReceiverSynchronizer {
}
const json = packet.data.spec;
if (this.#synchronized[type][id]) {
this.#synchronized[type][id].fromNetwork(json);
this.#synchronized[type][id].extendAndLoad(json);
}
else {
this.#synchronized[type][id] = new Resource(json);
this.#synchronized[type][id] = await Resource.load(json);
}
break;
}

View File

@ -73,7 +73,7 @@ export default class SenderSynchronizer {
delete this.#synchronized[type][id];
}
send(socket, informed) {
async send(socket, informed) {
const synchronizerPackets = this.packetsFor(informed);
for (let i = 0; i < synchronizerPackets.length; i++) {
this.#nextSyncPackets.push(synchronizerPackets[i]);
@ -83,7 +83,7 @@ export default class SenderSynchronizer {
}
this.#queuedPackets = [];
if (socket && this.#nextSyncPackets.length > 0) {
socket.send(['Bundle', this.#nextSyncPackets]);
await socket.send(['Bundle', this.#nextSyncPackets]);
this.#nextSyncPackets = [];
}
}

File diff suppressed because it is too large Load Diff

View File

@ -4,12 +4,9 @@ import {JsonResource} from '@avocado/resource';
export default () => class Sound extends JsonResource {
constructor({interval = 0, volume = 1, sound} = {}) {
constructor() {
super();
this.handle = undefined;
this.interval = interval;
this.originalVolume = volume;
this.sound = sound;
this.timestamp = 0;
}
@ -28,6 +25,12 @@ export default () => class Sound extends JsonResource {
return extended;
}
load({interval = 0, volume = 1, sound} = {}) {
this.interval = interval;
this.originalVolume = volume;
this.sound = sound;
}
play() {
if (this.interval > 0 && this.timestamp > 0) {
if ((Date.now() - this.timestamp) < this.interval) {

File diff suppressed because it is too large Load Diff

View File

@ -22,43 +22,9 @@ const decorate = compose(
export default () => class Animation extends decorate(JsonResource) {
constructor(json = {}) {
constructor() {
super();
this.imageUri = undefined;
if (json.frameRate) {
this.ticker.frequency = json.frameRate;
}
const keys = [
'directionCount',
'frameCount',
'frameSize',
'imageUri',
];
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
if (json[key]) {
this[key] = json[key];
}
}
}
get sourceRectangle() {
if (0 === this.frameCount) {
return [0, 0, 0, 0];
}
const {frameSize} = this;
if (Vector.isZero(frameSize)) {
return [0, 0, 0, 0];
}
const offset = [
this.index % this.frameCount,
this.direction,
];
const rectangle = Rectangle.compose(
Vector.mul(frameSize, offset),
frameSize,
);
return rectangle;
}
clampDirection(direction) {
@ -90,9 +56,46 @@ export default () => class Animation extends decorate(JsonResource) {
super.direction = this.clampDirection(direction << 0);
}
load(json = {}) {
if (json.frameRate) {
this.ticker.frequency = json.frameRate;
}
const keys = [
'directionCount',
'frameCount',
'frameSize',
'imageUri',
];
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
if (json[key]) {
this[key] = json[key];
}
}
}
reset() {
super.reset();
this.currentFrame = 0;
}
get sourceRectangle() {
if (0 === this.frameCount) {
return [0, 0, 0, 0];
}
const {frameSize} = this;
if (Vector.isZero(frameSize)) {
return [0, 0, 0, 0];
}
const offset = [
this.index % this.frameCount,
this.direction,
];
const rectangle = Rectangle.compose(
Vector.mul(frameSize, offset),
frameSize,
);
return rectangle;
}
};

File diff suppressed because it is too large Load Diff

View File

@ -16,27 +16,10 @@ const decorate = compose(
export default (latus) => class Layer extends decorate(JsonResource) {
constructor({
entityList,
tiles,
tileset,
world,
} = {}) {
constructor() {
super();
const {fromResourceType: {EntityList, Tiles, Tileset}} = resource(latus);
this.entityList = entityList || new EntityList();
this.index = -1;
this.tileEntities = {};
this.tileGeometry = [];
this.tiles = new Tiles(tiles);
// Listeners.
this.entityList.on('entityAdded', this.onEntityAddedToLayer, this);
this.entityList.on('entityRemoved', this.onEntityRemovedFromLayer, this);
this.tiles.on('dataChanged', this.onTileDataChanged, this);
// this.on('tilesetChanged', this.onTilesetChanged, this);
// this.on('worldChanged', this.onWorldChanged, this);
this.tileset = tileset || new Tileset();
this.world = world;
}
acceptPacket(packet) {
@ -149,6 +132,19 @@ export default (latus) => class Layer extends decorate(JsonResource) {
return this.tiles.indexAt(position);
}
load({
entityList,
tiles,
tileset,
world,
} = {}) {
const {fromResourceType: {EntityList, Tiles, Tileset}} = resource(latus);
this.setEntityList(entityList || new EntityList());
this.setTiles(new Tiles(tiles));
this.tileset = tileset || new Tileset();
this.world = world;
}
onEntityAddedToLayer(entity) {
entity.setIntoLayer(this);
this.emit('entityAdded', entity);
@ -219,10 +215,29 @@ export default (latus) => class Layer extends decorate(JsonResource) {
// this.tileEntities[index].splice(entityIndex, 1);
// }
setEntityList(entityList) {
if (this.entityList) {
this.entityList.off('entityAdded', this.onEntityAddedToLayer);
this.entityList.off('entityRemoved', this.onEntityRemovedFromLayer);
}
this.entityList = entityList;
this.entityList.on('entityAdded', this.onEntityAddedToLayer, this);
this.entityList.on('entityRemoved', this.onEntityRemovedFromLayer, this);
this.tiles.on('dataChanged', this.onTileDataChanged, this);
}
setTileAt(position, tile) {
this.tiles.setTileAt(position, tile);
}
setTiles(tiles) {
if (this.tiles) {
this.tiles.off('dataChanged', this.onTileDataChanged);
}
this.tiles = tiles;
this.tiles.on('dataChanged', this.onTileDataChanged, this);
}
tick(elapsed) {
this.entityList.tick(elapsed);
}

View File

@ -10,12 +10,9 @@ const decorate = compose(
export default (latus) => class Layers extends decorate(JsonResource) {
constructor({layers = []} = {}) {
constructor() {
super();
this.layers = [];
for (let i = 0; i < layers.length; i++) {
this.addLayer(layers[i]);
}
}
acceptPacket(packet) {
@ -41,8 +38,6 @@ export default (latus) => class Layers extends decorate(JsonResource) {
layer.on('entityAdded', this.onEntityAddedToLayers, this);
layer.on('entityRemoved', this.onEntityRemovedFromLayers, this);
this.layers.push(layer);
// eslint-disable-next-line no-param-reassign
layer.index = this.layers.length - 1;
this.emit('layerAdded', layer);
}
@ -94,6 +89,13 @@ export default (latus) => class Layers extends decorate(JsonResource) {
return this.layers[index];
}
load({layers = []} = {}) {
this.removeAllLayers();
for (let i = 0; i < layers.length; i++) {
this.addLayer(layers[i]);
}
}
onEntityAddedToLayers(entity) {
this.emit('entityAdded', entity);
}
@ -123,6 +125,12 @@ export default (latus) => class Layers extends decorate(JsonResource) {
return packets;
}
removeAllLayers() {
for (let i = 0; i < this.layers.length; i++) {
this.removeLayer(this.layers[i]);
}
}
removeEntityFromLayer(entity, layerIndex) {
const layer = this.layers[layerIndex];
if (!layer) {
@ -131,7 +139,6 @@ export default (latus) => class Layers extends decorate(JsonResource) {
layer.removeEntity(entity);
}
// TODO: fix index for remaining layers
removeLayer(layer) {
const index = this.layers.indexOf(layer);
if (-1 === index) {

View File

@ -28,23 +28,13 @@ let s13Id = 1;
export default (latus) => class Room extends decorate(JsonResource) {
constructor({layers, size} = {}) {
constructor() {
super();
this.bounds = [];
this._s13Id = s13Id++;
this.layers = layers;
// Listeners.
this.layers.on('entityAdded', this.onEntityAddedToRoom, this);
this.layers.on('entityRemoved', this.onEntityRemovedFromRoom, this);
this.layers.on('layerAdded', this.onLayerAdded, this);
const allEntities = this.allEntities();
for (let i = 0; i < allEntities.length; i++) {
this.onEntityAddedToRoom(allEntities[i]);
}
const {fromResourceType: {Layers}} = resource(latus);
this.setLayers(new Layers());
this.on('worldChanged', this.onWorldChanged, this);
if (size) {
this.size = size;
}
}
acceptPacket(packet) {
@ -81,7 +71,7 @@ export default (latus) => class Room extends decorate(JsonResource) {
static async extendJson(json) {
const extended = await super.extendJson(json);
const {fromResourceType: {Layers}} = resource(latus);
extended.layers = extended.layers
extended.layersInstance = extended.layers
? await Layers.load(extended.layers)
: new Layers();
return extended;
@ -95,6 +85,15 @@ export default (latus) => class Room extends decorate(JsonResource) {
return this.layers.layer(index);
}
load({layersInstance, size} = {}) {
if (layersInstance) {
this.setLayers(layersInstance);
}
if (size) {
this.size = size;
}
}
onEntityAddedToRoom(entity) {
entity.attachToRoom(this);
this.emit('entityAdded', entity);
@ -110,6 +109,12 @@ export default (latus) => class Room extends decorate(JsonResource) {
layer.world = this.world;
}
// eslint-disable-next-line class-methods-use-this
onLayerRemoved(layer) {
// eslint-disable-next-line no-param-reassign
delete layer.world;
}
onWorldChanged() {
this.layers.world = this.world;
// Update bounds.
@ -140,6 +145,34 @@ export default (latus) => class Room extends decorate(JsonResource) {
this.layers.removeEntityFromLayer(entity, layerIndex);
}
setLayers(layers) {
if (this.layers) {
const allEntities = this.layers.allEntities();
for (let i = 0; i < allEntities.length; i++) {
this.onEntityRemovedFromRoom(allEntities[i]);
}
this.layers.off('layerAdded', this.onLayerAdded);
this.layers.off('layerRemoved', this.onLayerRemoved);
this.layers.off('entityAdded', this.onEntityAddedToRoom);
this.layers.off('entityRemoved', this.onEntityRemovedFromRoom);
for (let i = 0; i < this.layers.length; i++) {
this.onLayerRemoved(this.layers[i]);
}
}
this.layers = layers;
for (let i = 0; i < this.layers.length; i++) {
this.onLayerAdded(this.layers[i]);
}
this.layers.on('entityRemoved', this.onEntityRemovedFromRoom, this);
this.layers.on('entityAdded', this.onEntityAddedToRoom, this);
this.layers.on('layerRemoved', this.onLayerRemoved, this);
this.layers.on('layerAdded', this.onLayerAdded, this);
const allEntities = this.layers.allEntities();
for (let i = 0; i < allEntities.length; i++) {
this.onEntityAddedToRoom(allEntities[i]);
}
}
s13Id() {
return this._s13Id;
}
@ -152,7 +185,6 @@ export default (latus) => class Room extends decorate(JsonResource) {
}
toNetwork(informed) {
console.log(this);
return {
layers: this.layers.toNetwork(informed),
size: this.size,

View File

@ -16,15 +16,9 @@ const decorate = compose(
export default () => class Tileset extends decorate(JsonResource) {
constructor({image, tileSize} = {}) {
constructor() {
super();
this.subimages = [];
if (image) {
this.image = image;
}
if (tileSize) {
this.tileSize = tileSize;
}
}
destroy() {
@ -51,6 +45,15 @@ export default () => class Tileset extends decorate(JsonResource) {
super.image = image;
}
load({image, tileSize} = {}) {
if (image) {
this.image = image;
}
if (tileSize) {
this.tileSize = tileSize;
}
}
recalculateSubimages(image) {
this.destroy();
if (!image) {

File diff suppressed because it is too large Load Diff

View File

@ -16,12 +16,11 @@ export default class Trait extends decorate(JsonResource) {
#previousState = {};
constructor({entity, params = {}, state = {}} = {}) {
constructor() {
super();
this.entity = entity;
const {constructor} = this;
this.params = constructor.defaultParamsWith(params);
this.state = constructor.defaultStateWith(state);
this.params = constructor.defaultParams();
this.state = constructor.defaultState();
this.#previousState = JSON.parse(JSON.stringify(this.state));
if (this.tick) {
this.tick = this.tick.bind(this);
@ -93,6 +92,14 @@ export default class Trait extends decorate(JsonResource) {
return {};
}
load({entity, params = {}, state = {}} = {}) {
this.entity = entity;
const {constructor} = this;
this.params = constructor.defaultParamsWith(params);
this.state = constructor.defaultStateWith(state);
this.#previousState = JSON.parse(JSON.stringify(this.state));
}
markAsClean() {
const state = Object.entries(this.state);
for (let i = 0; i < state.length; i++) {

File diff suppressed because it is too large Load Diff