feat: entity packets

This commit is contained in:
cha0s 2019-04-28 22:33:41 -05:00
parent 64f66937b3
commit e13c8dfc66
4 changed files with 112 additions and 0 deletions

View File

@ -0,0 +1,25 @@
import {Packet} from '@avocado/net';
export class EntityPacket extends Packet {
static get schema() {
return {
...super.schema,
data: [{
uuid: 'string',
}],
};
}
bundleWith(other) {
this.data.push(other.data[0]);
}
forEachData(fn) {
for (let i = 0; i < this.data.length; i++) {
const data = this.data[i];
fn(data);
}
}
}

View File

@ -67,6 +67,13 @@ export class Entity extends decorate(Resource) {
});
}
acceptPacket(packet) {
for (const type in this._traits) {
const instance = this._traits[type];
instance.acceptPacket(packet);
}
}
addTrait(type, json = {}) {
if (this.is(type)) {
debug(`Tried to add trait "${type}" when it already exists!`);
@ -291,8 +298,12 @@ export class Entity extends decorate(Resource) {
}
export {EntityPacket} from './entity.packet';
export {EntityList, EntityListView} from './list';
export {EntityPacketSynchronizer} from './packet-synchronizer';
export {
hasTrait,
lookupTrait,

View File

@ -0,0 +1,74 @@
import {EntityPacket} from '@avocado/entity';
export class EntityPacketSynchronizer {
constructor() {
this.packetsToSynchronize = new Map();
this.trackedEntities = new Map();
}
acceptPacket(packet) {
if (!(packet instanceof EntityPacket)) {
return;
}
for (let i = 0; i < packet.data.length; i++) {
const data = packet.data[i];
const packetEntity = this.trackedEntities.get(data.uuid);
if (!packetEntity) {
continue;
}
const Packet = packet.constructor;
packetEntity.acceptPacket(new Packet([data]));
}
}
flushPackets(flusher) {
for (const [entity, packets] of this.packetsToSynchronize.entries()) {
const mergedPackets = this._mergePackets(packets);
flusher(entity, Array.from(mergedPackets.values()));
}
this.packetsToSynchronize = new Map();
}
_mergePackets(packets) {
const mergedPackets = new Map();
for (let i = 0; i < packets.length; i++) {
const packet = packets[i];
const Packet = packet.constructor;
if (!mergedPackets.has(Packet)) {
mergedPackets.set(Packet, packet);
}
else {
mergedPackets.get(Packet).mergeWith(packet);
}
}
return mergedPackets;
}
_queuePacketFor(entity, packet) {
if (!this.packetsToSynchronize.has(entity)) {
this.packetsToSynchronize.set(entity, []);
}
this.packetsToSynchronize.get(entity).push(packet);
}
trackEntity(entity) {
this.trackedEntities.set(entity.instanceUuid, entity);
entity.once('destroy', () => {
this.trackedEntities.delete(entity.instanceUuid);
});
this._watchEntityPackets(entity);
}
_watchEntityPackets(entity) {
const onSendPacket = (packet) => {
this._queuePacketFor(entity, packet);
};
entity.on('sendPacket', onSendPacket);
entity.once('destroy', () => {
this.packetsToSynchronize.delete(entity);
entity.off('sendPacket', onSendPacket);
});
}
}

View File

@ -21,6 +21,8 @@ export class Trait extends decorate(class {}) {
this.state = I.fromJS(ctor.defaultState()).merge(I.fromJS(state));
}
acceptPacket(packet) {}
destroy() {}
get isDirty() {