avocado-old/packages/entity/packet-synchronizer.js

80 lines
2.1 KiB
JavaScript

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) {
const flushed = new Map();
const it = this.packetsToSynchronize.entries();
for (let value = it.next(); !value.done; value = it.next()) {
const entity = value.value[0];
const packets = value.value[1];
const mergedPackets = this._mergePackets(packets);
flushed.set(entity, mergedPackets);
}
this.packetsToSynchronize.clear();
return flushed;
}
_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);
});
}
}