75 lines
1.9 KiB
JavaScript
75 lines
1.9 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) {
|
|
for (const [entity, packets] of this.packetsToSynchronize.entries()) {
|
|
const mergedPackets = this._mergePackets(packets);
|
|
flusher(entity, Array.from(mergedPackets.values()));
|
|
}
|
|
this.packetsToSynchronize.clear();
|
|
}
|
|
|
|
_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);
|
|
});
|
|
}
|
|
|
|
}
|