refactor: s13n

This commit is contained in:
cha0s 2021-01-13 02:16:27 -06:00
parent 96b25d94b3
commit d7475494a2
17 changed files with 144 additions and 88 deletions

View File

@ -17,7 +17,7 @@ export default (latus) => class EntityUpdateTraitPacket extends SynchronizedUpda
}
}
static get synchronizationSchema() {
static get s13nSchema() {
return {
traits: [
{

View File

@ -1,14 +1,7 @@
import {compose, EventEmitter} from '@latus/core';
import {QuadTree, Rectangle} from '@avocado/math';
import {
JsonResource,
resource,
} from '@avocado/resource';
import {
normalize,
SynchronizedCreatePacket,
SynchronizedDestroyPacket,
} from '@avocado/s13n';
import {JsonResource, resource} from '@avocado/resource';
import {normalize} from '@avocado/s13n';
const decorate = compose(
EventEmitter,
@ -46,15 +39,21 @@ export default (latus) => class EntityList extends decorate(JsonResource) {
}
}
}
if (packet instanceof SynchronizedCreatePacket) {
const {fromResourceType: {Entity}} = resource(latus);
this.addEntity(await Entity.load(packet.data.spec));
}
if (packet instanceof SynchronizedDestroyPacket) {
const uuid = packet.data.synchronized.id;
if (this.#entities[uuid]) {
this.#entities[uuid].destroy();
const {constructor: {s13nType}} = packet;
switch (s13nType) {
case 'create': {
const {fromResourceType: {Entity}} = resource(latus);
this.addEntity(await Entity.load(packet.data.spec));
break;
}
case 'destroy': {
const uuid = packet.data.synchronized.id;
if (this.#entities[uuid]) {
this.#entities[uuid].destroy();
}
break;
}
default:
}
}

View File

@ -297,7 +297,7 @@ export default (latus) => class Entity extends decorate(JsonResource) {
types.forEach((type) => this.removeTrait(type));
}
synchronizationId() {
s13Id() {
return this.instanceUuid;
}

View File

@ -22,6 +22,7 @@
"test.js.map"
],
"dependencies": {
"@avocado/resource": "^2.0.0",
"@latus/core": "2.0.0",
"@latus/socket": "2.0.0",
"debug": "4.3.1",

View File

@ -1,7 +1,4 @@
import SynchronizedCreatePacket from '../packets/synchronized-create';
import SynchronizedDestroyPacket from '../packets/synchronized-destroy';
import SynchronizedUpdatePacket from '../packets/synchronized-update';
import {synchronized} from '../synchronized';
import {resource} from '@avocado/resource';
export default class ClientSynchronizer {
@ -11,28 +8,35 @@ export default class ClientSynchronizer {
}
acceptPacket(packet) {
if ((packet instanceof SynchronizedCreatePacket)) {
const {id, type} = packet.data.synchronized;
const {fromS13Type: {[type]: Synchronized}} = synchronized(this.latus);
if (!(type in this._synchronized)) {
this._synchronized[type] = {};
const {constructor: {s13nType}} = packet;
switch (s13nType) {
case 'create': {
const {id, type} = packet.data.synchronized;
const {fromResourceId: {[type]: Resource}} = resource(this.latus);
if (!(type in this._synchronized)) {
this._synchronized[type] = {};
}
const json = packet.data.spec;
if (this._synchronized[type][id]) {
this._synchronized[type][id].fromNetwork(json);
}
else {
this._synchronized[type][id] = new Resource(json);
}
break;
}
const json = packet.data.spec;
if (this._synchronized[type][id]) {
this._synchronized[type][id].fromNetwork(json);
case 'destroy': {
const {id, type} = packet.data.synchronized;
this._synchronized[type][id].destroy();
this._synchronized[type][id] = null;
break;
}
else {
this._synchronized[type][id] = new Synchronized(json);
case 'update': {
const {id, type} = packet.data.synchronized;
this._synchronized[type][id].acceptPacket(packet);
break;
}
}
else if ((packet instanceof SynchronizedUpdatePacket)) {
const {id, type} = packet.data.synchronized;
this._synchronized[type][id].acceptPacket(packet);
}
else if ((packet instanceof SynchronizedDestroyPacket)) {
const {id, type} = packet.data.synchronized;
this._synchronized[type][id].destroy();
this._synchronized[type][id] = null;
default:
}
}
@ -41,7 +45,7 @@ export default class ClientSynchronizer {
if (!(type in this._synchronized)) {
this._synchronized[type] = {};
}
const id = synchronized.synchronizationId();
const id = synchronized.s13Id();
this._synchronized[type][id] = synchronized;
}

View File

@ -1,5 +1,7 @@
import {gather, gatherWithLatus} from '@latus/core';
export * from './packets';
export {default as normalize} from './normalize';
export {default as Synchronized, synchronized} from './synchronized';

View File

@ -0,0 +1,3 @@
export {default as SynchronizedCreatePacket} from './synchronized-create';
export {default as SynchronizedDestroyPacket} from './synchronized-destroy';
export {default as SynchronizedUpdatePacket} from './synchronized-update';

View File

@ -2,7 +2,7 @@ import msgpack from 'msgpack-lite';
import SynchronizedPacket from './synchronized';
export default () => class SynchronizedCreatePacket extends SynchronizedPacket {
export default class SynchronizedCreatePacket extends SynchronizedPacket {
static packData(data) {
// eslint-disable-next-line no-param-reassign
@ -10,16 +10,20 @@ export default () => class SynchronizedCreatePacket extends SynchronizedPacket {
return data;
}
static get synchronizationSchema() {
static get s13nSchema() {
return {
spec: 'buffer',
};
}
static get s13nType() {
return 'create';
}
static unpackData(data) {
// eslint-disable-next-line no-param-reassign
data.spec = msgpack.decode(data.spec);
return data;
}
};
}

View File

@ -1,3 +1,9 @@
import SynchronizedPacket from './synchronized';
export default () => class SynchronizedDestroyPacket extends SynchronizedPacket {};
export default class SynchronizedDestroyPacket extends SynchronizedPacket {
static get s13nType() {
return 'destroy';
}
}

View File

@ -1,3 +1,9 @@
import SynchronizedPacket from './synchronized';
export default () => class SynchronizedUpdatePacket extends SynchronizedPacket {};
export default class SynchronizedUpdatePacket extends SynchronizedPacket {
static get s13nType() {
return 'update';
}
}

View File

@ -1,6 +1,6 @@
import {Packet} from '@latus/socket';
export default () => class SynchronizedPacket extends Packet {
export default class SynchronizedPacket extends Packet {
static get data() {
return {
@ -8,12 +8,16 @@ export default () => class SynchronizedPacket extends Packet {
type: 'uint8',
id: 'varuint',
},
...this.synchronizationSchema,
...this.s13nSchema,
};
}
static get synchronizationSchema() {
static get s13nSchema() {
return {};
}
};
static get s13nType() {
return 'none';
}
}

View File

@ -17,7 +17,7 @@ export default class ServerSynchronizer {
this._synchronized[type] = {};
}
this._synchronizedFlat.push(synchronized);
const id = synchronized.synchronizationId();
const id = synchronized.s13Id();
this._synchronized[type][id] = synchronized;
}
@ -36,7 +36,7 @@ export default class ServerSynchronizer {
const index = this._synchronizedFlat.indexOf(synchronized);
this._synchronizedFlat.splice(index, 1);
const {s13nType: type} = synchronized.constructor;
const id = synchronized.synchronizationId();
const id = synchronized.s13Id();
delete this._synchronized[type][id];
}

View File

@ -18,11 +18,11 @@ export default function SynchronizedMixin(Superclass) {
}
createPacket(informed) {
const id = this.synchronizationId();
const id = this.s13Id();
return new SynchronizedCreatePacket({
synchronized: {
id,
type: this.constructor.type,
type: this.constructor.resourceId,
},
spec: this.toNetwork(informed),
});
@ -32,17 +32,19 @@ export default function SynchronizedMixin(Superclass) {
destroy() {}
destroyPacket() {
const id = this.synchronizationId();
const id = this.s13Id();
return new SynchronizedDestroyPacket({
synchronized: {
id,
type: this.constructor.type,
type: this.constructor.resourceId,
},
});
}
fromNetwork(json) {
this.fromJSON(json);
fromNetwork() {
throw new ReferenceError(
`${this.constructor.resourceType || this.constructor.name}::fromNetwork is undefined`,
);
}
// eslint-disable-next-line class-methods-use-this
@ -61,11 +63,11 @@ export default function SynchronizedMixin(Superclass) {
}
const packets = normalize(latus, this.packets(informed));
// Embed synchronization info.
const id = this.synchronizationId();
const id = this.s13Id();
for (let i = 0; i < packets.length; i++) {
packets[i].data.synchronized = {
id,
type: this.constructor.type,
type: this.constructor.resourceId,
};
}
if (this.packetsAreIdempotent()) {
@ -75,7 +77,7 @@ export default function SynchronizedMixin(Superclass) {
}
// eslint-disable-next-line class-methods-use-this
synchronizationId() {
s13Id() {
return 0;
}

View File

@ -2,6 +2,24 @@
# yarn lockfile v1
"@avocado/core@2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@avocado%2fcore/-/core-2.0.0.tgz#26d548a708ebe174e1014e21996db7ca4efd1f7b"
integrity sha512-4T5veeYVxsBIMJqQYbaumYvViPLIShmtQW8qReLjuQCTt23cOG1IG4kcetKeOA5Gke3qrw4JNzakYEg2GqJoMQ==
dependencies:
debug "4.3.1"
"@avocado/resource@^2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@avocado%2fresource/-/resource-2.0.0.tgz#0b079dfa9b130b49cf02d0702395a42643a4a4fe"
integrity sha512-O8bEbuxP4VpxoAkWcmAvmI+qmpZMdO5wHn/RcsVIAP8g4IbykH/7RGzRKJKXvvJ1YtGxDwt+Oec88EZHf/n9sg==
dependencies:
"@avocado/core" "2.0.0"
"@latus/core" "2.0.0"
debug "4.3.1"
deepmerge "^4.2.2"
uuid "^8.3.2"
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.11":
version "7.12.11"
resolved "https://npm.i12e.cha0s.io/@babel%2fcode-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"
@ -2563,6 +2581,11 @@ deepmerge@^2.2.1:
resolved "https://npm.i12e.cha0s.io/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170"
integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==
deepmerge@^4.2.2:
version "4.2.2"
resolved "https://npm.i12e.cha0s.io/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
default-gateway@^4.2.0:
version "4.2.0"
resolved "https://npm.i12e.cha0s.io/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b"
@ -7128,6 +7151,11 @@ uuid@^3.3.2, uuid@^3.4.0:
resolved "https://npm.i12e.cha0s.io/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
uuid@^8.3.2:
version "8.3.2"
resolved "https://npm.i12e.cha0s.io/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
v8-compile-cache@^2.0.3, v8-compile-cache@^2.1.1:
version "2.2.0"
resolved "https://npm.i12e.cha0s.io/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132"

View File

@ -9,7 +9,7 @@ export default () => class RoomUpdateLayers extends SynchronizedUpdatePacket {
return data;
}
static get synchronizationSchema() {
static get s13nSchema() {
return {
layersPackets: 'buffer',
};

View File

@ -1,13 +1,6 @@
import {Property} from '@avocado/core';
import {
JsonResource,
resource,
} from '@avocado/resource';
import {
normalize,
SynchronizedCreatePacket,
SynchronizedDestroyPacket,
} from '@avocado/s13n';
import {JsonResource, resource} from '@avocado/resource';
import {normalize} from '@avocado/s13n';
import {compose, EventEmitter} from '@latus/core';
// import Tiles from './tiles';
@ -48,18 +41,22 @@ export default (latus) => class Layer extends decorate(JsonResource) {
}
acceptPacket(packet) {
if ('EntityListUpdateEntity' === packet.constructor.type) {
this.entityList.acceptPacket(packet);
const {constructor: {s13nType}} = packet;
switch (s13nType) {
case 'create':
case 'destroy':
this.entityList.acceptPacket(packet);
break;
default:
}
// May have to check type...
if (packet instanceof SynchronizedCreatePacket) {
this.entityList.acceptPacket(packet);
}
if (packet instanceof SynchronizedDestroyPacket) {
this.entityList.acceptPacket(packet);
}
if ('TilesUpdate' === packet.constructor.type) {
this.tiles.acceptPacket(packet);
switch (packet.constructor.type) {
case 'EntityListUpdate':
this.entityList.acceptPacket(packet);
break;
case 'TilesUpdate':
this.tiles.acceptPacket(packet);
break;
default:
}
}

View File

@ -24,14 +24,14 @@ const decorate = compose(
}),
);
let synchronizationId = 1;
let s13Id = 1;
export default (latus) => class Room extends decorate(JsonResource) {
constructor({layers, size} = {}) {
super();
this.bounds = [];
this._synchronizationId = synchronizationId++;
this._s13Id = s13Id++;
this.layers = layers;
// Listeners.
this.layers.on('entityAdded', this.onEntityAddedToRoom, this);
@ -140,8 +140,8 @@ export default (latus) => class Room extends decorate(JsonResource) {
this.layers.removeEntityFromLayer(entity, layerIndex);
}
synchronizationId() {
return this._synchronizationId;
s13Id() {
return this._s13Id;
}
tick(elapsed) {